为什么经过训练的 Pybrain 网络即使将输入用于训练也会产生不同的结果

Why a Trained Pybrain network yield different results even with an input use for training

我使用 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])) 。对于此输入 n.activate([3,5]),我应该有大约 0.75。所以我不明白为什么这个奇怪的结果

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

打个比方,回归。在下面的线性情况下,模型不匹配任何训练(蓝色)数据,但通常捕获蓝色和红色(外部测试)数据的趋势。使用线性方程总是会给我所有数据的错误答案,但它是一个不错的近似器。然后说我对数据拟合了多项式趋势线。现在它有更多的灵活性,击中了所有的蓝点,但测试数据的错误增加了。

regression

建立网络后,您需要通过它重新运行所有数据。然后,除了 k-fold 交叉验证之类的东西之外,您还可以对 absolute average deviation, MSE, MASE 等进行验证。您对错误的容忍度取决于您的应用:在工程中,我可能总是需要将误差控制在 5% 以内,任何超过该阈值的事情(将出现在第二张图中)都可能会产生致命的后果。在语言处理中,我可能能够容忍一两个真实的 mess-ups,如果大多数预测非常接近,我会尝试用另一种方式捕捉它们,所以我可能会采用第二张图。

利用您的学习率和动力可能有助于找到更好的解决方案。

编辑:基于评论

评论"should have been able to recognise it"对我来说暗示了一些不同于神经网络基础的东西。网络中甚至没有一个模糊的记忆概念,它只是使用训练数据来制定一组复杂的规则,以尽量减少其对所有数据点的误差。一旦网络经过训练,它就不会再收集任何训练数据,它只会留下一串将对输入数据执行的乘法步骤。因此,无论您的网络有多好,您永远无法 reverse-map 您的训练输入得到准确的答案。

"convergence"的想法不能理解为你的网络很好。网络可能只是发现了一个 local minima 错误并放弃了学习。这就是为什么您 必须 始终验证您的模型。如果您对验证结果不满意,可以尝试通过以下方式改进模型:
- 简单地 re-running 一遍。网络的随机初始化现在可以避免局部最小值
- 改变神经元的数量。这会放松或收紧模型的灵活性
- 改变学习率和动量
- 改变学习规则,例如从 Levenberg-Marquardt 换成贝叶斯正则化

我没有看到结果有什么奇怪的。仅仅因为您有一个输入 [3,5] 和输出 [0.75] 的训练实例,并不意味着网络应该始终产生相同的输出。该模型不只是 记住 个训练实例。