Basándome en los tutoriales de PyBrain, logré reunir el siguiente código:
#!/usr/bin/env python2 # coding: utf-8 from pybrain.structure import FeedForwardNetwork, LinearLayer, SigmoidLayer, FullConnection from pybrain.datasets import SupervisedDataSet from pybrain.supervised.trainers import BackpropTrainer n = FeedForwardNetwork() inLayer = LinearLayer(2) hiddenLayer = SigmoidLayer(3) outLayer = LinearLayer(1) n.addInputModule(inLayer) n.addModule(hiddenLayer) n.addOutputModule(outLayer) in_to_hidden = FullConnection(inLayer, hiddenLayer) hidden_to_out = FullConnection(hiddenLayer, outLayer) n.addConnection(in_to_hidden) n.addConnection(hidden_to_out) n.sortModules() ds = SupervisedDataSet(2, 1) ds.addSample((0, 0), (0,)) ds.addSample((0, 1), (1,)) ds.addSample((1, 0), (1,)) ds.addSample((1, 1), (0,)) trainer = BackpropTrainer(n, ds) # trainer.train() trainer.trainUntilConvergence() print n.activate([0, 0])[0] print n.activate([0, 1])[0] print n.activate([1, 0])[0] print n.activate([1, 1])[0]
Se supone que debe aprender la función XOR, pero los resultados parecen bastante aleatorios:
0.208884929522
0.168926515771
0.459452834043
- Cómo se resuelven las referencias a las variables en Python
- Función Python / AWS Lambda: ¿Cómo ver / tmp el almacenamiento?
- ¿Cómo obtener todas las claves del diccionario de un valor?
- python 2.7 - Requirement.parse ('six> = 1.6.0'))
- Comprobando el error de tiempo de espera en python
0.424209192223
o
0.84956138664
0.888512762786
0.564964077401
0.611111147862
Hay cuatro problemas con su enfoque, todos fáciles de identificar después de leer las Preguntas Frecuentes de la Red Neural :
¿Por qué usar un sesgo / umbral? : debe agregar un nodo de sesgo. La falta de sesgo hace que el aprendizaje sea muy limitado: el hiperplano de separación representado por la red solo puede pasar por el origen. Con el nodo de sesgo, puede moverse libremente y ajustarse mejor a los datos:
bias = BiasUnit() n.addModule(bias) bias_to_hidden = FullConnection(bias, hiddenLayer) n.addConnection(bias_to_hidden)
¿Por qué no codificar entradas binarias como 0 y 1? : todas sus muestras están en un solo cuadrante del espacio muestral. Muevalos para que se dispersen alrededor del origen:
ds = SupervisedDataSet(2, 1) ds.addSample((-1, -1), (0,)) ds.addSample((-1, 1), (1,)) ds.addSample((1, -1), (1,)) ds.addSample((1, 1), (0,))
(Corrija el código de validación al final de su script en consecuencia).
trainUntilConvergence
método trainUntilConvergence
funciona con validación y hace algo que se parece al método de detención temprana . Esto no tiene sentido para un conjunto de datos tan pequeño. Utilice trainEpochs
en trainEpochs
lugar. 1000
épocas son más que suficientes para este problema para que la red pueda aprender:
trainer.trainEpochs(1000)
¿Qué tasa de aprendizaje se debe utilizar para backprop? : Ajuste el parámetro de velocidad de aprendizaje. Esto es algo que haces cada vez que empleas una neural network. En este caso, el valor 0.1
o incluso 0.2
aumenta dramáticamente la velocidad de aprendizaje:
trainer = BackpropTrainer(n, dataset=ds, learningrate=0.1, verbose=True)
(Tenga en cuenta el parámetro verbose=True
. Es esencial observar cómo se comporta el error al ajustar los parámetros).
Con estas correcciones obtengo resultados consistentes y correctos para la red dada con el conjunto de datos dado, y error inferior a 1e-23
.