计算过程

现在我们有这样一个神经网络:

吴恩达反向传播 反向传播计算公式_吴恩达反向传播



输入层有两个神经元i1i2,隐藏层有两个神经元h1h2,偏差都为b1,输出层有两个神经元o1o2,偏差都为b2,权重为w

神经元的输入经过激活函数转变为输出,即带权输入net经过激活函数转变为输出激活值out,如图所示:

吴恩达反向传播 反向传播计算公式_深度学习_02

现在一步一步进行计算

前向传播

输入层 -> 隐藏层
  1. 计算隐藏层神经元h1h2带权输入
    neth1=ω1∗i1+ω2∗i2+b1
    neth2=ω3∗i1+ω4∗i2+b1
  2. 计算h1h2输出激活值(激活函数为sigmoid函数):

sigmoid函数: S(x)=11+e−x


outh1=11+e−neth1


outh2=11+e−neth2

隐藏层 -> 输出层
  1. 计算输出层神经元o1o2带权输入
    neto1=ω5∗outh1+ω6∗outh2+b2
    neto2=ω7∗outh1+ω8∗outh2+b2
  2. 计算o1o2输出激活值
    outo1=11+e−neto1
    outo2=11+e−neto2

至此,我们就计算出了前向传播的输出,接下来进行反向传播

反向传播

计算误差(代价函数)
  1. 分别计算o1o2的误差:

这里使用二次代价函数:E=12(target−output)2


Eo1=12(targeto1−outputo1)2


Eo2=12(targeto2−outputo2)2

2. 计算总误差:

总误差为:Etotal=∑12(target−output)2


Etotal=Eo1+Eo2

权值更新

微分知识告诉我们,导数体现变化率,那么权值对于总误差的影响则体现在导数上
要更新权值,就要计算总误差对权值的偏导数,即权值能对总误差产生多少影响,这里用到了链式法则

隐藏层 -> 输出层的权值更新
  1. w5为例:
    ∂Etotal∂outo1∗∂outo1∂neto1∗∂neto1∂ω5=∂Etotal∂ω5
    下图可以更直观的感受反向传播误差:
  2. 分别计算等号左边的三个式子:
  • ∂Etotal∂outo1:
    Etotal=12(targeto1−outputo1)2+12(targeto2−outputo2)2
    ∂Etotal∂outo1=−(targeto1−outputo1)
  • ∂outo1∂neto1(即对sigmoid函数求导):
    outo1=11+e−neto1
    ∂outo1∂neto1=outo1(1−outo1)
  • ∂neto1∂ω5:
    neto1=ω5∗outh1+ω6∗outh2+b2
    ∂neto1∂ω5=outh1
  1. 然后乘起来即可:
    ∂Etotal∂ω5=−(targeto1−outputo1)∗outo1(1−outo1)∗outh1
    现在我们得到了整体误差E(total)w5的偏导值,为了表达方便,在此我们定义:

δ为神经元的误差
(与上文提到的误差不同,上文着重最终结果的误差,此处更着重单个神经元的误差)

  1. 那么δo1即为神经元o1误差,即:
    δo1=∂Etotal∂outo1∗∂outo1∂neto1=∂Etotal∂neto1
    δo1=−(targeto1−outputo1)∗outo1(1−outo1)
    所以,整体误差E(total)w5的偏导为:
    ∂Etotal∂ω5=δo1∗outh1
    最后,w5得到更新:
    ω5→ω5−η∗∂Etotal∂ω5

η是学习速率,也叫步长

输入层(隐藏层) -> 隐藏层的权值更新
  1. w1为例:
    ∂Etotal∂outh1∗∂outh1∂neth1∗∂neth1∂ω1=∂Etotal∂ω1
    计算方法与上面类似,但是有个地方需要变一下,在计算h1的误差时,out(h1)会接受来自o1o2两个神经元的误差,所以在这两个都要计算
  2. 分别计算等号左边的三个式子:
  • ∂Etotal∂outh1:
    ∂Etotal∂outh1=∂Eo1∂outh1+∂Eo2∂outh1
    先计算∂Eo1∂outh1:
    ∂Eo1∂outh1=∂Eo1∂neto1∗∂neto1∂outh1
    其中:
    ∂Eo1∂neto1=∂Eo1∂outo1∗∂outo1∂neto1
    neto1=ω5∗outh1+ω6∗outh2+b2
    ∂neto1∂outh1=ω5
    得到:
    ∂Eo1∂outh1=∂Eo1∂outo1∗∂outo1∂neto1∗ω5
    代入上边计算出的结果可得:
    ∂Eo1∂outh1=−(targeto1−outputo1)∗outo1(1−outo1)∗ω5
    观察1,2两个式子,我们可以发现,等号右边的左边两项,其实就是δo1,所以上式可以化简为:
    ∂Eo1∂outh1=δo1∗ω5
    同理可得另一项:
    ∂Eo2∂outh1=δo2∗ω7
    然后加起来便得到第一项:
    ∂Etotal∂outh1=δo1∗ω5+δo2∗ω7
  • ∂outh1∂neth1(即对sigmoid函数求导):
    outh1=11+e−neth1
    ∂outh1∂neth1=outh1(1−outh1)
  • ∂neth1∂ω1:
    neth1=ω1∗i1+ω2∗i2+b1
    ∂neth1∂ω1=i1
  1. 然后乘起来即可:
    ∂Etotal∂ω1=(δo1∗ω5+δo2∗ω7)∗outh1(1−outh1)∗i1
  2. 那么δh1即为神经元h1误差,即:
    δh1=∂Etotal∂outh1∗∂outh1∂neth1=∂Etotal∂neth1
    δh1=(δo1∗ω5+δo2∗ω7)∗outh1(1−outh1)
    所以,整体误差E(total)w1的偏导为:
    ∂Etotal∂ω1=δh1∗i1
    最后,w5得到更新:
    ω1→ω1−η∗∂Etotal∂ω1

结论公式

首先我们重新规定一下命名,z表示带权输入,a表示输出激活值,即为经过激活函数的带权输入,C表示代价函数,L表示神经网络的层数。

现在我们以sigmoid激活函数为例,用四个公式总结一下反向传播算法

输出层误差的方程

L层第j个神经元的误差:


δLj=∂C∂aLj∗σ′(zLj)


用微分算子表示的矩阵形式为:



δL=∇aC⊙σ′(zL)

使用下一层的误差表示当前层的误差

下一层的误差呈上下一层的权重值,再点乘上当前层的输出,即为当前层的误差:


δl=(δl+1(ωl+1)T)⊙σ′(zl)

偏置b在代价函数C中的改变率

仔细观察上述计算过程可以发现,偏置b是带权输入z中的一项,而且偏置b的系数为1,所以我们可以得出,代价函数C对某神经元的偏置b的偏导即为该神经元的误差:


∂C∂b=δ

权重ω在代价函数C中的改变率

根据带权输入的表达式(ain为输入该神经元的激活值):


z=ω∗ain+b


可知,代价函数

C

ω的偏导是在误差的基础上乘上了输入激活值:



∂C∂ω=ain∗δout

总结

四个公式:


δL=∇aC⊙σ′(zL)



δl=(δl+1(ωl+1)T)⊙σ′(zl)



∂C∂b=δ



∂C∂ω=ain∗δout

参考:
2. http://neuralnetworksanddeeplearning.com/