【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

我已经有两年 ML 经历,这系列课主要用来查缺补漏,会记录一些细节的、自己不知道的东西。

已经有人记了笔记(很用心,强烈推荐):
https://github.com/Sakura-gh/ML-notes

本节对应笔记:https://sakura-gh.github.io/ML-notes/ML-notes-html/9_Backpropagation.html

本节内容综述

  1. 反向传播就是更好地进行梯度下降的方法;
  2. 并不是很晦涩的数学属性,只需要知道 Chain Rule
  3. 本节课具体阐述了反向传播算法,具体都在“小细节”里。

小细节

Chain Rule

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

如上,定义了损失函数,进行了简单推导后,我们只需:

  • 聚焦在如何计算某一笔数据的偏微分
  • 先考虑某一个神经元。
    【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

如上,将lw\frac{\partial l}{\partial w}拆分成两项,前者较容易计算,如下。
【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

如下,对于某神经元,其输出对权重的偏微分就是输入。
【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

而对于后者lz\frac{\partial l}{\partial z},依然使用链式法则拆分。假设我们的 zz 通过**函数得到 aa 。即这个神经元的输出为 a=σ(z)a = \sigma(z) 。接下来这个 aa 会乘上下一层的权重,然后再加上其他的值得到下一神经元的输入 zz' … 我们这里先不管那么多,只考虑目前这个步骤。

lz=azla\frac{\partial l}{\partial z} = \frac{\partial a}{\partial z} \frac{\partial l}{\partial a}

这里的 az\frac{\partial a}{\partial z} 实际上就是简单的**函数微分σ(z)\sigma'(z),如下图。
【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的
那么 la\frac{\partial l}{\partial a} 是什么呢?

由 chain rule 可知

la=zalz+zalz\frac{\partial l}{\partial a} = \frac{\partial z'}{\partial a} \frac{\partial l}{\partial z'} + \frac{\partial z''}{\partial a} \frac{\partial l}{\partial z''}

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

如上图,首先易得 za=w3\frac{\partial z'}{\partial a}=w_3za=w4\frac{\partial z''}{\partial a}=w_4 ,难点在于 lz\frac{\partial l}{\partial z'}lz\frac{\partial l}{\partial z'‘}

先把其当成常数,把式子整理一下:

lz=σ(z)[w3lz+w4lz]\frac{\partial l}{\partial z} = \sigma'(z) [w_3 \frac{\partial l}{\partial z'} + w_4 \frac{\partial l}{\partial z''}]

Back propagation - Backward pass

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

有没有注意到lz=σ(z)[w3lz+w4lz]\frac{\partial l}{\partial z} = \sigma'(z) [w_3 \frac{\partial l}{\partial z'} + w_4 \frac{\partial l}{\partial z''}]

这个式子的形式和我们前面的lz=azla=σ(z)la\frac{\partial l}{\partial z} = \frac{\partial a}{\partial z} \frac{\partial l}{\partial a}=\sigma'(z)\frac{\partial l}{\partial a}

很像?

因此,我们可以想象一个新的“神经元”,其输入就是 lz\frac{\partial l}{\partial z'}lz\frac{\partial l}{\partial z''} ,输出是 lz\frac{\partial l}{\partial z} 。此外,因为 zz 已经固定,σ(z)\sigma'(z) 是一个常数;因此可以把这个神经元理解为一个放大器

Case 1. Output Layer

如果下面蓝色的神经元是隐藏层最后一层,那么此时就已知神经元输出,则由下式

lz=y1zly1\frac{\partial l}{\partial z'} = \frac{\partial y_1}{\partial z'} \frac{\partial l}{\partial y_1}

一切都可计算:

  • y1z\frac{\partial y_1}{\partial z'} 是**函数偏导;
  • ly1\frac{\partial l}{\partial y_1}loss 对 y1y_1 偏微分。
    【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

Case 2:Not Output Layer

假设下图中红色的神经元并不是输出,那么:

  • zz' 经过**函数得到 aa'
  • aa' 继续到下一层,得到 zaz_azbz_b

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

由上面的“放大器神经元”,我们知道有如下关系:

lz=σ(z)[w5lza+w6lzb]\frac{\partial l}{\partial z'} = \sigma'(z') [w_5 \frac{\partial l}{\partial z_a} + w_6 \frac{\partial l}{\partial z_b}]

可见,尽管我们不知道当前 lz\frac{\partial l}{\partial z} 到底是多少,但是可以通过 lz\frac{\partial l}{\partial z'}lz\frac{\partial l}{\partial z''} 计算;而 lz\frac{\partial l}{\partial z'} 又可以由 lza\frac{\partial l}{\partial z_a}lzb\frac{\partial l}{\partial z_b} 得到…由此,我们可以通过神经网络的反向传播(从 output layer 出发),一层层经过“放大器”,达到我们现在的神经元。

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

所以,我们算偏微分,是从后面的神经元开始算。如下。

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

先算 lz5\frac{\partial l}{\partial z_5}lz6\frac{\partial l}{\partial z_6} 的偏微分,会很有效率。

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

接着后向传播,如上。

Summary

【李宏毅2020 ML/DL】P13 Backpropagation | 神经网络反向传播到底是怎么计算的

最后总结一下:

  • 前向传播计算神经元对权重的偏微分;
  • 后向传播计算目标值对神经元输出的偏微分;
  • 二者相乘得到目标值对权重偏微分。