【问题标题】:Why a Trained Pybrain network yield different results even with an input use for training为什么即使输入用于训练,经过训练的 Pybrain 网络也会产生不同的结果
【发布时间】:2015-10-02 08:49:11
【问题描述】:

我已经使用 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。所以我不明白为什么会出现这种奇怪的结果

【问题讨论】:

    标签: python neural-network pybrain


    【解决方案1】:

    如果我的理解正确,这只是模型验证的一个方面,您必须始终进行。网络通常会尽量减少对所有训练数据的误差,但它不会准确地得到每个结果。您可以通过运行更多具有更多隐藏神经元的 epoch 来提高预测准确性。然而,这样做最终会通过过度的灵活性导致过度拟合。这有点平衡。

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

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

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

    编辑:基于 cmets

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

    “融合”的概念不能被认为意味着您拥有良好的网络。网络可能只是发现了错误的local minima 并放弃了学习。这就是为什么您必须始终验证您的模型。如果您对验证结果不满意,可以尝试通过以下方式改进模型:
    - 只需重新运行它。网络的随机初始化现在可能会避免局部最小值
    - 改变神经元的数量。这会放松或收紧模型的灵活性
    - 改变学习率和动量
    - 改变学习规则,例如从 Levenberg-Marquardt 转换为贝叶斯正则化

    【讨论】:

    • 我的问题是为什么会给出完全不同的结果,尽管我的网络已经过训练直到它收敛?它的值应该接近实际值。我必须指出,我用于测试的值是我用于训练的值。所以我的网络应该能够识别它。
    • @user3841581 这就是我试图用回归图来说明的。您可以将线性模型视为经过训练的网络。您可以看到该线与任何训练数据都不相交,例如询问训练示例的答案将得到与您期望的结果不同的结果。我不能说 1.178 - 0.75 是否是一个很大的差异,这取决于你的数据(如果它的范围从 1 到 1 百万,则误差很小)。此外,您在实际模型中训练了多少示例数据?如果它只是 3 分,那么你永远不会有一个伟大的模型。
    • 我明白你的意思,我们需要更多的训练示例。但是我的模型不应该在用于训练的示例中获得好的结果吗?
    • @user3841581 希望编辑让它更清晰一些。您希望对训练数据得到一个好的答案,但不幸的是,这并不能保证:)
    • 谢谢;我将动量更改为 0.5,我有一个更好的解决方案。对于该示例,我现在有 0.72270291,它更接近 0.75。谢谢
    【解决方案2】:

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

    【讨论】:

    • 我现在明白了。我认为模型应该保存用于训练的示例
    猜你喜欢
    • 2019-02-28
    • 2017-10-12
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    • 2017-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多