我有以下代码,来自PyBrain教程:
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure.modules import TanhLayer
ds = SupervisedDataSet(2, 1)
ds.addSample((0,0), (0,))
ds.addSample((0,1), (1,))
ds.addSample((1,0), (1,))
ds.addSample((1,1), (0,))
net = buildNetwork(2, 3, 1, bias=True, hiddenclass=TanhLayer)
trainer = BackpropTrainer(net, ds)
for inp, tar in ds:
print [net.activate(inp), tar]
errors = trainer.trainUntilConvergence()
for inp, tar in ds:
print [net.activate(inp), tar]
然而,结果是一个训练不好的神经网络。在查看错误输出时,网络会得到正确的训练,但是它会使用'continueEpochs'参数来训练更多,并且网络再次表现更差。因此网络正在融合,但没有办法获得训练有素的网络。 PyBrain的文档意味着返回的网络被训练得最好,但它会返回一个错误元组。
Whens etting continueEpochs to 0我得到一个错误(ValueError:max()arg是一个空序列)所以continueEpochs必须大于0。
PyBrain是否实际维护,因为它似乎在文档和代码方面存在很大差异。
答案 0 :(得分:35)
经过一番挖掘后,我发现PyBrain教程中的示例完全不合适。
当我们查看源代码中的方法签名时,我们发现:
def trainUntilConvergence(self, dataset=None, maxEpochs=None, verbose=None, continueEpochs=10, validationProportion=0.25):
这意味着25%的训练集用于验证。虽然在训练网络数据时这是一种非常有效的方法,但是当您拥有可用的全部可能性时,您将不会这样做,即4行XOR 2合1解决方案集。当一个人想要训练一个XOR集并且你删除其中一行进行验证时,你会得到一个非常稀疏的训练集,其中一个可能的组合被省略,导致自动进入那些未被训练的权重。
通常,当您省略25%的数据进行验证时,您可以假设25%的数据覆盖网络已经或多或少地遇到的“大部分”解决方案空间。在这种情况下,这不是真的,它覆盖了网络完全未知的解决方案空间的25%,因为您将其删除以进行验证。
因此,培训师正在正确地训练网络,但是通过省略25%的XOR问题,这会导致训练有素的网络。
作为快速入门的PyBrain网站上的另一个例子非常方便,因为这个例子在这个特定的XOR案例中是完全错误的。您可能想知道他们是否自己尝试了这个例子,因为它只输出随机训练有素的网络。
答案 1 :(得分:17)
我接受了由Andrew Ng教授的优秀Machine Learning class on Coursera,并且该课程的一部分涵盖了训练小神经网络来识别xor。所以我对基于quickstart部分没有收敛的pybrain示例感到有点困扰。
我认为有很多原因,包括上面关于将最小数据集分成训练和验证的原因。在课程的某一点,安德鲁说“它不是拥有最佳算法的人,而是拥有最多数据的人。他接着解释说,2000年的数据可用性爆炸是其中一部分原因。人工智能的复兴,现在称为机器学习。
所以考虑到这一点我找到了
所以这里有一些有用的代码:
from pybrain.datasets import SupervisedDataSet
dataModel = [
[(0,0), (0,)],
[(0,1), (1,)],
[(1,0), (1,)],
[(1,1), (0,)],
]
ds = SupervisedDataSet(2, 1)
for input, target in dataModel:
ds.addSample(input, target)
# create a large random data set
import random
random.seed()
trainingSet = SupervisedDataSet(2, 1);
for ri in range(0,1000):
input,target = dataModel[random.getrandbits(2)];
trainingSet.addSample(input, target)
from pybrain.tools.shortcuts import buildNetwork
net = buildNetwork(2, 2, 1, bias=True)
from pybrain.supervised.trainers import BackpropTrainer
trainer = BackpropTrainer(net, ds, learningrate = 0.001, momentum = 0.99)
trainer.trainUntilConvergence(verbose=True,
trainingData=trainingSet,
validationData=ds,
maxEpochs=10)
print '0,0->', net.activate([0,0])
print '0,1->', net.activate([0,1])
print '1,0->', net.activate([1,0])
print '1,1->', net.activate([1,1])
答案 2 :(得分:2)
trainer = BackpropTrainer(net, ds, learningrate = 0.9, momentum=0.0, weightdecay=0.0, verbose=True)
trainer.trainEpochs(epochs=1000)
这种方式可以收敛。如果学习率太小(例如0.01),它就会失去局部最小值。正如我测试的那样,在0.3-30中学习,它可以收敛。
答案 3 :(得分:0)
以下似乎始终如一地给出了正确的结果:
from pybrain.tools.shortcuts import buildNetwork
from pybrain.structure import TanhLayer
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised.trainers import BackpropTrainer
#net = buildNetwork(2, 3, 1, bias=True, hiddenclass=TanhLayer)
net = buildNetwork(2, 3, 1, bias=True)
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,))
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,))
trainer = BackpropTrainer(net, ds, learningrate=0.001, momentum=0.99)
trainer.trainUntilConvergence(verbose=True)
print net.activate([0,0])
print net.activate([0,1])
print net.activate([1,0])
print net.activate([1,1])