反向传播 - 李宏毅机器学习笔记

输入通过前向传播由输入层传播到输出层;梯度通过后向传播由输出层传播到输入层。 

\begin{bmatrix} z_{1}^{l }\\ z_{2}^{l } \\ \vdots \\ z_{m}^{l} \end{bmatrix} = \begin{bmatrix} w_{11}^{l } \ w_{12}^{l } \ \cdots w_{1n}^{l } \\ w_{21}^{l} \ w_{22}^{l} \ \cdots w_{2n}^{l } \\ \vdots \\ w_{m1}^{l} \ w_{m2}^{l} \ \cdots w_{mn}^{l } \end{bmatrix} \begin{bmatrix} a_{1}^{l-1}\\ a_{2}^{l-1} \\ \vdots \\ a_{n}^{l - 1} \end{bmatrix} + \begin{bmatrix} b_{1}^{l }\\ b_{2}^{l } \\ \vdots \\ b_{m}^{l } \end{bmatrix} \ \ \ \ \ \ \ (1)

\begin{bmatrix} a_{1}^{l }\\ a_{2}^{l } \\ \vdots \\ a_{m}^{l} \end{bmatrix} = \sigma (\begin{bmatrix} z_{1}^{l }\\ z_{2}^{l } \\ \vdots \\ z_{m}^{l} \end{bmatrix} ) \ \ \ \ \ \ \ (2) 

\begin{bmatrix} z_{1 + 1}^{l + 1 }\\ z_{2}^{l + 1} \\ \vdots \\ z_{r}^{l + 1} \end{bmatrix} = \begin{bmatrix} w_{11}^{l + 1 } \ w_{12}^{l + 1} \ \cdots w_{1m}^{l + 1} \\ w_{21}^{l + 1} \ w_{22}^{l + 1} \ \cdots w_{2m}^{l + 1} \\ \vdots \\ w_{r1}^{l + 1} \ w_{r2}^{l + 1} \ \cdots w_{rm}^{l + 1} \end{bmatrix} \begin{bmatrix} a_{1}^{l}\\ a_{2}^{l} \\ \vdots \\ a_{m}^{l } \end{bmatrix} + \begin{bmatrix} b_{1}^{l+1 }\\ b_{2}^{l+1 } \\ \vdots \\ b_{r}^{l + 1 } \end{bmatrix} \ \ \ \ \ \ \ (3)

 

 

求解\frac{\partial C}{\partial w_{ij}^{l}}

\frac{\partial C}{\partial w_{ij}^{l}} = \frac{\partial z_{i}^{l}}{\partial w_{ij}^{l}} \frac{\partial C}{\partial z_{i}^{l}} = a_{i}^{l-1} \frac{\partial C}{\partial z_{i}^{l}} \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (4)

可见若我们能够求解出\frac{\partial C}{\partial z_{i}^{l}},就 ok 啦,下面就看如何求解 \frac{\partial C}{\partial z_{i}^{l}} 

\begin{aligned} \frac{\partial C}{\partial z_{i}^{l}} &= \frac{\partial a_{i}^{l }}{\partial z_{i}^{l}} \frac{\partial C}{\partial a_{i}^{l }} =\sigma^{'}(z_{i}^{l}) \cdot \frac{\partial C}{\partial a_{i}^{l }} \\ &=\sigma^{'}(z_{i}^{l}) \cdot( \frac{\partial z_{1}^{l +1} }{\partial a_{i}^{l }} \frac{\partial C}{\partial z_{1}^{l +1}} + \frac{\partial z_{2}^{l +1} }{\partial a_{i}^{l }} \frac{\partial C}{\partial z_{2}^{l +1}} + \cdots + \frac{\partial z_{r}^{l +1} }{\partial a_{i}^{l }} \frac{\partial C}{\partial z_{r}^{l +1}} )\\ &= \sigma^{'}(z_{i}^{l}) \cdot( \sum_{k=1}^{r}\frac{\partial z_{k}^{l +1} }{\partial a_{i}^{l }} \frac{\partial C}{\partial z_{k}^{l +1}} )\\ &= \sigma^{'}(z_{i}^{l}) \cdot( \sum_{k=1}^{r} w_{ki}^{l + 1} \frac{\partial C}{\partial z_{k}^{l +1}}) \end{aligned} \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ (5)

结合(4)和 (5)

\frac{\partial C}{\partial w_{ij}^{l}} = a_{i}^{l-1} \cdot \sigma^{'}(z_{i}^{l}) \cdot \frac{\partial C}{\partial a_{i}^{l }} = a_{i}^{l-1} \cdot \sigma^{'}(z_{i}^{l}) (\sum_{k=1}^{r} w_{ki}^{l + 1} \frac{\partial C}{\partial z_{k}^{l +1}} ) \ \ \ \ (6)

若我们能够求解出\frac{\partial C}{\partial z_{i}^{l}},就可算出对 w_{ij}^{l} 的偏微分。

而要求解 \frac{\partial C}{\partial z_{i}^{l}} 就得有 \frac{\partial C}{\partial z_{k}^{l +1}},这是一个很好的递归公式,要求该层对 z 的偏微分,就得知道后续所有层对z的偏微分,直至输出层,时间复杂度O(n^2)。换种思路,我们可以从最后一层往前求解,则这种求解走一遍,所有的都可以求解,时间复杂度O(n)。图示如下:

 N个样本的损失函数,其中C^{n}(\theta)代表单个样本损失函数:

L(\theta) = \sum_{n=1}^{N}C^{n}(\theta)

求解梯度,以 weight 为例, bias 同理:

\frac{\partial L(\theta) }{\partial w} = \sum_{n=1}^{N} \frac{\partial C^{n}(\theta)}{\partial w}

可见,我们只要求解单个样本上的梯度,再对所有样本梯度求和,就可以了。

下面以输入层、所有隐藏层、输出层均为2维为例,仅考虑单个样本的 weight 的梯度。

 整个梯度求解 \frac{\partial C}{\partial w_{1}} = \frac{\partial z_{1}^{'}}{\partial w_{1}} \frac{\partial C}{\partial z_{1}^{'}} 分为两步

  • 前向传播:\frac{\partial z_{1}^{'}}{\partial w_{1}}
  • 后向传播:\frac{\partial C}{\partial z_{1}^{'}}

前向传播比较好求解 \frac{\partial z_{1}^{'}} {\partial w_{1}} ,因为 z 和 w 的式子很简单 z_{1}^{'} = x^{'} w_{1} + x^{''}w_{2} + b

\left\{\begin{matrix} \partial z_{1}^{'} / \partial w_{1} = x^{'}\\ \partial z_{1}^{'} / \partial w_{2} = x^{''} \end{matrix}\right.

看 w 的前面接的是啥(上一个神经元的输出值 or 输入层)就是啥,我们在前向传播的时候会计算出每个神经元的输出值,所以这边很容易就能拿到上一个神经元的输出值,如下图,激活函数取 sigmoid ( \sigma )函数。

\begin{aligned} \left\{\begin{matrix} z_{1}^{'} &= 1* 1 + (-1) * (-2) + 1 = 4 & a_{1}^{'} &= \sigma [z_{1}^{'}] =0.98 \\ z_{1}^{''} &= 1 * (-1) + (-1) * 1 + 0 = -2 & a_{1}^{''} &= \sigma [z_{1}^{''}] =0.12\\ z_{2}^{'} &= z_{1}^{'} * 2 + z_{1}^{''}*(-1) + 0= 1.84 & a_{2}^{'} &= \sigma [z_{2}^{'}] =0.86 \\ z_{2}^{''} &= z_{1}^{'} * (-2) + z_{1}^{''} + 0 = -2.08 & a_{2}^{''} &= \sigma [z_{2}^{''}] =0.11\\ \end{matrix}\right. \end{aligned}

后向传播 \frac{\partial C} {\partial z_{1}^{'}} 比较复杂。

有如下公式, z 先经过激活函数输出 a , a 再通过后续的神经元影响 C 。

a_{1}^{'} = \sigma[z_{1}^{'}]

\frac{\partial C} {\partial z_{1}^{'}} =\frac{\partial a_{1}^{'}} {\partial z_{1}^{'}} \frac{\partial C} {\partial a_{1}^{'}} ,

a 对 z 的偏导很好求,\frac{\partial a_{1}^{'}} {\partial z_{1}^{'}} = \sigma ^{'}[z_{1}^{'}] ,因为在前向传播过程中所有神经元的输出已经计算出来了,即 z 已经固定下来了,所以 \sigma ^{'}[z_{1}^{'}] 是一个可以求解的数值。

那么就剩下 \partial C / \partial a_{1}^{'} ,a_{1}^{'} 是通过 z_{2}^{'} 和 z_{2}^{''} 对 C 产生影响。

\frac{\partial C}{\partial a_{1}^{'}} = \frac{\partial z_{2}^{'}}{\partial a_{1}^{'}}\frac{\partial C}{\partial z_{2}^{'}} + \frac{\partial z_{2}^{''}}{\partial a_{1}^{'}}\frac{\partial C}{\partial z_{2}^{''}} ,因为 \left\{\begin{matrix} z_{2}^{'} = a_{1}^{'} w_{3} +\cdots \\ z_{2}^{''} = a_{1}^{'} w_{4} +\cdots \end{matrix}\right. ,所以 \left\{\begin{matrix} \partial z_{2}^{'} / \partial a_{1}^{'} = w_{3} \\ \partial z_{2}^{''} / \partial a_{1}^{'} = w_{4} \end{matrix}\right. ,故 \frac{\partial C}{\partial a_{1}^{'}} =w_{3}\frac{\partial C}{\partial z_{2}^{'}} + w_{4}\frac{\partial C}{\partial z_{2}^{''}} 。

\frac{\partial C} {\partial z_{1}^{'}} =\frac{\partial a_{1}^{'}} {\partial z_{1}^{'}} \frac{\partial C} {\partial a_{1}^{'}} = \sigma ^{'}[z_{1}^{'}][w_{3}\frac{\partial C}{\partial z_{2}^{'}} + w_{4}\frac{\partial C}{\partial z_{2}^{''}}] 。若我们能够知道 \frac{\partial C}{\partial z_{2}^{'}} 和 \frac{\partial C}{\partial z_{2}^{''}} 就可以求解了。我们要知道当前层的梯度,就先得知道他后面一层的梯度,这可以看作一个递归问题,递归结束的条件就是在输出层求解时,我们只要知道 激活函数 和 损失函数就可以求了,而这俩函数是固定的。下面我们看输出层。

输出层是很好求的,\partial y / \partial z 只要知道激活函数是啥就可以求解, \partial C / \partial y 只要知道损失函数就可以求解:

\frac{\partial C}{ \partial z^{'}} = \frac{\partial y_{1}}{ \partial z^{'}}\frac{\partial C}{ \partial y_{1}} , \ \ \ \ \ \frac{\partial C}{ \partial z^{''}} = \frac{\partial y_{2}}{ \partial z^{''}}\frac{\partial C}{ \partial y_{2}}

只要输出层求出来了,它前面的一层也就可以求出来了,依次下去可以理解为递归求解。但是递归的复杂度比较高,求解当前层梯度,需要从当前层一直求解到输出层,可以发现很多层的梯度都被求解了不止一次,复杂度很高。若是我们换个方式来看待,直接从输出层开始往前求解,也可以理解成将递归求解转换为动态规划求解,从后往前求解也是后向传播的由来。这个思路可以由下图表示,我们将输入是 \frac{\partial C} {\partial z^{'}} 和 \frac{\partial C} {\partial z^{''}} ,它们的权重分别为 w_{3} 和 w_{4} ,再乘上激活函数带来的梯度 \sigma ^{'}[z] ,这个梯度对后向传播来说是一个常数,因为前向传播的时候就固定了,就得到输出 \frac{\partial C} {\partial z} 。所以梯度求解可以看作是梯度经过一个类似的神经网络从后往前传播。

参考

https://speech.ee.ntu.edu.tw/~tlkagk/courses/ML_2016/Lecture/BP.pdf

https://www.youtube.com/watch?v=ibJpTrp5mcE

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值