Las compuertas XOR¶




La tabla de verdad está dada por

p q p XOR q
1 1 0
1 0 1
0 1 1
0 0 0

Creación de una red neuronal¶

Realizamos las importaciones necesarias

In [2]:
import numpy as np
from keras.models import Sequential
from keras.layers.core import Dense

Haremos que la información de las columnas p y q será la información de entrada a nuestra red neuronal, de modo que podremos ingresar a ésta los valores $(1,1), (1,0), (0,1), (0,0)$. Así, crearemos entonces dos nodos de entrada en la primer capa

red1.PNG

Crearemos una capa oculta de 16 nodos y la capa de salida será de un nodo; la función de activiación relu y en la capa de salida será la función sigmoid. La información objetivo a la cual queremos llegar son los valores de la columna p XOR q: 0, 1, 1, 0.

In [3]:
# Datos de entrenamiento
train = np.array([[0,0], [0,1], [1,0], [1,1]])

# Datos objetivo
target = np.array([[0], [1], [1], [0]])

Procedemos a crear la arquitectura de nuestra red neuronal

In [4]:
model = Sequential()
# Capa de entrada de más capa oculta de 16 nodos
model.add(Dense(16, activation='relu', input_shape=(2,)))
# Capa de salida
model.add(Dense(1, activation='sigmoid'))

Ahora entrenaremos las red neuronal que acabamos de modelar

In [5]:
# Primero copilamos la red
#            Funcion de perdidad   |   optimizar la       | copilacion del modelo
#                                  |   tasa de aprendizaje| paso a paso
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['binary_accuracy'])

# Entrenamos la red
#                        Cantidad de iteraciones
#                        de aprendizaje de 
#                        entrenamiento
model.fit(train, target, epochs=150)
Epoch 1/150
1/1 [==============================] - 1s 999ms/step - loss: 0.2460 - binary_accuracy: 0.7500
Epoch 2/150
1/1 [==============================] - 0s 7ms/step - loss: 0.2452 - binary_accuracy: 0.5000
Epoch 3/150
1/1 [==============================] - 0s 7ms/step - loss: 0.2444 - binary_accuracy: 0.5000
Epoch 4/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2436 - binary_accuracy: 0.5000
Epoch 5/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2428 - binary_accuracy: 0.5000
Epoch 6/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2420 - binary_accuracy: 0.5000
Epoch 7/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2412 - binary_accuracy: 0.5000
Epoch 8/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2404 - binary_accuracy: 0.5000
Epoch 9/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2397 - binary_accuracy: 0.5000
Epoch 10/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2389 - binary_accuracy: 0.5000
Epoch 11/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2382 - binary_accuracy: 0.5000
Epoch 12/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2375 - binary_accuracy: 0.5000
Epoch 13/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2367 - binary_accuracy: 0.5000
Epoch 14/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2360 - binary_accuracy: 0.5000
Epoch 15/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2353 - binary_accuracy: 0.5000
Epoch 16/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2347 - binary_accuracy: 0.5000
Epoch 17/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2340 - binary_accuracy: 0.5000
Epoch 18/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2333 - binary_accuracy: 0.5000
Epoch 19/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2327 - binary_accuracy: 0.5000
Epoch 20/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2321 - binary_accuracy: 0.5000
Epoch 21/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2315 - binary_accuracy: 0.5000
Epoch 22/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2309 - binary_accuracy: 0.5000
Epoch 23/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2303 - binary_accuracy: 0.5000
Epoch 24/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2297 - binary_accuracy: 0.5000
Epoch 25/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2291 - binary_accuracy: 0.5000
Epoch 26/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2285 - binary_accuracy: 0.5000
Epoch 27/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2280 - binary_accuracy: 0.5000
Epoch 28/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2274 - binary_accuracy: 0.5000
Epoch 29/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2269 - binary_accuracy: 0.5000
Epoch 30/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2264 - binary_accuracy: 0.5000
Epoch 31/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2259 - binary_accuracy: 0.5000
Epoch 32/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2253 - binary_accuracy: 0.5000
Epoch 33/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2248 - binary_accuracy: 0.5000
Epoch 34/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2243 - binary_accuracy: 0.5000
Epoch 35/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2238 - binary_accuracy: 0.5000
Epoch 36/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2234 - binary_accuracy: 0.5000
Epoch 37/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2229 - binary_accuracy: 0.5000
Epoch 38/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2224 - binary_accuracy: 0.5000
Epoch 39/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2220 - binary_accuracy: 0.5000
Epoch 40/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2215 - binary_accuracy: 0.5000
Epoch 41/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2211 - binary_accuracy: 0.5000
Epoch 42/150
1/1 [==============================] - 0s 2ms/step - loss: 0.2207 - binary_accuracy: 0.5000
Epoch 43/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2202 - binary_accuracy: 0.5000
Epoch 44/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2198 - binary_accuracy: 0.5000
Epoch 45/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2194 - binary_accuracy: 0.5000
Epoch 46/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2189 - binary_accuracy: 0.5000
Epoch 47/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2185 - binary_accuracy: 0.5000
Epoch 48/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2181 - binary_accuracy: 0.5000
Epoch 49/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2177 - binary_accuracy: 0.5000
Epoch 50/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2173 - binary_accuracy: 0.5000
Epoch 51/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2168 - binary_accuracy: 0.5000
Epoch 52/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2164 - binary_accuracy: 0.5000
Epoch 53/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2160 - binary_accuracy: 0.5000
Epoch 54/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2156 - binary_accuracy: 0.5000
Epoch 55/150
1/1 [==============================] - 0s 2ms/step - loss: 0.2152 - binary_accuracy: 0.5000
Epoch 56/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2148 - binary_accuracy: 0.5000
Epoch 57/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2144 - binary_accuracy: 0.5000
Epoch 58/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2140 - binary_accuracy: 0.5000
Epoch 59/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2136 - binary_accuracy: 0.5000
Epoch 60/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2131 - binary_accuracy: 0.5000
Epoch 61/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2127 - binary_accuracy: 0.5000
Epoch 62/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2123 - binary_accuracy: 0.5000
Epoch 63/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2119 - binary_accuracy: 0.5000
Epoch 64/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2115 - binary_accuracy: 0.5000
Epoch 65/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2111 - binary_accuracy: 0.7500
Epoch 66/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2107 - binary_accuracy: 0.7500
Epoch 67/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2103 - binary_accuracy: 0.7500
Epoch 68/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2099 - binary_accuracy: 0.7500
Epoch 69/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2095 - binary_accuracy: 0.7500
Epoch 70/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2091 - binary_accuracy: 0.7500
Epoch 71/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2087 - binary_accuracy: 0.7500
Epoch 72/150
1/1 [==============================] - 0s 2ms/step - loss: 0.2083 - binary_accuracy: 0.7500
Epoch 73/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2079 - binary_accuracy: 0.7500
Epoch 74/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2075 - binary_accuracy: 0.7500
Epoch 75/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2071 - binary_accuracy: 0.7500
Epoch 76/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2068 - binary_accuracy: 0.7500
Epoch 77/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2064 - binary_accuracy: 0.7500
Epoch 78/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2060 - binary_accuracy: 0.7500
Epoch 79/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2057 - binary_accuracy: 0.7500
Epoch 80/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2053 - binary_accuracy: 0.7500
Epoch 81/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2049 - binary_accuracy: 0.7500
Epoch 82/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2046 - binary_accuracy: 0.7500
Epoch 83/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2042 - binary_accuracy: 0.7500
Epoch 84/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2038 - binary_accuracy: 0.7500
Epoch 85/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2035 - binary_accuracy: 0.7500
Epoch 86/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2031 - binary_accuracy: 0.7500
Epoch 87/150
1/1 [==============================] - 0s 4ms/step - loss: 0.2027 - binary_accuracy: 0.7500
Epoch 88/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2024 - binary_accuracy: 0.7500
Epoch 89/150
1/1 [==============================] - 0s 2ms/step - loss: 0.2020 - binary_accuracy: 0.7500
Epoch 90/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2016 - binary_accuracy: 0.7500
Epoch 91/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2013 - binary_accuracy: 0.7500
Epoch 92/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2009 - binary_accuracy: 0.7500
Epoch 93/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2006 - binary_accuracy: 0.7500
Epoch 94/150
1/1 [==============================] - 0s 3ms/step - loss: 0.2002 - binary_accuracy: 0.7500
Epoch 95/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1998 - binary_accuracy: 0.7500
Epoch 96/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1995 - binary_accuracy: 0.7500
Epoch 97/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1992 - binary_accuracy: 0.7500
Epoch 98/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1989 - binary_accuracy: 0.7500
Epoch 99/150
1/1 [==============================] - 0s 2ms/step - loss: 0.1985 - binary_accuracy: 0.7500
Epoch 100/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1981 - binary_accuracy: 0.7500
Epoch 101/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1978 - binary_accuracy: 0.7500
Epoch 102/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1974 - binary_accuracy: 0.7500
Epoch 103/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1971 - binary_accuracy: 0.7500
Epoch 104/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1968 - binary_accuracy: 0.7500
Epoch 105/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1965 - binary_accuracy: 0.7500
Epoch 106/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1962 - binary_accuracy: 0.7500
Epoch 107/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1959 - binary_accuracy: 0.7500
Epoch 108/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1956 - binary_accuracy: 0.7500
Epoch 109/150
1/1 [==============================] - 0s 2ms/step - loss: 0.1953 - binary_accuracy: 1.0000
Epoch 110/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1950 - binary_accuracy: 1.0000
Epoch 111/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1947 - binary_accuracy: 1.0000
Epoch 112/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1944 - binary_accuracy: 1.0000
Epoch 113/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1941 - binary_accuracy: 1.0000
Epoch 114/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1937 - binary_accuracy: 1.0000
Epoch 115/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1934 - binary_accuracy: 1.0000
Epoch 116/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1931 - binary_accuracy: 1.0000
Epoch 117/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1928 - binary_accuracy: 1.0000
Epoch 118/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1925 - binary_accuracy: 1.0000
Epoch 119/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1922 - binary_accuracy: 1.0000
Epoch 120/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1919 - binary_accuracy: 1.0000
Epoch 121/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1916 - binary_accuracy: 1.0000
Epoch 122/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1913 - binary_accuracy: 1.0000
Epoch 123/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1910 - binary_accuracy: 1.0000
Epoch 124/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1907 - binary_accuracy: 1.0000
Epoch 125/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1903 - binary_accuracy: 1.0000
Epoch 126/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1900 - binary_accuracy: 1.0000
Epoch 127/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1897 - binary_accuracy: 1.0000
Epoch 128/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1894 - binary_accuracy: 1.0000
Epoch 129/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1891 - binary_accuracy: 1.0000
Epoch 130/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1888 - binary_accuracy: 1.0000
Epoch 131/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1885 - binary_accuracy: 1.0000
Epoch 132/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1882 - binary_accuracy: 1.0000
Epoch 133/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1879 - binary_accuracy: 1.0000
Epoch 134/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1876 - binary_accuracy: 1.0000
Epoch 135/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1873 - binary_accuracy: 1.0000
Epoch 136/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1870 - binary_accuracy: 1.0000
Epoch 137/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1866 - binary_accuracy: 1.0000
Epoch 138/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1863 - binary_accuracy: 1.0000
Epoch 139/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1860 - binary_accuracy: 1.0000
Epoch 140/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1857 - binary_accuracy: 1.0000
Epoch 141/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1854 - binary_accuracy: 1.0000
Epoch 142/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1851 - binary_accuracy: 1.0000
Epoch 143/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1848 - binary_accuracy: 1.0000
Epoch 144/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1844 - binary_accuracy: 1.0000
Epoch 145/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1841 - binary_accuracy: 1.0000
Epoch 146/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1838 - binary_accuracy: 1.0000
Epoch 147/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1835 - binary_accuracy: 1.0000
Epoch 148/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1832 - binary_accuracy: 1.0000
Epoch 149/150
1/1 [==============================] - 0s 3ms/step - loss: 0.1829 - binary_accuracy: 1.0000
Epoch 150/150
1/1 [==============================] - 0s 4ms/step - loss: 0.1826 - binary_accuracy: 1.0000
Out[5]:
<keras.callbacks.History at 0x1d2bdb860d0>

Notamos que, a partir de la época 109 comenzó a tener una precisión del 100%, a partir de ahí la precisión se mantuvo igual y la función de pérdida continúo decreciendo. Luego, evaluaremos nuestro modelo

In [6]:
scores = model.evaluate(train, target)
print('%s: %.4f%%' % (model.metrics_names[1], scores[1] * 100))
1/1 [==============================] - 0s 138ms/step - loss: 0.1822 - binary_accuracy: 1.0000
binary_accuracy: 100.0000%

Podemos guardar nuestro modelo:

In [7]:
from keras.models import load_model
model.save('XOR.h5')

Y posteriormento lo podremos utilizar cuando queramos, por ejemplo vamos a utilizarlo para hacer predicciones, lo cual no tendría mucho sentido para nuestro ejemplo pues la red neuronal dará el valor correcto a las 4 posibilidades de la tabla de verdad del XOR

In [8]:
# Cargamos el modelo guardado
model_xor = load_model('XOR.h5')

# Hacemos las 4 predicciones posibles de XOR
pred = model_xor.predict(train)
pred
1/1 [==============================] - 0s 80ms/step
Out[8]:
array([[0.4879571 ],
       [0.57188183],
       [0.61815906],
       [0.40221503]], dtype=float32)

Lo cual podemos ver de manera más visual si realizamos el redondeo, pues lo anterior nos arroja probabilidades (lo cual logramos con la función de activación sigmoide, donde el umbral por defecto es 0.5)

In [9]:
pred.round()
Out[9]:
array([[0.],
       [1.],
       [1.],
       [0.]], dtype=float32)