为什么训练有素的Pybrain网络即使在输入用于训练时也会产生不同的结果

时间:2015-07-13 22:13:05

标签: python neural-network pybrain

我使用pybrain训练了一个神经网络。但是当我使用与用于训练的输入相同的输入测试我的网络时,我得到完全不同的结果。这是我的代码

from pybrain.structure import FeedForwardNetwork
from pybrain.structure import LinearLayer, SigmoidLayer
from pybrain.structure import FullConnection
import numpy as np
from pybrain.datasets import SupervisedDataSet
from pybrain.supervised import BackpropTrainer
from pybrain.tools.xml.networkreader import NetworkReader
from pybrain.tools.xml.networkwriter import NetworkWriter
from pybrain.utilities import percentError

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()

X = np.array(([3,5], [5,1], [10,2]),dtype=float)
Y = np.array(([75], [82], [93]),dtype=float)
X/=np.amax(X, axis=0)
Y/=100

print(n.activate([ 1, 2]))
print(in_to_hidden.params)
ds = SupervisedDataSet(2,1)
for i in range(len(X)):
  ds.addSample(X[i],Y[i])

trainer=BackpropTrainer(n,ds, learningrate=0.5, momentum=0.05,verbose=True)
trainer.trainUntilConvergence(ds)
trainer.testOnData(ds, verbose=True)

现在,当我想使用代码测试输入时 print("Testing",n.activate([3,5])) 我得到('Testing', array([ 1.17809308]))。对于此输入0.75,我应该在n.activate([3,5])左右。所以我不明白为什么这个奇怪的结果

2 个答案:

答案 0 :(得分:2)

如果我理解正确,这只是模型验证的一个方面,您将始终需要这样做。网络通常寻求最小化其针对所有训练数据的错误,但是它不会准确地得到每个结果。您可以通过运行更多隐藏神经元的更多时期来提高预测准确性。但是,这样做最终会导致过度适应过度灵活。这是一种平衡行为。

作为类比,采取回归。在下面的线性情况下,模型与任何训练(蓝色)数据都不匹配,但通常捕获蓝色和红色(外部测试)数据的趋势。使用线性方程总是会给我所有数据的错误答案,但它是一个不错的近似值。然后说我适合数据的多项式趋势线。现在它具有更大的灵活性,达到所有蓝点,但测试数据上的错误已经增加。

regression

建立网络后,您需要通过它重新运行所有数据。然后,除了k-fold交叉验证之外,您还可以在absolute average deviationMSEMASE等上进行验证。您对错误的容忍度取决于您的应用程序:在工程方面,我可能总是需要在5%的误差范围内,并且超出该阈值的任何内容(将出现在第二个图表中)可能会产生致命的后果。在语言处理中,我可以容忍一两个真正的混乱,并且如果大多数预测非常接近,尝试用另一种方式捕捉它们,所以我可能会采用第二个图形。

利用您的学习速度和动力可能有助于收集更好的解决方案。

编辑:基于评论

评论"应该能够识别它"对我来说意味着与神经网络的基础不同的东西。在网络中甚至没有模糊的内存概念,它只是使用训练数据来开发一套复杂的规则来尝试并最小化其对所有数据点的错误。一旦网络被训练,它就没有任何训练数据的记忆,它只是留下了将在输入数据上执行的乘法步骤的意大利面。因此,无论您的网络有多好,您都无法将您的培训输入反向映射到完全正确的答案。

"融合的想法"不能认为你有一个良好的网络。网络可能刚刚发现local minima错误并放弃了学习。这就是必须始终验证模型的原因。如果您对验证结果不满意,可以尝试通过以下方式改进模型:
- 只需重新运行它。网络的随机初始化现在可以避免局部最小值 - 改变神经元的数量。这松弛或收紧了模型的灵活性 - 改变学习率和动力
- 更改学习规则,例如从Levenberg-Marquardt交换到贝叶斯正则化

答案 1 :(得分:0)

我没有看到结果有什么奇怪的。仅仅因为你有一个输入[0.75]和输出s = 'aaaabbcccca' out = '' c = 1 for i in range(len(s)): if i < len(s)-1 and s[i] == s[i+1]: c += 1 else: out += s[i] + str(c) c = 1 print out 的训练实例,这并不意味着网络应该总是产生相同的输出。该模型不仅仅是记忆训练实例。