Bootstrap

反向传播算法详细计算过程与结论公式

计算过程

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


输入层有两个神经元i1i2,隐藏层有两个神经元h1h2,偏差都为b1,输出层有两个神经元o1o2,偏差都为b2,权重为w
神经元的输入经过激活函数转变为输出,即带权输入net经过激活函数转变为输出激活值out,如图所示:

现在一步一步进行计算

前向传播

输入层 -> 隐藏层
  1. 计算隐藏层神经元h1h2带权输入
    neth1=ω1i1+ω2i2+b1

    neth2=ω3i1+ω4i2+b1
  2. 计算h1h2输出激活值(激活函数为sigmoid函数):
    sigmoid函数: S(x)=11+ex
outh1=11+eneth1
outh2=11+eneth2
隐藏层 -> 输出层
  1. 计算输出层神经元o1o2带权输入
    neto1=ω5outh1+ω6outh2+b2

    neto2=ω7outh1+ω8outh2+b2
  2. 计算o1o2输出激活值
    outo1=11+eneto1

    outo2=11+eneto2

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

反向传播

计算误差(代价函数)
  1. 分别计算o1o2的误差:
    这里使用二次代价函数: E=12(targetoutput)2
Eo1=12(targeto1outputo1)2
Eo2=12(targeto2outputo2)2
2. 计算总误差:

总误差为: Etotal=12(targetoutput)2

Etotal=Eo1+Eo2
权值更新

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

隐藏层 -> 输出层的权值更新
  1. w5为例:

    Etotalouto1outo1neto1neto1ω5=Etotalω5

    下图可以更直观的感受反向传播误差:

  2. 分别计算等号左边的三个式子:

    • Etotalouto1
      Etotal=12(targeto1outputo1)2+12(targeto2outputo2)2

      Etotalouto1=(targeto1outputo1)
    • outo1neto1 (即对sigmoid函数求导):
      outo1=11+eneto1

      outo1neto1=outo1(1outo1)
    • neto1ω5
      neto1=ω5outh1+ω6outh2+b2

      neto1ω5=outh1
  3. 然后乘起来即可:

    Etotalω5=(targeto1outputo1)outo1(1outo1)outh1

    现在我们得到了整体误差E(total)w5的偏导值,为了表达方便,在此我们定义:

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

  4. 那么δo1即为神经元o1误差,即:

    δo1=Etotalouto1outo1neto1=Etotalneto1

    δo1=(targeto1outputo1)outo1(1outo1)

    所以,整体误差E(total)w5的偏导为:
    Etotalω5=δo1outh1

    最后,w5得到更新:
    ω5ω5ηEtotalω5

    η 学习速率,也叫步长

输入层(隐藏层) -> 隐藏层的权值更新
  1. w1为例:

    Etotalouth1outh1neth1neth1ω1=Etotalω1

    计算方法与上面类似,但是有个地方需要变一下,在计算h1的误差时,out(h1)会接受来自o1o2两个神经元的误差,所以在这两个都要计算

  2. 分别计算等号左边的三个式子:

    • Etotalouth1
      Etotalouth1=Eo1outh1+Eo2outh1

      先计算 Eo1outh1
      Eo1outh1=Eo1neto1neto1outh1

      其中:
      Eo1neto1=Eo1outo1outo1neto1

      neto1=ω5outh1+ω6outh2+b2

      neto1outh1=ω5

      得到:
      Eo1outh1=Eo1outo1outo1neto1ω5

      代入上边计算出的结果可得:
      Eo1outh1=(targeto1outputo1)outo1(1outo1)ω5

      观察1,2两个式子,我们可以发现,等号右边的左边两项,其实就是δo1,所以上式可以化简为:
      Eo1outh1=δo1ω5

      同理可得另一项:
      Eo2outh1=δo2ω7

      然后加起来便得到第一项:
      Etotalouth1=δo1ω5+δo2ω7
    • outh1neth1 (即对sigmoid函数求导):
      outh1=11+eneth1

      outh1neth1=outh1(1outh1)
    • neth1ω1
      neth1=ω1i1+ω2i2+b1

      neth1ω1=i1
  3. 然后乘起来即可:

    Etotalω1=(δo1ω5+δo2ω7)outh1(1outh1)i1

  4. 那么δh1即为神经元h1误差,即:
    δh1=Etotalouth1outh1neth1=Etotalneth1

    δh1=(δo1ω5+δo2ω7)outh1(1outh1)

    所以,整体误差E(total)w1的偏导为:
    Etotalω1=δh1i1

    最后,w5得到更新:
    ω1ω1ηEtotalω1

结论公式

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

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

输出层误差的方程

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

δLj=CaLjσ(zLj)

用微分算子表示的矩阵形式为:
δL=aCσ(zL)

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

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

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

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

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

Cb=δ

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

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

z=ωain+b

可知,代价函数 Cω的偏导是在误差的基础上乘上了输入激活值:
Cω=ainδout

总结

四个公式:

δL=aCσ(zL)

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

Cb=δ

Cω=ainδout

参考:
1. http://www.cnblogs.com/charlotte77/p/5629865.html
2. http://neuralnetworksanddeeplearning.com/

;