{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Red Neuronal en Python (mejorada)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Crearemos una red neuronal simple, con 3 capas, neuronas con valores de entrada -1 a 1 y de salida 0 a 1 indicando encender o no los motores de un coche Arduino." ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "ExecuteTime": { "end_time": "2018-07-28T00:01:48.731495Z", "start_time": "2018-07-28T00:01:48.007632Z" } }, "outputs": [], "source": [ "import numpy as np\n", "\n", "# Creamos la clase \n", "class NeuralNetwork:\n", "\n", " def __init__(self, layers, activation='tanh'):\n", " if activation == 'sigmoid':\n", " self.activation = sigmoid\n", " self.activation_prime = sigmoid_derivada\n", " elif activation == 'tanh':\n", " self.activation = tanh\n", " self.activation_prime = tanh_derivada\n", "\n", " # inicializo los pesos\n", " self.weights = []\n", " self.deltas = []\n", " # capas = [2,3,4]\n", " # rando de pesos varia entre (-1,1)\n", " # asigno valores aleatorios a capa de entrada y capa oculta\n", " for i in range(1, len(layers) - 1):\n", " r = 2*np.random.random((layers[i-1] + 1, layers[i] + 1)) -1\n", " self.weights.append(r)\n", " # asigno aleatorios a capa de salida\n", " r = 2*np.random.random( (layers[i] + 1, layers[i+1])) - 1\n", " self.weights.append(r)\n", "\n", " def fit(self, X, y, learning_rate=0.2, epochs=100000):\n", " # Agrego columna de unos a las entradas X\n", " # Con esto agregamos la unidad de Bias a la capa de entrada\n", " ones = np.atleast_2d(np.ones(X.shape[0]))\n", " X = np.concatenate((ones.T, X), axis=1)\n", " \n", " for k in range(epochs):\n", " i = np.random.randint(X.shape[0])\n", " a = [X[i]]\n", "\n", " for l in range(len(self.weights)):\n", " dot_value = np.dot(a[l], self.weights[l])\n", " activation = self.activation(dot_value)\n", " a.append(activation)\n", " # Calculo la diferencia en la capa de salida y el valor obtenido\n", " error = y[i] - a[-1]\n", " deltas = [error * self.activation_prime(a[-1])]\n", " \n", " # Empezamos en el segundo layer hasta el ultimo\n", " # (Una capa anterior a la de salida)\n", " for l in range(len(a) - 2, 0, -1): \n", " deltas.append(deltas[-1].dot(self.weights[l].T)*self.activation_prime(a[l]))\n", " self.deltas.append(deltas)\n", "\n", " # invertir\n", " # [level3(output)->level2(hidden)] => [level2(hidden)->level3(output)]\n", " deltas.reverse()\n", "\n", " # backpropagation\n", " # 1. Multiplcar los delta de salida con las activaciones de entrada \n", " # para obtener el gradiente del peso.\n", " # 2. actualizo el peso restandole un porcentaje del gradiente\n", " for i in range(len(self.weights)):\n", " layer = np.atleast_2d(a[i])\n", " delta = np.atleast_2d(deltas[i])\n", " self.weights[i] += learning_rate * layer.T.dot(delta)\n", "\n", " if k % 10000 == 0: print('epochs:', k)\n", "\n", " def predict(self, x): \n", " ones = np.atleast_2d(np.ones(x.shape[0]))\n", " a = np.concatenate((np.ones(1).T, np.array(x)), axis=0)\n", " for l in range(0, len(self.weights)):\n", " a = self.activation(np.dot(a, self.weights[l]))\n", " return a\n", "\n", " def print_weights(self):\n", " print(\"LISTADO PESOS DE CONEXIONES\")\n", " for i in range(len(self.weights)):\n", " print(self.weights[i])\n", "\n", " def get_weights(self):\n", " return self.weights\n", " \n", " def get_deltas(self):\n", " return self.deltas\n", "\n", "# Al crear la red, podremos elegir entre usar la funcion sigmoid o tanh\n", "def sigmoid(x):\n", " return 1.0/(1.0 + np.exp(-x))\n", "\n", "def sigmoid_derivada(x):\n", " return sigmoid(x)*(1.0-sigmoid(x))\n", "\n", "def tanh(x):\n", " return np.tanh(x)\n", "\n", "def tanh_derivada(x):\n", " return 1.0 - x**2" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Comportamiento del Coche Robot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Crearemos una red neuronal que nos dará los pesos para las conexiones que utilizaremos en un coche robot Arduino" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "ExecuteTime": { "end_time": "2018-07-28T08:17:49.655846Z", "start_time": "2018-07-28T08:17:48.030401Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "epochs: 0\n", "epochs: 10000\n", "epochs: 20000\n", "epochs: 30000\n", "epochs: 40000\n", "X: [-1 0] esperado: [1 0 0 1] obtenido: 1 0 0 1\n", "X: [-1 1] esperado: [1 0 0 1] obtenido: 1 0 0 1\n", "X: [-1 -1] esperado: [1 0 0 1] obtenido: 1 0 0 1\n", "X: [ 0 -1] esperado: [0 1 0 1] obtenido: 0 1 0 1\n", "X: [0 1] esperado: [1 0 1 0] obtenido: 1 0 1 0\n", "X: [0 0] esperado: [1 0 0 1] obtenido: 1 0 0 1\n", "X: [1 1] esperado: [0 1 1 0] obtenido: 0 1 1 0\n", "X: [ 1 -1] esperado: [0 1 1 0] obtenido: 0 1 1 0\n", "X: [1 0] esperado: [0 1 1 0] obtenido: 0 1 1 0\n" ] } ], "source": [ "# Red Coche para Evitar obstáculos\n", "nn = NeuralNetwork([2,3,4],activation ='tanh')\n", "X = np.array([[-1, 0], # sin obstaculos\n", " [-1, 1], # sin obstaculos\n", " [-1, -1], # sin obstaculos\n", " [0, -1], # obstaculo detectado a derecha\n", " [0,1], # obstaculo a izq\n", " [0,0], # obstaculo centro\n", " [1,1], # demasiado cerca a derecha\n", " [1,-1], # demasiado cerca a izq\n", " [1,0] # demasiado cerca centro\n", " ])\n", "# las salidas 'y' se corresponden con encender (o no) los motores\n", "y = np.array([[1,0,0,1], # avanzar\n", " [1,0,0,1], # avanzar\n", " [1,0,0,1], # avanzar\n", " [0,1,0,1], # giro derecha\n", " [1,0,1,0], # giro izquierda (cambie izq y derecha)\n", " [1,0,0,1], # avanzar\n", " [0,1,1,0], # retroceder\n", " [0,1,1,0], # retroceder\n", " [0,1,1,0] # retroceder\n", " ])\n", "nn.fit(X, y, learning_rate=0.03,epochs=40001)\n", "\n", "def valNN(x):\n", " return (int)(abs(round(x)))\n", "\n", "index=0\n", "for e in X:\n", " prediccion = nn.predict(e)\n", " print(\"X:\",e,\"esperado:\",y[index],\"obtenido:\", valNN(prediccion[0]),valNN(prediccion[1]),valNN(prediccion[2]),valNN(prediccion[3]))\n", " #print(\"X:\",e,\"y:\",y[index],\"Network:\",prediccion)\n", " index=index+1" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Graficamos la función coste " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vemos como el gradiente desciende y disminuye el error a medida que pasan las iteraciones de aprendizaje" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "ExecuteTime": { "end_time": "2018-07-28T08:17:55.715347Z", "start_time": "2018-07-28T08:17:55.397792Z" } }, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "\n", "deltas = nn.get_deltas()\n", "valores=[]\n", "index=0\n", "for arreglo in deltas:\n", " valores.append(arreglo[1][0] + arreglo[1][1])\n", " index=index+1\n", "\n", "plt.plot(range(len(valores)), valores, color='b')\n", "plt.ylim([0, 0.4])\n", "plt.ylabel('Cost')\n", "plt.xlabel('Epochs')\n", "plt.tight_layout()\n", "plt.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Generamos el código para Arduino" ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "ExecuteTime": { "end_time": "2018-07-28T08:18:20.322749Z", "start_time": "2018-07-28T08:18:20.317377Z" } }, "outputs": [], "source": [ "def to_str(name, W):\n", " s = str(W.tolist()).replace('[', '{').replace(']', '}')\n", " return 'float '+name+'['+str(W.shape[0])+']['+str(W.shape[1])+'] = ' + s + ';'" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "ExecuteTime": { "end_time": "2018-07-28T08:18:23.469458Z", "start_time": "2018-07-28T08:18:23.461463Z" } }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "// Reemplazar estas lineas en tu codigo arduino:\n", "// float HiddenWeights ...\n", "// float OutputWeights ...\n", "// Con lo pesos entrenados.\n", "\n", "\n", "float HiddenWeights[3][4] = {{-0.7960407385601368, 0.33445223923885203, 1.960425026701174, -0.2188265940282402}, {3.2656011309214015, -3.6013913588454005, -0.29096408903685744, -2.9388553664766386}, {1.446933199813894, 1.1486435763683631, 0.3135522324567505, -0.9821514189870271}};\n", "float OutputWeights[4][4] = {{-0.5877653512662401, 1.2155643742120474, 2.031535401995985, -0.600509803082288}, {1.5646656113326125, -1.4443245182339164, -0.14615109999534517, -0.30734376440418343}, {1.200279804931951, 1.5841869308538188, 1.5974846833590683, 2.053825687728427}, {-0.9889240481130815, 1.1326242970187457, 0.6332460304988264, 1.6646621069357435}};\n" ] } ], "source": [ "# Obtenermos los pesos entrenados para poder usarlos en el codigo de arduino\n", "pesos = nn.get_weights();\n", "\n", "print('// Reemplazar estas lineas en tu codigo arduino:')\n", "print('// float HiddenWeights ...')\n", "print('// float OutputWeights ...')\n", "print('// Con lo pesos entrenados.')\n", "print('\\n')\n", "print(to_str('HiddenWeights', pesos[0]))\n", "print(to_str('OutputWeights', pesos[1]))" ] }, { "cell_type": "markdown", "metadata": { "ExecuteTime": { "end_time": "2018-07-25T10:25:56.999747Z", "start_time": "2018-07-25T10:25:56.975198Z" } }, "source": [ "Lee el artículo completo en www.aprendemachinelearning.com" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sigeme en Twitter @jbagnato" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.5" } }, "nbformat": 4, "nbformat_minor": 2 }