「机器学习-李宏毅」:Backpropagation

这篇文章中,讲解了Deep Learning中使用的一种高效Gradient Descent的算法:BackPropagation。
BackPropagation通过正向传播和反向传播两个阶段,最后能一起算出损失函数对每一个参数的gradient。

Gradient Descent

在Neural Network中,参数的更新也是通过Gradient Descent。

但是当Neural Network层数很深,结构很复杂的时候,会有millions of parapmeters。

Backpropagation:To compute the gradient efficiently.

Chain Rule

BP中需要用到的数学知识:微积分中的链式法则。

Jmc7z4.md.png

Backpropagation

JmcTWF.md.png

在NN中,定义损失函数 $L(\theta)=\sum_{n=1}^{N} C^{n}(\theta)$

($\theta$ 代指NN中所有的weight 和bias,$C$ 为Cross-entropy)

对某一参数的gradient为 $\frac{\partial L(\theta)}{\partial w}=\sum_{n=1}^{N} \frac{\partial C^{n}(\theta)}{\partial w}$

JmcoJU.md.png

在上图NN中,我们先只研究红框部分,即是以下结构:

JmcIiT.md.png

z:每个activation function的输入。

根据链式法则, $\frac{\partial C}{\partial w}= \frac{\partial z}{\partial w} \frac{\partial C}{\partial z}$ .

要计算每个参数的 $\frac{\partial C}{\partial w}$ ,分为两部分。

  1. Forward pass: compute $\frac{\partial z}{\partial w} $ for all parameters.
  2. Backward pass: compute $\frac{\partial C}{\partial z} $ for all activation function inputs z.

BP:Forward pass

Compute $\frac{\partial z}{\partial w} $ for all parameters.

Jmchd0.md.png

还是只看上图这一部分,可以轻易得出: $\partial{z}/\partial{w_1}=x_1\qquad \partial{z}/\partial{w_2}=x_2$

得到结论: $\frac{\partial z}{\partial w} $ 等于 the value of the input connected by the weight.

【$\frac{\partial z}{\partial w} $ 等于 连接w的输入的值】


那么,如何计算出NN中全部的 $\frac{\partial z}{\partial w} $ ?

Jmc4oV.md.png

:Forward pass.

用当前参数(w,b)

从hidden layer的第一层开始,计算出第一层的输出,即第二层的输入。

依次相前计算,计算出每一层的输出,即下一层的输入,即输入所连接权重的 $\frac{\partial z}{\partial w}$ 。

BP:Backward pass

Compute $\frac{\partial C}{\partial z} $ for all activation function inputs z.

JmcfZq.md.png

z:activation function的 input

a:activation function的 output

这里的activation function 是 sigmod函数 $a=\sigma(z)=\frac{1}{1+e^{-z}}$

要求 $\frac{\partial C}{\partial z}$ , 再根据链式法则: $\frac{\partial C}{\partial z}=\frac{\partial a}{\partial z}\frac{\partial C}{\partial a}$

  1. 求 $\frac{\partial{a}}{\partial{z}}$ : $\frac{\partial{a}}{\partial{z}}=\sigma'(z)=\sigma(z)(1-\sigma(z))$ (是其他activation function 也能轻易求出)

  2. 求 $\frac{\partial C}{\partial a}$ :根据链式法则: $\frac{\partial C}{\partial a}=\frac{\partial z^{\prime}}{\partial a} \frac{\partial C}{\partial z^{\prime}}+\frac{\partial z^{\prime \prime}}{\partial a} \frac{\partial C}{\partial z^{\prime \prime}}$

    JmcfZq.md.png
    • $\frac{\partial z^{\prime}}{\partial a} =w_3$ , $\frac{\partial z^{\prime\prime}}{\partial a} =w_4$
    • $\frac{\partial C}{\partial z^{\prime}}$ 和 $\frac{\partial C}{\partial z^{\prime\prime}}$ ?假设,已经通过某种方法算出这个值。
  3. $\frac{\partial C}{\partial z}=\sigma^{\prime}(z)\left[w_{3} \frac{\partial C}{\partial z^{\prime}}+w_{4} \frac{\partial C}{\partial z^{\prime \prime}}\right]$

    这个式子,可以画成一个反向传播的NN,见下图。

    JmcRLn.md.png $\frac{\partial C}{\partial z^{\prime}},\frac{\partial C}{\partial z^{\prime\prime}}$ 是这个neuron的输入, $w_3,w_4$ 仍然是 neuron的 weight(无bias)。

    $\sigma’(z)$ 是一个常数,因为在forward pass中每一个activation的输入已经被算出来了。

    和forward pass中的NN的区别是,forward 中是一个activation function,输入z作用于这个函数;

    而在 backward pass中,这更像一个放缩器,将他的输入变小,即乘上一个 $\sigma’(z)$ 。


问题还是如何计算 $\frac{\partial C}{\partial z}=\sigma^{\prime}(z)\left[w_{3} \frac{\partial C}{\partial z^{\prime}}+w_{4} \frac{\partial C}{\partial z^{\prime \prime}}\right]$ ?

分为两种情况讨论, $z’,z’’$ 是否为输出层的输入?

  • Output Layer:

    Jmc2ss.md.png

    z’,z’’:activation function的输入。

    y1,y2:actiavtion function(也是NN)的输出。

    C:NN输出和target的cross entropy。

    根据链式法则: $\frac{\partial C}{\partial z^{\prime}}=\frac{\partial y_{1}}{\partial z^{\prime}} \frac{\partial C}{\partial y_{1}} \quad \frac{\partial C}{\partial z^{\prime \prime}}=\frac{\partial y_{2}}{\partial z^{\prime \prime}} \frac{\partial C}{\partial y_{2}}$

    所以,已知activation function(simod或者其他),可以轻易求出 $\frac{\partial y_{1}}{\partial z^{\prime}}(=\sigma'(z'))$ 和 $\frac{\partial y_{2}}{\partial z^{\prime\prime}}(=\sigma''(z''))$ 。

    所以,已知损失函数,也可以轻易求出 $\frac{\partial C}{\partial y_1}$ 和 $\frac{\partial C}{\partial y_2}$ 。( $C\left(y, \hat{y}\right)=-\left[\hat{y} \ln y+\left(1-\hat{y}\right) \ln \left(1-y\right)\right]$ )

    所以,可以直接求出 $\frac{\partial C}{\partial z}=\sigma^{\prime}(z)\left[w_{3} \frac{\partial C}{\partial z^{\prime}}+w_{4} \frac{\partial C}{\partial z^{\prime \prime}}\right]$ 。

  • Not Output Layer:

    JmcsJS.md.png

    上图中,如果我们要计算 $\frac{\partial C}{\partial z’}$ ,必须要已知下一层的 $\frac{\partial C}{\partial z_a}$ ,然后一直递归下去,直到到达最后的输出层,也就是上面一种情况,可以直接计算出,再递归回来,计算当前层的 $\frac{\partial C}{\partial z’}$ 。

    但是,这样计算每个参数的 $\frac{\partial{C}}{\partial{z}}$ 都要一直递归到输出层,效率显然太低了。

    JmcyRg.md.png

    计算方法如上图:

    当我们已知输出层的 $\frac{\partial{C}}{\partial{z'}},\frac{\partial{C}}{\partial{z''}}$ 时,再通过上面的步骤3(且的确算出了 $\frac{\partial{C}}{\partial{z'}},\frac{\partial{C}}{\partial{z''}}$ ),画成反向的NN,计算$\frac{\partial{C}}{\partial{z}}$.

    再依次反向传播计算出每一个neuron的输出z (也是正向传播neuron的输入)的 $\frac{\partial{C}}{\partial{z}}$ .


Backforward pass 的做法:

Jmcri8.md.png
  1. 先计算出输出层的 $\frac{\partial{C}}{\partial{z}}$ (也就是上图的 $\frac{\partial{C}}{\partial{z_5}}$ 和 $\frac{\partial{C}}{\partial{z_6}}$ )
  2. 用反向传播的NN,向后依次计算出每一层每一个neuron的 $\frac{\partial{C}}{\partial{z}}$ 。

Summary

JmcgMj.md.png

公式: $\frac{\partial z}{\partial w} \frac{\partial C}{\partial z}=\frac{\partial C}{\partial w}$

在正向传播NN中,z是neuron的activation function的输入。

在反向传播NN中,z是neuron的放缩器的输出。

通过Forward Pass计算出正向传播NN的每一个neuron的 $\frac{\partial z}{\partial w}$ ,等于该层neuron的输入。

通过Backward Pass计算出反向传播NN的每一个neuron的 $\frac{\partial C}{\partial z}$ 。

然后,通过相乘,计算出每个参数的 $\frac{\partial C}{\partial w}$。

Reference

「机器学习-李宏毅」:Backpropagation

https://f7ed.com/2020/04/18/Backpropagation/

Author

f1ed

Posted on

2020-04-18

Updated on

2021-01-25

Licensed under

CC BY-NC-SA 4.0


Comments