了解神经网络反向传播

Posted

技术标签:

【中文标题】了解神经网络反向传播【英文标题】:Understanding Neural Network Backpropagation 【发布时间】:2011-01-12 12:59:01 【问题描述】:

更新:问题的更好表述。

我试图以 XOR 神经网络为例来理解反向传播算法。对于这种情况,有 2 个输入神经元 + 1 个偏置,隐藏层中的 2 个神经元 + 1 个偏置,以及 1 个输出神经元。

 A   B  A XOR B
 1    1   -1
 1   -1    1
-1    1    1
-1   -1   -1

(来源:wikimedia.org)

我正在使用stochastic backpropagation。

阅读更多内容后,我发现输出单元的错误会传播到隐藏层......最初这很令人困惑,因为当你到达神经网络的输入层时,每个神经元都会得到隐藏层中两个神经元的误差调整。尤其是误差的分布方式,一开始很难掌握。

步骤 1 计算每个输入实例的输出。步骤 2 计算输出神经元之间的误差(在我们的例子中,只有一)和目标值:步骤 3 我们使用步骤 2 中的误差来计算每个隐藏单元 h 的误差:@987654325 @

“权重 kh”是隐藏单元 h 和输出单元 k 之间的权重,这很容易混淆,因为输入单元没有与输出单元相关的直接权重。盯着公式看了几个小时后,我开始思考求和是什么意思,我开始得出结论,连接到隐藏层神经元的每个输入神经元的权重乘以输出误差并求和.这是一个合乎逻辑的结论,但公式似乎有点混乱,因为它清楚地说明了“权重 kh”(在输出层 k 和隐藏层 h 之间)。

我在这里理解正确吗?有人可以证实这一点吗?

输入层的 O(h) 是多少?我的理解是每个输入节点都有两个输出:一个进入隐藏层的第一个节点,一个进入第二个节点隐藏层。两个输出中的哪一个应该插入公式的O(h)*(1 - O(h)) 部分?

【问题讨论】:

昨天看到这个引用并注意到step 2 image has moved 和step 3 image 一样 【参考方案1】:

我从第 3 步的方程式中读到的是:

    O_h = 此隐藏单元的最后输出(输入层上的 O_h 为实际输入值) w_kh = 此隐藏单元与下一层单元之间的连接权重(朝向输出) delta_k = 下一层单元的错误(朝向输出,与上一个项目符号相同的单元)

每个单元只有一个输出,但输出和下一层之间的每个链接都被加权。所以输出是一样的,但是在接收端,如果链接的权重不同,每个单元会收到不同的值。 O_h 总是指最后一次迭代的这个神经元的值。错误不适用于输入层,因为根据定义,输入本身没有“错误”。

误差需要逐层计算,从输出端开始,因为我们需要第N+1层的误差值来计算第N层。你是对的,在反向传播中输入和输出之间没有直接联系.

我相信这个等式是正确的,如果有悖常理的话。可能令人困惑的是,在每个单元的前向传播中,我们必须考虑单元左侧的所有单元和链接(输入值),但对于错误传播(反向传播),我们必须考虑右侧的单元(输出值)正在处理的单元。

【讨论】:

好吧,看了一些我也同意你的观点:O_h是单位的实际值。关于 delta_k 的一点说明:如何为隐藏层计算它?我了解如何为输出层计算它,因为我们可以直接将它与 XOR 目标值进行比较。但是隐藏层的目标值是多少?我假设我们只对输出层计算一次,然后对所有层都使用它。 隐藏神经元没有“目标值”。您必须使用您在步骤 3 中列出的方程式来计算隐藏层神经元的所有 delta_k。请注意,您只需要输出值和右侧层中神经元的误差即可执行此操作 - 这就是为什么必须从输出返回到输入计算误差的原因。 第 2 步中的方程仅适用于输出神经元的错误。步骤 3 中的方程适用于隐藏神经元的错误。输入层神经元没有误差项。 好的,因此输入神经元的增量是通过将其输出 Oh(1-Oh) 与为右侧隐藏单元计算的权重 * 误差之和相乘来计算的。假设顶部隐藏单元的误差为 0.02,底部为 0.01,从输入单元到两个隐藏单元的权重为 0.5,输入单元的输出为 1,那么我们将得到 1(1- 1)(0.5*0.02+0.5*0.01) = 0;因此没有对输入单元的重量进行调整。 刚刚找到了一些可能有帮助的东西,Lirik。看看这里的 C/C++ 源代码:codeproject.com/KB/recipes/BP.aspx - 就在那里。【参考方案2】:

您在此处发布的教程实际上做错了。我对照 Bishop 的两本标准书籍和我的两本工作实现仔细检查了它。我会在下面指出确切的位置。

要记住的重要一点是,您总是在寻找误差函数关于单位或重量的导数。前者是增量,后者是您用来更新权重的。

如果你想了解反向传播,你必须了解链式法则。这都是关于链式法则的。如果您不知道它是如何工作的,请查看 wikipedia - 这并不难。但是,一旦您了解了推导,一切就都到位了。承诺! :)

∂E/∂W可以通过链式法则组合成∂E/∂o ∂o/∂W。 ∂o/∂W 很容易计算,因为它只是一个单元的激活/输出相对于权重的导数。 ∂E/∂o 实际上就是我们所说的增量。 (这里我假设 E、o 和 W 是向量/矩阵)

我们确实将它们用于输出单元,因为这是我们可以计算误差的地方。 (大多数情况下,我们有一个误差函数,它归结为 (t_k - o_k) 的 delta,例如对于线性输出的二次误差函数和逻辑输出的交叉熵。)

现在的问题是,我们如何获得内部单位的导数?好吧,我们知道一个单元的输出是所有传入单元的总和,这些单元按权重加权,然后应用传递函数。所以 o_k = f(sum(w_kj * o_j, 对于所有 j))。

所以我们要做的是,根据 o_j 推导出 o_k。因为 delta_j = ∂E/∂o_j = ∂E/∂o_k ∂o_k/∂o_j = delta_k ∂o_k/o_j。所以给定delta_k,我们可以计算delta_j!

让我们这样做。 o_k = f(sum(w_kj * o_j, 对于所有 j)) => ∂o_k/∂o_j = f'(sum(w_kj * o_j, 对于所有 j)) * w_kj = f'(z_k) * w_kj。

对于 sigmoidal 传递函数,这变为 z_k(1 - z_k) * w_kj。 (这里是教程中的错误,作者说的是o_k(1 - o_k) * w_kj!

【讨论】:

+1 用于将计算细节与反向传播背后的直觉交织在一起。 教程没有错。 f'(z_k) = f(z_k)(1 - f(z_k)),相当于o_k(1 - o_k) 您似乎很了解反向传播@bayer,也许您对***.com/questions/53287032/… 有想法?提前非常感谢【参考方案3】:

我不确定您的问题是什么,但实际上我自己已经完成了该教程,我可以向您保证,除了一个明显的错字之外,没有任何不妥之处。

我会假设您的问题是因为您对反向传播 hidden 增量是如何得出的感到困惑。如果这确实是您的问题,请考虑

(来源:pandamatak.com)

您可能对作者如何得出这个等式感到困惑。这实际上是多元链式法则的直接应用。即,(以下内容来自wikipedia)

"假设 z = f(u, v) 的每个参数都是一个二元函数,使得 u = h(x, y) 和 v = g(x, y),并且这些函数都是可微的. 那么链式法则应该是这样的:

"

现在想象通过一个归纳参数来扩展链式法则

E(z'1,z'2,..,z'n) 其中 z'k 是第 k 个输出层预激活的输出, 和z'k(wji),也就是说E是z'的函数,z'本身是wji的函数sub>(如果一开始这对您没有意义考虑非常仔细地考虑如何设置 NN。)将链式规则直接扩展到 n 个变量:

δE(z'1,z'2,..,z'n)/δwji = ΣkδE/δz'kδz'k/δwji

这是最重要的一步,然后作者再次应用链式法则,这次在和内展开δz'k/δwji 项,即

δz'k/δwji = δz'k/δojδoj/δzjδzj/δwji.

如果您在理解链式法则方面有困难,您可能需要学习一门多元微积分课程,或者阅读教科书中的此类部分。

祝你好运。

【讨论】:

@gmatt,感谢您的参与...这个问题有点老了(2010 年 2 月),但我发现了问题出在哪里。 @Idog 或稍后遇到此问题的任何人,first algorithm has moved 的链接

以上是关于了解神经网络反向传播的主要内容,如果未能解决你的问题,请参考以下文章

弹性反向传播神经网络 - 关于梯度的问题

反向传播训练算法如何工作?

如何通过反向传播训练卷积神经网络中的过滤器?

反向传播

反向传播 - 误差导数

反向传播