深度学习基石:一篇文章理解反向传播

原文地址:https://mattmazur.com/2015/03/17/a-step-by-step-backpropagation-example/

逐步反向传播示例

背景

反向传播是训练神经网络的常用方法,之前对此一直了解的不够彻底,这篇文章算是让我彻底搞懂了反向传播的细节。

概观

对于本教程,我们将使用具有两个输入,两个隐藏的神经元,两个输出神经元的神经网络。此外,隐藏和输出神经元将包括一个偏见。

基本结构如下:

neural_network(7)

为了使用一些数字,下面是最初的权重偏见培训输入/输出

neural_network(9)

反向传播的目标是优化权重,以便神经网络可以学习如何正确映射任意输入到输出。

对于本教程的其余部分,我们将使用单个训练集:给定输入0.05和0.10,我们希望神经网络输出0.01和0.99。

前进通行证

首先,让我们看看神经网络目前预测的是什么,给定0.05和0.10的权重和偏差。为此,我们将通过网络向前馈送这些输入。

我们计算出净输入总到每个隐藏层神经元,壁球使用的总净输入激活功能(在这里我们使用的逻辑功能),然后重复上述过程与输出层的神经元。

总净输入也被称为只是 净输入 一些消息来源

以下是我们计算总净投入的方法H_1

net_ {h1} = w_1 * i_1 + w_2 * i_2 + b_1 * 1

net_ {h1} = 0.15 * 0.05 + 0.2 * 0.1 + 0.35 * 1 = 0.3775

然后我们使用逻辑函数对其进行压缩以获得以下输出H_1

out_ {h1} = \ frac {1} {1 + e ^ { -  net_ {h1}}} = \ frac {1} {1 + e ^ { -  0.3775}} = 0.593269992

执行相同的过程,H_2我们得到:

out_ {h2} = 0.596884378

我们重复这个过程为输出层神经元,使用隐藏层神经元的输出作为输入。

以下是输出O-1

net_ {o1} = w_5 * out_ {h1} + w_6 * out_ {h2} + b_2 * 1

net_ {o1} = 0.4 * 0.593269992 + 0.45 * 0.596884378 + 0.6 * 1 = 1.105905967

out_ {o1} = \ frac {1} {1 + e ^ { -  net_ {o1}}} = \ frac {1} {1 + e ^ { -  1.105905967}} = 0.75136507

并执行相同的过程,0-2我们得到:

out_ {o2} = 0.772928465

计算总误差

现在我们可以使用平方误差函数来计算每个输出神经元的误差,并将它们相加得到总误差:

E_ {total} = \ sum \ frac {1} {2}(目标 - 输出)^ {2}

有些来源 将目标称为 理想 ,而输出 则以实际 目标
\压裂{1} {2} 是包括的,以便指数在我们稍后区分时被取消。无论如何,结果最终会乘以学习率,所以我们在这里引入一个常数并不重要[  1  ]。

例如,目标输出为O-10.01,但神经网络输出为0.75136507,因此其误差为:

E_ {o1} = \ frac {1} {2}(target_ {o1} -out_ {o1})^ {2} = \ frac {1} {2}(0.01-0.75136507)^ {2} = 0.274811083

重复这个过程0-2(记住目标是0.99),我们得到:

E_ {o2} = 0.023560026

神经网络的总误差是这些误差的总和:

E_ {total} = E_ {o1} + E_ {o2} = 0.274811083 + 0.023560026 = 0.298371109

向后传递

我们使用反向传播的目标是更新网络中的每个权重,使它们使实际输出更接近目标输出,从而最大限度地减少每个输出神经元和整个网络的误差。

输出层

考虑一下的例句我们想知道变化的例句会影响总误差,也就是说\ frac {\ partial E_ {total}} {\ partial w_ {5}}

\ frac {\ partial E_ {total}} {\ partial w_ {5}} 读作“部分的衍生物 E_ {}总 相对于 W_ {5} ”。你也可以说“关于梯度 W_ {5} ”。

通过应用链式规则,我们知道:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = \ frac {\ partial E_ {total}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\部分net_ {o1}} * \ frac {\ partial net_ {o1}} {\ partial w_ {5}}

在视觉上,这是我们正在做的事情:

output_1_backprop(4)

我们需要找出这个方程中的每一部分。

首先,总误差相对于输出的变化有多大?

E_ {total} = \ frac {1} {2}(target_ {o1} -out_ {o1})^ {2} + \ frac {1} {2}(target_ {o2}  -  out_ {o2})^ { 2}

\ frac {\ partial E_ {total}} {\ partial out_ {o1}} = 2 * \ frac {1} {2}(target_ {o1}  -  out_ {o1})^ {2-1} * -1 + 0

\ frac {\ partial E_ {total}} {\ partial out_ {o1}} =  - (target_ {o1}  -  out_ {o1})=  - (0.01  -  0.75136507)= 0.74136507

- (目标出)  有时表达为  超出目标
当我们取总偏差的偏导数时 OUT_ {} O1 ,数量 \ frac {1} {2}(target_ {o2}  -  out_ {o2})^ {2} 变为零,因为 OUT_ {} O1 它不影响它,这意味着我们正在取一个常数为零的导数。

接下来,O-1相对于其总净投入变化输出多少

逻辑函数的偏导数是输出乘以1减去输出:

out_ {o1} = \ frac {1} {1 + e ^ { -  net_ {o1}}}

(1-out_ {o1})= 0.75136507(1-0.75136507)= 0.186815602

最后,关于O1变化的总净投入是的例句多少?

net_ {o1} = w_5 * out_ {h1} + w_6 * out_ {h2} + b_2 * 1

\ frac {\ partial net_ {o1}} {\ partial w_ {5}} = 1 * out_ {h1} * w_5 ^ {(1-1)} + 0 + 0 = out_ {h1} = 0.593269992

把它放在一起:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = \ frac {\ partial E_ {total}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\部分net_ {o1}} * \ frac {\ partial net_ {o1}} {\ partial w_ {5}}

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = 0.74136507 * 0.186815602 * 0.593269992 = 0.082167041

您经常会看到以delta规则的形式组合这个计算

\ frac {\ partial E_ {total}} {\ partial w_ {5}} =  - (target_ {o1}  -  out_ {o1})* out_ {o1}(1  -  out_ {o1})* out_ {h1}

或者,我们有\ frac {\ partial E_ {total}} {\ partial out_ {o1}}\ frac {\ partial out_ {o1}} {\ partial net_ {o1}}可以写成\ frac {\ partial E_ {total}} {\ partial net_ {o1}},又名\ delta_ {O1}(希腊字母三角洲)aka 节点三角洲我们可以用它来重写上面的计算:

\ delta_ {o1} = \ frac {\ partial E_ {total}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\ partial net_ {o1}} = \ frac {\ partial E_ {total}} {\ partial net_ {o1}}

\ delta_ {o1} =  - (target_ {o1}  -  out_ {o1})* out_ {o1}(1  -  out_ {o1})

因此:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} = \ delta_ {o1} out_ {h1}

有些来源提取负号,\三角洲所以它会写成:

\ frac {\ partial E_ {total}} {\ partial w_ {5}} =  -  \ delta_ {o1} out_ {h1}

为了减少误差,我们从当前权重中减去这个值(可选地乘以一些学习率eta,我们将其设置为0.5):

w_5 ^ {e} * \ frac {\ partial E_ {total}} {\ partial w_ {5}} = 0.4  -  0.5 * 0.082167041 = 0.35891648

有些  来源 使用 \α (alpha)来表示学习率, 其他来源使用  \ ETA (eta), 其他 使用 \小量 (epsilon)。

我们可以重复这个过程中获得新的权重w_6w_7以及w_8

w_6 ^ {+} = 0.408666186

w_7 ^ {+} = 0.511301270

w_8 ^ {+} = 0.561370121

我们将新权重引入隐含层神经元之后,我们执行神经网络中的实际更新(即,当我们继续下面的反向传播算法时,我们使用原始权重,而不是更新的权重)。

隐藏层

接下来,我们将继续为新的计算值,向后传递W_1W_2w_3,和W_4

大图片,这是我们需要弄清楚的:

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = \ frac {\ partial E_ {total}} {\ partial out_ {h1}} * \ frac {\ partial out_ {h1}} {\ partial net_ {h1}} * \ frac {\ partial net_ {h1}} {\ partial w_ {1}}

视觉:

NN-计算

我们将使用与输出层类似的过程,但略有不同,以说明每个隐藏层神经元的输出对多个输出神经元的输出(并因此产生误差)的贡献。我们知道这OUT_ {} H1影响到两者OUT_ {} O1OUT_ {} O2因此\ frac {\ partial E_ {total}} {\ partial out_ {h1}}需要考虑它对两个输出神经元的影响:

\ frac {\ partial E_ {total}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial out_ {h1}} + \ frac {\ partial E_ {o2}} {\部分out_ {h1}}

从以下开始\ frac {\ partial E_ {o1}} {\ partial out_ {h1}}

\ frac {\ partial E_ {o1}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial net_ {o1}} * \ frac {\ partial net_ {o1}} {\部分out_ {h1}}

我们可以\ frac {\ partial E_ {o1}} {\ partial net_ {o1}}使用我们之前计算的值来计算:

\ frac {\ partial E_ {o1}} {\ partial net_ {o1}} = \ frac {\ partial E_ {o1}} {\ partial out_ {o1}} * \ frac {\ partial out_ {o1}} {\部分net_ {o1}} = 0.74136507 * 0.186815602 = 0.138498562

并且\ frac {\ partial net_ {o1}} {\ partial out_ {h1}}等于的例句

net_ {o1} = w_5 * out_ {h1} + w_6 * out_ {h2} + b_2 * 1

\ frac {\ partial net_ {o1}} {\ partial out_ {h1}} = w_5 = 0.40

将它们插入:

\ frac {\ partial E_ {o1}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial net_ {o1}} * \ frac {\ partial net_ {o1}} {\部分out_ {h1}} = 0.138498562 * 0.40 = 0.055399425

按照相同的过程\ frac {\ partial E_ {o2}} {\ partial out_ {h1}},我们得到:

\ frac {\ partial E_ {o2}} {\ partial out_ {h1}} = -0.019049119

因此:

\ frac {\ partial E_ {total}} {\ partial out_ {h1}} \ frac {\ partial E_ {o1}} {\ partial out_ {h1}} + \ frac {\ partial E_ {o2}} {\部分out_ {h1}} = 0.055399425 + -0.019049119 = 0.036350306

现在,我们有\ frac {\ partial E_ {total}} {\ partial out_ {h1}},我们需要弄清楚\ frac {\ partial out_ {h1}} {\ partial net_ {h1}},然后\ frac {\ partial net_ {h1}} {\ partial w}每一个权重:

out_ {h1} = \ frac {1} {1 + e ^ { -  net_ {h1}}}

(1  -  0.59326999)= 0.241300709(1  -  out_ {h1})= 0.59326999

我们计算总净投入的偏导数,H_1W_1我们对输出神经元所做的相同:

net_ {h1} = w_1 * i_1 + w_3 * i_2 + b_1 * 1

\ frac {\ partial net_ {h1}} {\ partial w_1} = i_1 = 0.05

把它放在一起:

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = \ frac {\ partial E_ {total}} {\ partial out_ {h1}} * \ frac {\ partial out_ {h1}} {\ partial net_ {h1}} * \ frac {\ partial net_ {h1}} {\ partial w_ {1}}

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = 0.036350306 * 0.241300709 * 0.05 = 0.000438568

你也可以看到这写成:

\ frac {\ partial E_ {total}} {\ partial w_ {1}} =(\ sum \ limits_ {o} {\ frac {\ partial E_ {total}} {\ partial out_ {o}} * \ frac { \ partial {​{}} {\ partial net_ {o}} \ \ frac {\ partial net_ {o}} {\ partial out_ {h1}}})* \ frac {\ partial out_ {h1}} {\ partial net_ {h1}} * \ frac {\ partial net_ {h1}} {\ partial w_ {1}}

\ frac {\ partial E_ {total}} {\ partial w_ {1}} =(\ sum \ limits_ {o} {\ delta_ {o} * w_ {ho}})* out_ {h1}(1  -  out_ { h1})* i_ {1}

\ frac {\ partial E_ {total}} {\ partial w_ {1}} = \ delta_ {h1} i_ {1}

我们现在可以更新W_1

w1 ^ {+} = w_1  -  \ eta * \ frac {\ partial E_ {total}} {\ partial w_ {1}} = 0.15  -  0.5 * 0.000438568 = 0.149780716

重复这些W_2w_3W_4

w_2 ^ {+} = 0.19956143

w_3 ^ {+} = 0.24975114

w_4 ^ {+} = 0.29950229

最后,我们已经更新了所有的重量!当我们最初输入0.05和0.1的输入时,网络上的误差为0.298371109。在第一轮反向传播之后,总误差现在降至0.291027924。它可能看起来并不多,但是在重复这个过程10,000次后,错误会直线下降到0.0000351085。此时,当我们提前0.05和0.1时,两个输出神经元产生0.015912196(vs 0.01目标)和0.984065734(vs 0.99目标)。

如果你已经做到了这一点,并发现上述任何错误,或者可以想出任何方法使未来的读者更清楚,不要犹豫,给我一个笔记谢谢!


  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值