0

Cómo programar correctamente la función XOR con PyBrain

¡Hola gente! Estos días he estado probando la librería PyBrain, una librería en python para trabajar con Redes Neuronales. Es una librería muy completa que te da todos los algoritmos para crear la topología de la red y entrenarla, ahorrándote un montón de trabajo de picar código…

Pero me he encontrado con la desagradable sorpresa que el programa de ejemplo de la Página Oficial de pyBrain para entrenar una función booleana XOR no converge bien (por lo menos en el momento de publicar este artículo). Si habéis terminado en esta página, es muy probable que tengáis el mismo problema.

Inputs (izquierda) y output (derecha). Esto no se parece a la función booleana XOR… 🙁

Lo que pasa es que en el ejemplo de la página de PyBrain el dataSet para entrenar el sistema no es lo suficientemente grande, y además utiliza el 25% de los ejemplos del dataSet para testear la Red Neuronal, no para entrenarla (por tanto, utiliza el último ejemplo para testear el sistema).

He pensado que sería buena idea escribir un mini-tutorial y compartir mi propio código para que podáis ver cómo implementar la función XOR correctamente con pyBrain.


Tabla de verdad de la función XOR

Recordemos que la tabla de verdad de la función XOR (también llamada ‘OR exclusiva’ ) es esta:

El output es verdadero si y solo si los dos inputs son diferentes.


Código

Como siempre empezaremos importando los módulos de la librería PyBrain que necesitemos:

from pybrain.datasets import SupervisedDataSet
from pybrain.tools.shortcuts import buildNetwork
from pybrain.supervised.trainers import BackpropTrainer

Ahora crearemos el dataSet. ¡Aquí está la gracia! Hay que darle muchos ejemplos, y que sean redundantes, repitiéndolos varias veces.

ds = SupervisedDataSet(2, 1)

ds.addSample((0,0), (0))
ds.addSample((0,1), (1))
ds.addSample((1,0), (1))
ds.addSample((1,1), (0))
ds.addSample((0,0), (0))
ds.addSample((0,1), (1))
ds.addSample((1,0), (1))
ds.addSample((1,1), (0))
ds.addSample((0,0), (0))
ds.addSample((0,1), (1))
ds.addSample((1,0), (1))
ds.addSample((1,1), (0))
ds.addSample((0,0), (0))
ds.addSample((0,1), (1))
ds.addSample((1,0), (1))
ds.addSample((1,1), (0))

Ahora creamos una red neuronal con dos neuronas en la capa de entrada, cuatro en la capa oculta y una en la capa de salida. También usaremos un bias.

red_neuronal = buildNetwork(2, 4, 1, bias=True)

El entrenador lo vamos a crear con un learning rate de 0.01 y un momento de 0.99. Este entrenador utilizará el algoritmo estrella para entrenar redes neuronales: propagación hacia atrás (o Backpropagation)

entrenador = BackpropTrainer(red_neuronal, ds, learningrate = 0.01, momentum = 0.99)

¡Vamos a entrenar la red neuronal! Haremos 10.000 iteraciones y utilizaremos el 50% de los ejemplos del dataSet para hacer las validaciones.

entrenador.trainUntilConvergence(maxEpochs=10000, verbose=False, validationProportion=0.5)

Y acabaremos escribiendo los outputs que nos da la red neuronal pasándole como input cada uno de los valores de la tabla de verdad de la función XOR:

print '(0,0) :', red_neuronal.activate([0,0])
print '(0,1) :', red_neuronal.activate([0,1])
print '(1,0) :', red_neuronal.activate([1,0])
print '(1,1) :', red_neuronal.activate([1,1])

Si todo ha ido bien y no nos hemos equivocado en nada, al ejecutar el script en python debería aparecer un output parecido a este, con el primer y último valor muy cercano a 0 y los otros dos cercanos a 1.

¡Arreglado! 😉

PS: Si conocéis una forma más simple de hacerlo, por favor, dejadme un comentario!

N4n0

Creado para cuidar de los sistemas de laboratorios tan secretos que ni él tiene la seguridad de estar trabajando en ellos, a Nano le gusta dedicar los ciclos que no gasta en tapar agujeros de Firewall para dedicarse al hobby de la electrónica o a ver películas de ciencia ficción. Entre su filmoteca de culto, ocupan un lugar destacado Tron, The Matrix y Johnny Mnemonic.

Antes de comentar, por favor, lee las Normas

Ten el honor de decir "Primero!"

avatar
wpDiscuz