反向传播算法
- 一、计算图
- 二、一直是后面导数乘以当前自变量系数,得出当前自变量的导数?*(我个人疑问)
- 三、链式法则(反向传播的精髓,一定搞明白,不然没法向下继续学习)
- 四、反向传播
- 加法节点的反向传播
- 乘法节点的反向传播(明显看出来受到相乘系数就是偏导)
反向传播(Backward Propagation 或 Back Propagation,BP 算法)指的是计算神经网络参数梯度的方法。简言之,该方法根据微积分中的链式法则,按相反的顺序从输出层到输入层遍历网络。该算法存储了计算某些参数梯度时所需的任何中间变量。
复合函数的链式求导法则
一、计算图
计算图将计算过程用图表示出来。这里说的图是数据结构中的图,通过多个节点和边表示(连接节点的直线称为边)。
如上就是 100 × 2 + 150 × 3 = 650 的计算图表示。
计算图的基本计算原则,就是从输入出发、按照箭头方向,从左到右依次进行计算,最终得到输出结果。这个过程,其实就是 前向传播(forward)。
计算图的特点是可以通过传递“局部计算”获得最终结果。即只需根据与自己相关的信息输出接下来的结果。无论全局的计算有多么复杂,各个节点所要做的就是进行局部计算并传递计算结果,最终得出全局的复杂计算的结果
如果增加更多的计算环节,比如再乘以一个“零售加价系数”,计算图如下所示
如果我们进一步考虑,当衣服的价格上涨(输入变化)时,会多大程度上影响最后要支付的金额(输出结果)?
将输入的衣服价格记为( x (x(x),输出的支付金额记为( L (L(L),这其实就是要求导数值( ∂ L ∂ x (\frac{\partial L}{\partial x}(∂x∂L)。在计算图上,我们可以利用反向(从右到左)的传递来方便地计算导数。这个过程,就可以叫做反向传播(backward)。
这里衣服加1,收到和他相乘个数影响,就变成2,如果再来一个相乘个数x,那就是 2x,这里最后零售价加价系数也是相乘1.1,所以变成2.2x 这就是衣服加1最终总价影响,变得是衣服单价,他最终影响收到相乘的影响,从而得出衣服单价对总价的导数
如果衣服件数加1,他的导数是110(一定根据这简单举例明白这些局部偏导):这里每次自变量变化,对应局部导数就是和自变量变化 相乘的那个数加法,当前局部导数就是1,没变化
方式一:顺着你的思路(计算图反向传播求导)
正向传播(先看数值变化):
如果衣服件数原来是 2,现在加 1 变成 3。
衣服的总价从 (100 \times 2 = 200) 变成了 (100 \times 3 = 300),也就是增加了 100。
最终支付金额增加了 (100 \times 1.1(零售系数) = 110)。反向传播(求导数,即图中的红色箭头):
- 看“衣服件数”到“乘法节点”这条边:局部导数是衣服单价,也就是100。
- 看“加法节点”的右侧:加法直接传递,导数依然是100。
- 看“乘法节点(乘以1.1)”这条边:局部导数是零售系数1.1。
- 最后把路径上的局部导数相乘:(100 \times 1.1 = \mathbf{110})。
所以,衣服件数对最终总价的导数是 110。
方式二:用纯数学公式推导(最严谨)
我们把整个过程写成一个总价公式:
设 (Y) 为最终支付金额,(x) 为衣服件数。
(Y = (衣服单价 \times x + 裤子单价 \times 裤子件数) \times 零售系数)
代入图中的数字:
(Y = (100 \times x + 150 \times 3) \times 1.1)
(Y = 110x + 495)
现在我们对 (x)(衣服件数)求导:
(\frac{\partial Y}{\partial x} = 110)
公式求导的结果也是 110。
二、一直是后面导数乘以当前自变量系数,得出当前自变量的导数?*(我个人疑问)
在计算图里,这被称为“上游传来的导数(后面的导数)”乘以“当前节点的局部导数(也就是你说的当前自变量系数)”。
场景一:单纯的乘法节点(适用我疑问的规律)
假设函数是( y = 3 x (y = 3x(y=3x)(系数是 3)。
- 如果( x (x(x) 变化一点点,( y (y(y) 的变化量就是( x (x(x) 变化量的 3 倍。
- 所以,( ∂ y ∂ x = 3 (\frac{\partial y}{\partial x} = 3(∂x∂y=3)。
- 如果这个乘法节点前面还有更复杂的网络,后面传回来的导数是( L ′ (L'(L′)(上游导数)。
- 那么( x (x(x) 的导数就是:( L ′ × 3 (L' \times 3(L′×3)。
这就是你说的“后面导数 x 当前系数”。
场景二:加法节点(你的规律的补充)
假设函数是( y = x + z (y = x + z(y=x+z)(加法节点)。
- 如果( x (x(x) 变化一点点,( y (y(y) 的变化量就是( x (x(x) 的变化量,不会放大也不会缩小。
- 所以,加法节点的局部导数(系数)永远是 1。
- 如果后面传回来的导数是( L ′ (L'(L′)(上游导数)。
- 那么( x (x(x) 的导数就是:( L ′ × 1 = L ′ (L' \times 1 = L'(L′×1=L′)。
这也印证了你说的规律:乘以当前系数(加法节点系数是1,相当于没变)。
三、链式法则(反向传播的精髓,一定搞明白,不然没法向下继续学习)
反向传播将局部导数向反方向传递,传递的原理基于链式法则。反向传播时将信号乘以节点的局部导数然后传递给下一个节点。
仔细想下面这链式法则,很重要仔细想下面这链式法则,很重要仔细想下面这链式法则,很重要L 代表的就是最后整体计算的结果(通常在神经网络中,L 代表 Loss,即最终的损失函数值;在你之前看的价格计算图里,L 就是最终的支付总金额
举例:
对于复合函数( z = ( x + y ) 2 (z = (x + y)^2(z=(x+y)2),令( u = x + y (u = x + y(u=x+y),则
∂ z ∂ x = ∂ z ∂ u ∂ u ∂ x = 2 u × 1 = 2 ( x + y ) \frac{\partial z}{\partial x} = \frac{\partial z}{\partial u} \frac{\partial u}{\partial x} = 2u \times 1 = 2(x + y)∂x∂z=∂u∂z∂x∂u=2u×1=2(x+y)
四、反向传播
利用计算图的反向传播,可以很容易地计算出输出关于输入的偏导数。
加法节点的反向传播
对于( z = x + y (z = x + y(z=x+y),( ∂ z ∂ x = 1 (\frac{\partial z}{\partial x} = 1(∂x∂z=1),( ∂ z ∂ y = 1 (\frac{\partial z}{\partial y} = 1(∂y∂z=1)。因此加法的反向传播会将上游传来的值原样向下游传递。
乘法节点的反向传播(明显看出来受到相乘系数就是偏导)
对于( z = x y (z = xy(z=xy),( ∂ z ∂ x = y (\frac{\partial z}{\partial x} = y(∂x∂z=y),( ∂ z ∂ y = x (\frac{\partial z}{\partial y} = x(∂y∂z=x)。因此乘法的反向传播会将上游传来的值乘以输入的翻转向下游传递。
这里在前向传播的过程就要记住得到的x是多少,y是多少,并保存。因为这写值在反向传播的时候,且是乘法节点时候会影响当前局部导数。所以在反向传播的时候一定要先执行一次前向传播