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

2024-05-29 03:05:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下代码,来自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]

然而,结果是神经网络没有得到很好的训练。当查看错误输出时,网络会得到适当的训练,但是它使用“continuepochs”参数来训练更多的错误,网络的性能再次变差。所以网络正在收敛,但是没有办法得到训练最好的网络。PyBrain的文档表明,网络返回的是经过最好训练的网络,但是它返回的是一个错误元组。

当设置continuepochs为0时,我得到一个错误(ValueError:max()arg是一个空序列),因此continuepochs必须大于0。

PyBrain实际上是被维护的,因为它看起来在文档和代码上有很大的不同。


Tags: 代码fromimport网络net错误dstar
3条回答

经过进一步的挖掘,我发现PyBrain教程中的示例完全不合适。

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

def trainUntilConvergence(self, dataset=None, maxEpochs=None, verbose=None, continueEpochs=10, validationProportion=0.25):

这意味着25%的训练集用于验证。虽然这是一个非常有效的方法,当你有一个完整的可能性,即一个4行异或2-in-1-out解决方案集,你不会这样做。当一个人想要训练一个异或集,并且你移除其中一行进行验证时,这将直接导致你得到一个非常稀疏的训练集,其中一个可能的组合被忽略,从而自动生成那些未训练的权重。

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

因此,培训师对网络进行了正确的培训,但是省略了25%的异或问题,这就导致了网络培训不好。

PyBrain网站上的另一个快速启动示例将非常方便,因为这个示例在这个特定的XOR案例中是完全错误的。你可能想知道他们是否自己尝试过这个例子,因为它只是输出随机的训练不良的网络。

trainer = BackpropTrainer(net, ds, learningrate = 0.9, momentum=0.0, weightdecay=0.0, verbose=True) 
trainer.trainEpochs(epochs=1000)

这条路可以汇合。如果学习率太小(例如0.01),则在本地最小值中丢失。正如我所测试的,学习率在0.3-30之间,它可以收敛。

我采用了由Andrew Ng教授的优秀Machine Learning class on Coursera,该类的一部分覆盖了训练一个小的神经网络来识别异或。所以我对基于quickstart部分不收敛的pybrain示例有点不安。

我认为有很多原因,包括上面关于最小数据集被分成训练和验证的原因。在这门课上,安德鲁曾说:“不是拥有最好算法的人获胜,而是拥有最多数据的人。他接着解释说,2000年数据可用性的激增是人工智能(现在称为机器学习)死灰复燃的部分原因。

考虑到这些我发现

  1. 验证集可以有4个样本,因为这是在培训阶段之后进行的。
  2. 网络在隐藏层只需要2个节点,正如我在课堂上学到的
  3. 在这种情况下,学习率需要非常小,比如0.005,否则训练有时会跳过答案(这是我通过玩数字确认的课堂要点)。
  4. 学习率越小,最大时期就越小。一个小的学习率意味着收敛沿着梯度朝着最小化的方向走小步。如果它更大,你需要一个更大的maxEpochs,这样它将等待更长的时间,然后再决定它是否达到了最小值。
  5. 在网络中需要一个bias=True(它将一个常量1节点添加到输入层和隐藏层)。阅读this question关于偏见的答案。
  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])

相关问题 更多 >

    热门问题