XOR compara dos bits de entrada y genera un bit de salida. Si los bits son iguales, el resultado es 0. Si los bits son diferentes, el resultado es 1. Los resultados de esta operación pueden resumirse en la tabla de abajo:
## x1 x2 y
## 1 0 0 0
## 2 0 1 1
## 3 1 1 0
## 4 1 0 1
Sea desea utilizar una red neuronal con dos inputs (basados en la
tabla anterior), dos neuronas ocultas y una neurona de salida, en este
caso será hará el ejercicio con la fila dos y el proceso solo tendrá dos
épocas . Además, tendremos en cuenta la función logística como función
de activación. De esta forma, se aplicará el método de retropropagación,
cuyo objetivo es optimizar los pesos para que la red neuronal pueda
aprender a asignar correctamente entradas arbitrarias a salidas. Para
empezar, debemos ver qué predice actualmente la red neuronal dados unos
pesos, unos sesgos y algunos valores de las variables como entradas
iniciales. Con estos valores, alimentaremos esas entradas a través de la
red. En este sentido, calculamos la entrada neta total a cada neurona de
la capa oculta, obtenemos la salida correspondiente de cada neurona
transformando la entrada neta total con ayuda de una función de
activación (aquí utilizamos la función logística) y, a continuación,
repetimos el proceso con las neuronas de la capa de salida. Para este
caso, se usarán los siguientes pesos y sesgos:
- W1=0.1
- W2=0.5
- W3=-0.7
- W4=0.3
- W5=0.2
- W6=0.4
- b1=0
- b2=0
- b3=0
En este sentido, la estructura básica será:
El algoritmo que se plantea está pensado para el caso que tengamos las neuronas de la imagen. De esta forma, el usuario puede hacer el ejercicio con los pesos, sesgos, epocas y entradas que desee; para ello, se plantearán las siguientes funciones que serán llamadas para ejecutarse en una función principal:
Las funciones que se harán para automarizar estas tareas serán hechas en python para una mayor facilidad en el manejo de matrices y operaciones. De esta forma, para este problema se plantea la creación de las siguientes funciones.
Nota: en el ejercicio hecho a mano en clase hubo un error con el
calculo de las derivadas del error con respecto a z3, porque al hacer la
derivada del error total con respecto a f3, es decir,
\[
\frac{\partial E_{total}}{\partial f_3}
\cdot
\frac{\partial f_3}{\partial z_3}
= (O_1 - \hat{O}_1)(1 - f_3) f_3
\] Se hace la derivada del exponente pero no la interior porque
el resultado debe ser el siguiente:
\[
\frac{\partial E_{total}}{\partial f_3}
\cdot
\frac{\partial f_3}{\partial z_3}
= -(O_1 - \hat{O}_1)(1 - f_3) f_3
\]
Por tanto, se hará el ejercicio con este ultimo resultado y luego con la versión hecha en clase.
La primera época se harán con los pesos y sesgos definidos anteriormente. Haremos esta primera época por pasos.
| Valor | |
|---|---|
| W1 | 0.1 |
| W2 | 0.5 |
| W3 | -0.7 |
| W4 | 0.3 |
| W5 | 0.2 |
| W6 | 0.4 |
| B1 | 0.0 |
| B2 | 0.0 |
| B3 | 0.0 |
| Valor | |
|---|---|
| Z1 | -0.7000000 |
| F1 | 0.3318122 |
| Z2 | 0.3000000 |
| F2 | 0.5744425 |
| Z3 | 0.2961395 |
| F3 | 0.5734985 |
## [1] 0.09095176
En este caso se usan las dos funciones para notar que funcionan igual, solo que una es automátizada y la otra solo sirve para esta red.
## W1 W2 W3 W4 W5 W6
## 0.000000000 0.000000000 -0.004625879 -0.010200893 -0.034615116 -0.059926648
## B1 B2 B3
## -0.004625879 -0.010200893 -0.104321400
| Parámetro | Valor | |
|---|---|---|
| dE_dW1 | ∂E/∂W1 | 0.0000000 |
| dE_dW2 | ∂E/∂W2 | 0.0000000 |
| dE_dW3 | ∂E/∂W3 | -0.0046259 |
| dE_dW4 | ∂E/∂W4 | -0.0102009 |
| dE_dW5 | ∂E/∂W5 | -0.0346151 |
| dE_dW6 | ∂E/∂W6 | -0.0599266 |
| dE_dB1 | ∂E/∂B1 | -0.0046259 |
| dE_dB2 | ∂E/∂B2 | -0.0102009 |
| dE_dB3 | ∂E/∂B3 | -0.1043214 |
| Valor | |
|---|---|
| W1 | 0.1000000 |
| W2 | 0.5000000 |
| W3 | -0.6988435 |
| W4 | 0.3025502 |
| W5 | 0.2086538 |
| W6 | 0.4149817 |
| B1 | 0.0000000 |
| B2 | 0.0000000 |
| B3 | 0.0000000 |
La salida del la red neural para esta epoca fue 0.5734 y el error total fue 0.090951 y la gráfica de la red es la siguiente:
Se ejecutará las mismas funciones que en la primer época pero solo se mostrará la propagación hacia adelante, la propagación hacia atrás, los pesos actualizados y el error total.
| Valor | |
|---|---|
| Z1 | -0.6988435 |
| F1 | 0.3320687 |
| Z2 | 0.3025502 |
| F2 | 0.5750658 |
| Z3 | 0.3079292 |
| F3 | 0.5763797 |
| Parámetro | Valor | |
|---|---|---|
| dE_dW1 | ∂E/∂W1 | 0.0000000 |
| dE_dW2 | ∂E/∂W2 | 0.0000000 |
| dE_dW3 | ∂E/∂W3 | -0.0047868 |
| dE_dW4 | ∂E/∂W4 | -0.0104889 |
| dE_dW5 | ∂E/∂W5 | -0.0343471 |
| dE_dW6 | ∂E/∂W6 | -0.0594812 |
| dE_dB1 | ∂E/∂B1 | -0.0047868 |
| dE_dB2 | ∂E/∂B2 | -0.0104889 |
| dE_dB3 | ∂E/∂B3 | -0.1034337 |
| Valor | |
|---|---|
| W1 | 0.1000000 |
| W2 | 0.5000000 |
| W3 | -0.6976468 |
| W4 | 0.3051725 |
| W5 | 0.2172406 |
| W6 | 0.4298520 |
| B1 | 0.0000000 |
| B2 | 0.0000000 |
| B3 | 0.0000000 |
## [1] 0.08972707
La salida del la red neural para esta epoca fue 0.5763 y el error
total fue 0.08972. Es decir, el error disminuyó y la salida de la red se
acercó más a la salida esperada 1.
La gráfica de la red después de la segunda época es la siguiente:
Se realizará el mismo ejercicio pero con la observación que se hizo en las derivadas del error total. Entonces se modificará la función gradiente_manual_nombres(). Los resultados resumidos para las dos epocas son los siguientes:
##
## ====== Época 1 ======
## Salida (y): 0.5735
## Error: 0.090952
## Pesos actuales:
## $W1
## [1] 0.1
##
## $W2
## [1] 0.5
##
## $W3
## [1] -0.7
##
## $W4
## [1] 0.3
##
## $W5
## [1] 0.2
##
## $W6
## [1] 0.4
##
## $B1
## [1] 0
##
## $B2
## [1] 0
##
## $B3
## [1] 0
##
## Gradientes:
## $dE_dW1
## [1] 0
##
## $dE_dW2
## [1] 0
##
## $dE_dW3
## [1] 0.004625879
##
## $dE_dW4
## [1] 0.01020089
##
## $dE_dW5
## [1] 0.03461512
##
## $dE_dW6
## [1] 0.05992665
##
## $dE_dB1
## [1] 0.004625879
##
## $dE_dB2
## [1] 0.01020089
##
## $dE_dB3
## [1] 0.1043214
##
##
## ====== Época 2 ======
## Salida (y): 0.5706
## Error: 0.092184
## Pesos actuales:
## $W1
## [1] 0.1
##
## $W2
## [1] 0.5
##
## $W3
## [1] -0.7011565
##
## $W4
## [1] 0.2974498
##
## $W5
## [1] 0.1913462
##
## $W6
## [1] 0.3850183
##
## $B1
## [1] 0
##
## $B2
## [1] 0
##
## $B3
## [1] 0
##
## Gradientes:
## $dE_dW1
## [1] 0
##
## $dE_dW2
## [1] 0
##
## $dE_dW3
## [1] 0.004461439
##
## $dE_dW4
## [1] 0.009905665
##
## $dE_dW5
## [1] 0.03488108
##
## $dE_dW6
## [1] 0.06036818
##
## $dE_dB1
## [1] 0.004461439
##
## $dE_dB2
## [1] 0.009905665
##
## $dE_dB3
## [1] 0.1052042
##
## Pesos finales:
## $W1
## [1] 0.1
##
## $W2
## [1] 0.5
##
## $W3
## [1] -0.7022718
##
## $W4
## [1] 0.2949734
##
## $W5
## [1] 0.182626
##
## $W6
## [1] 0.3699263
##
## $B1
## [1] 0
##
## $B2
## [1] 0
##
## $B3
## [1] 0
Notemos que el error aumenta en lugar de disminuir, entonces puede que ocurra un problema con estos resultados de la clase.