【问题标题】:Python Neural Network BackpropagationPython 神经网络反向传播
【发布时间】:2013-04-26 21:27:02
【问题描述】:

我正在学习神经网络,特别是研究具有反向传播实现的 MLP。我正在尝试在 python 中实现我自己的网络,我想在开始之前我会查看其他一些库。经过一番搜索,我找到了 Neil Schemenauer 的 python 实现 bpnn.py。 (http://arctrix.com/nas/python/bpnn.py)

在完成了代码并阅读了 Christopher M. Bishops 书“用于模式识别的神经网络”的第一部分后,我发现 backPropagate 函数存在问题:

# calculate error terms for output
output_deltas = [0.0] * self.no
for k in range(self.no):
    error = targets[k]-self.ao[k]
    output_deltas[k] = dsigmoid(self.ao[k]) * error

Bishops 书中计算误差的代码行不同。在第 145 页,等式 4.41 他将输出单位误差定义为:

d_k = y_k - t_k

其中 y_k 是输出,t_k 是目标。 (我用 _ 代表下标) 所以我的问题是这行代码应该:

error = targets[k]-self.ao[k]

实事求是:

error = self.ao[k] - targets[k]

我很可能完全错了,但请有人帮忙解决我的困惑。谢谢

【问题讨论】:

  • 由于错误是这个时期的结果与预期相差多少,这应该是正确的线:error = targets[k]-self.ao[k] 但两者都可以是正确的,这取决于dsigmoid(self.ao[k])的信号也是。
  • 无论你对 y 推导 (y-t)^2 还是 (t-y)^2 都没有区别,它始终是 y-t,而不是 t-y。

标签: python neural-network backpropagation


【解决方案1】:

在实际代码中,我们经常会计算 NEGATIVE grad(of loss 关于 w),并使用 w += eta*grad 来更新权重。实际上它是一个梯度上升。

在某些教科书中,会计算 POSITIVE grad 并使用 w -= eta*grad 来更新权重。

【讨论】:

    【解决方案2】:

    你可以从Padasip图书馆学习this implementation of MLP

    文档是here

    【讨论】:

      【解决方案3】:

      这完全取决于您使用的误差度量。仅仅给出一些错误措施的例子(对于简洁,我将使用ys表示n输出和ts表示n targets):

      mean squared error (MSE):
          sum((y - t) ** 2 for (y, t) in zip(ys, ts)) / n
      
      mean absolute error (MAE):
          sum(abs(y - t) for (y, t) in zip(ys, ts)) / n
      
      mean logistic error (MLE):
          sum(-log(y) * t - log(1 - y) * (1 - t) for (y, t) in zip(ys, ts)) / n 
      

      您使用哪一个完全取决于上下文。 MSE和MAE可以用于当目标输出可以采用任何值时使用,并且当您的目标输出是@或1y打开 em时,MLE提供非常好的结果>范围(0, 1)

      如上所说,我没有看到y - t或@或@ 987654333之前的错误(我在学习自己的机器中不是很有经验)。据我所知,你提供的源代码没有平衡差异或使用绝对值,你确定这本书还不是吗?我看到它的方式y - t或@ 487654335 @不能是非常好的错误措施,这就是为什么:
      n = 2                 # We only have two output neurons
      ts = [ 0, 1 ]         # Our target outputs
      ys = [ 0.999, 0.001 ] # Our sigmoid outputs
      
      # Notice that your outputs are the exact opposite of what you want them to be.
      # Yet, if you use (y - t) or (t - y) to measure your error for each neuron and
      # then sum up to get the total error of the network, you get 0.
      t_minus_y = (0 - 0.999) + (1 - 0.001)
      y_minus_t = (0.999 - 0) + (0.001 - 1)
      

      编辑: per alfa's comment,在书中,y - t实际上是MSE的衍生。在这种情况下,t - y是不正确的。但是,请注意,MSE的实际导数是2 * (y - t) / n,不仅仅是y - t

      如果不划分n(所以你实际上有一个总和平方错误(SSE),而不是均匀的错误),那么衍生物将是2 * (y - t)。此外,如果您使用SSE / 2作为您的错误测量,那么1 / 22在衍生物取消,您留下了y - t

      【讨论】:

      • 问题是:您需要y-t for backpropagation(参见例如github.com/OpenANN/OpenANN/blob/master/src/Net.cpp,第323行)。它不是错误测量,它是平方误差的(均值)的衍生物。无论是 y-t 还是 t-y,它都应该有所不同。
      • 哦,我明白了,我糊涂了。
      • @ alfa是在bpnn.py中在bpnn.py中说出当前实现不正确? span>
      • @ fidesfacitfidem确定,它实际上是错误的,但这没关系,因为,它确实渐变上升而不是梯度下降:self.wi [i] [j] = self.wi [i] [ j] + Nchange + Mself.ci[i][j] 您可以将 +s 替换为 -s 并使用 error = self.ao[k] - targets[k] 并会得到结果相同。
      • 另外动量的实现其实是错误的,因为它只合并了之前的梯度。通常它应该使用所有以前的梯度,权重呈指数衰减。 :)
      【解决方案4】:

      你必须反向传播的导数

      0.5*(y-t)^2 或 0.5*(t-y)^2 相对于 y

      总是这样

      y-t = (y-t)(+1) = (t-y)(-1)

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-03
        • 2012-02-21
        • 2011-01-05
        • 1970-01-01
        • 1970-01-01
        • 2016-09-19
        • 2014-03-15
        相关资源
        最近更新 更多