PyBrain的神经网络训练不会收敛

ava*_*gen 32 python neural-network pybrain

我有以下代码,来自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]
Run Code Online (Sandbox Code Playgroud)

然而,结果是一个训练不好的神经网络.在查看错误输出时,网络会得到正确的训练,但是它会使用'continueEpochs'参数来训练更多,并且网络再次表现更差.因此网络正在融合,但没有办法获得训练有素的网络.PyBrain的文档意味着返回的网络被训练得最好,但它会返回一个错误元组.

当我将continueEpochs设为0时,我得到一个错误(ValueError:max()arg是一个空序列)所以continueEpochs必须大于0.

是否实际维护了PyBrain,因为它似乎在文档和代码方面存在很大差异.

ava*_*gen 35

经过一番挖掘后,我发现PyBrain教程中的示例完全不合适.

当我们查看源代码中的方法签名时,我们发现:

def trainUntilConvergence(self, dataset=None, maxEpochs=None, verbose=None, continueEpochs=10, validationProportion=0.25):
Run Code Online (Sandbox Code Playgroud)

这意味着25%的训练集用于验证.虽然在训练网络数据时这是一种非常有效的方法,但是当您拥有可用的全部可能性时,您将不会这样做,即4行XOR 2合1解决方案集.当想要训练XOR集并且你删除其中一行以进行验证时,你会得到一个非常稀疏的训练集,其中一个可能的组合被省略,自动导致那些未被训练的权重.

通常,当您省略25%的数据进行验证时,您可以假设25%的数据覆盖了网络已经或多或少地遇到的"大部分"解决方案空间.在这种情况下,这不是真的,它覆盖了网络完全未知的25%的解决方案空间,因为您已将其删除以进行验证.

因此,培训师正在正确地训练网络,但是通过省略25%的XOR问题,这会导致训练有素的网络.

作为快速入门的PyBrain网站上的一个不同的例子非常方便,因为这个例子在这个特定的XOR案例中是完全错误的.您可能想知道他们是否自己尝试了这个例子,因为它只输出随机训练有素的网络.

  • 这是一个经典的神经网络示例,因为它表明使用线性函数(sigmoids)的组合可以训练网络学习二进制逻辑.然而,他们的教程很糟糕,因为他们似乎并没有掌握这个概念. (4认同)
  • 我建议您分叉github项目,将示例放入您认为应该是的内容然后发出拉取请求 (3认同)

小智 17

在Coursera上学了优秀的机器学习课程,由Andrew Ng教授,课程的一部分包括训练一个小神经网来识别xor.所以我对pybrain示例有点困扰,该示例基于快速入门的部分未收敛.

我认为有很多原因,包括上面关于将最小数据集分成训练和验证的原因.在课程的某一点,安德鲁说"它不是拥有最佳算法的人,而是拥有最多数据的人.他接着解释说,2000年的数据可用性爆炸是其中一部分原因.人工智能的复兴,现在称为机器学习.

所以我想到了这一切

  1. 验证集可以有4个样本,因为它是在训练阶段之后.
  2. 根据我在课堂上学到的,网络中隐藏层只需要2个节点,
  3. 在这种情况下,学习率需要非常小,如0.005,否则训练有时会跳过答案(这是我通过玩数字确认的课程中的一个重点).
  4. 学习率越小,maxEpochs越小.较小的学习率意味着收敛沿着梯度向最小化采取较小的步骤.如果它更大,你需要一个更大的maxEpochs,以便在决定它达到最小值之前等待更长时间.
  5. 您需要在网络中使用bias = True(它为输入和隐藏层添加一个常量1节点).阅读关于偏见的这个问题的答案.
  6. 最后,也是最重要的,你需要一个大的训练集.在大约75%的时间里,1000收敛于正确的答案.我怀疑这与最小化算法有关.较小的数字会经常失败.

所以这里有一些有用的代码:

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])
Run Code Online (Sandbox Code Playgroud)