反向传播的微积分原理 | Chapter 4 | Deep Learning | 3Blue1Brown
目录
- 前言
- 1. 简介
- 2. 神经网络中的链式法则
- 3. 微积分的计算
- 4. 公式含义
- 5. 代价函数对权重偏置的敏感度
- 6. 多个神经元的情形
- 7. 回顾
- 相关资料
- 结语
前言
3Blue1Brown 视频笔记,仅供自己参考
这个章节主要来深度讲解反向传播中的一些微积分理论
官网:https://www.3blue1brown.com
视频:https://www.bilibili.com/video/BV16x411V7Qg
1. 简介
这章开始我们就假设你已经看过第三章了,上章让大家直观上感受了反向传播算法的原理
在这章里,我们会更深入讲解一些其中的微积分理论,这个看不太懂很正常,所以我们的六字格言 “停一停想一想” 在这依旧管用,这章我们的目标是给大家展示在机器学习中,我们一般是怎么理解链式法则的,这点跟别的基础微积分课讲得会有点不一样
对于微积分不够熟悉的观众,我之前已经做了一整个系列了,大家感兴趣的可以看看:Calculus
2. 神经网络中的链式法则
我们从最最简单的网络讲起吧,每层只有一个神经元
图上这个网络就是由 3 个权重和 3 个偏置决定的,我们的目标是理解代价函数对于这些变量有多敏感,这样我们就知道怎么调整这些变量才可以使得代价降低得最快,
我们先来关注最后两个神经元吧,我给最后一个神经元的激活值一个上标 L,表示它处于第 L 层,那么,前一个神经元的激活值就是 a ( L − 1 ) a^{(L-1)} a(L−1),这里的上标不是指数,而是用来标记我们正在讨论哪一层,过一会我会用到下标来表示别的意思
给定一个训练样本,我们把这个最终层激活值要接近的目标叫做 y,例如 y 可能是 0 或者 1,那么这个简易网络对于单个训练样本的代价就等于 ( a ( L ) − y ) 2 \color{black}(a^{(L)}-\color{gold}y\color{black})^2 (a(L)−y)2,对于这个样本,我们把这个代价值标记为 C 0 \color{red}C_0 C0
还记得吗,最终层的激活值是这么算出来的,即一个权重 w L \color{blue}w^L wL 乘上前一个神经元的激活值再加上一个偏置 b L \color{pink}b^L bL,最后把加权和塞进一个特定的非线性函数,例如 sigmoid 或者 ReLU 之类的,给这个加权和起一个名字会方便很多,就叫它 z L \color{green}z^L zL 好了,跟对应的激活值用同一个上标
这里的项挺多,概括起来我们拿权重 w L \color{blue}w^L wL、前一个激活值 a ( L − 1 ) a^{(L-1)} a(L−1) 以及偏置值 b L \color{pink}b^L bL 一起来算出 z L \color{green}z^L zL 再算出 a ( L ) a^{(L)} a(L),最后再用上常量 y \color{gold}y y 算出代价值 C 0 \color{red}C_0 C0,当然 a ( L − 1 ) a^{(L-1)} a(L−1) 也是由它自己的权重和偏置决定的,以此类推,但我们现在重点不在那里
上面这些东西都是数字,没错吧,我们可以想象每个数字都对应一个数轴,我们第一个目标是理解代价函数对权重 w L \color{blue}w^L wL 的微小变化有多敏感,或者换句话讲求 C 0 \color{red}C_0 C0 对 w L \color{blue}w^L wL 的导数
当你看到 ∂ w \color{blue}\partial w ∂w 之类的项时,请把它当做这是对 w \color{blue}w w 的微小扰动,好比改变 0.01,然后把 ∂ C 0 \color{red}\partial C_0 ∂C0 当做 “改变 w \color{blue}w w 对 C 0 \color{red}C_0 C0 的值造成的变化”,我们求得是这两个数的比值
概念上说 w L \color{blue}w^L wL 的微小变化会导致 z L \color{green}z^L zL 产生些变化,然后会导致 a L a^L aL 产生变化,最终影响到代价值
那么,我们把式子拆开,首先求 z L \color{green}z^L zL 的变化量比上 w L \color{blue}w^L wL 的变化量,也就是求 z L \color{green}z^L zL 关于 w L \color{blue}w^L wL 的导数,同理考虑 a L a^L aL 的变化量比上因变量 z L \color{green}z^L zL 的变化量,以及最终的 C 0 \color{red}C_0 C0 的变化量比上直接改动 a L a^L aL 产生的变化量
这不就是链式法则么,把三个比值相乘就可以算出 C 0 \color{red}C_0 C0 对 w L \color{blue}w^L wL 的微小变化有多敏感
3. 微积分的计算
现在图上多了一大堆符号,稍微花点时间理解一下每个符号都是什么意思吧,因为马上我们就要对各个部分求导了
C 0 \color{red}C_0 C0 关于 a L a^L aL 的导数就是 2 ( a ( L ) − y ) \color{black}2(a^{(L)}-\color{gold}y\color{black}) 2(a(L)−y),这也就意味着导数的大小跟网络最终的输出减目标结果的差成正比,如果网络的输出差别很大,即使 w \color{blue}w w 稍稍变一点代价也会改变非常大
a L a^L aL 对 z L \color{green}z^L zL 求导就是求 sigmoid 的导数,或就你选择的非线性激活函数求导
而 z L \color{green}z^L zL 对 w L \color{blue}w^L wL 求导结果就是 a L − 1 a^{L-1} aL−1
4. 公式含义
对我自己来说,这里如果不退一步好好想想这些公式的含义,很容易卡住
就最后这个导数来说,这个权重的改变量 ∂ w \color{blue}\partial w ∂w 对最后一层的影响有多大取决于之前一层的神经元,所谓的 “一同激活的神经元关联在一起” 的出处即来源于此
不过这只是包含一个训练样本的代价对 w ( L ) \color{blue}w^{(L)} w(L) 的导数,由于总的代价函数是许许多多训练样本所有代价的总平均,它对 w ( L ) \color{blue}w^{(L)} w(L) 的导数就需要求 ∂ C ∂ w ( L ) \frac{\color{red}\partial C}{\color{blue}\partial w^ {(L)}} ∂w(L)∂C 这个表达式之于每一个训练样本的平均
当然这只是梯度向量 ∇ C \color{red}\nabla C ∇C 的一个分量,而梯度向量 ∇ C \color{red}\nabla C ∇C 本身则由代价函数对每一个权重和每一个偏置求偏导构成的
5. 代价函数对权重偏置的敏感度
值得注意的是,求出这些偏导中的一个就完成了一大半的工作量,对偏置的求导步骤也就基本相同,只要把 ∂ z ∂ w \frac{\color{green}\partial z}{\color{blue} \partial w} ∂w∂z 替换成 ∂ z ∂ b \frac{\color{green}\partial z}{\color{pink} \partial b} ∂b∂z,对应的公式中可以看出导数 ∂ z ∂ b \frac{\color{green}\partial z}{\color{pink} \partial b} ∂b∂z 等于 1
这里也涉及到了反向传播的概念,我们来看下这个代价函数对上一层激活值的敏感度,展开来说,链式法则的第一项 z \color{green}z z 对上一层激活值的敏感度就是权重 w ( L ) \color{blue}w^{(L)} w(L)
虽然说过我们不能直接改变激活值,但我们很有必要关注这个值,因为我们可以反向应用链式法则来计算代价函数对之前的权重偏置的敏感度
6. 多个神经元的情形
你可能觉得这个例子举得太简单了,毕竟每层只有一个神经元,而真实的神经网络会比这个例子复杂百倍,然而说真的,每层多加若干个神经元并不会复杂很多,真的,只不过多写一些下标罢了
我们用加上下标的神经元来表示 L 层的若干神经元,而不是用 a ( L ) a^{(L)} a(L) 统称 L 层的激活值,现在用 k 来标注 L-1 层的神经元,j 则是 L 层的神经元
现在要求代价函数,我们从期望的输出着手,计算上一层激活值和期望输出的差值的平方然后求和,即求 ( a j ( L ) − y j ) 2 \color{black}(a_j^{(L)}-\color{gold}y_j\color{black})^2 (aj(L)−yj)2 的和
由于权重的数量多了不少,那么每个权重要多用几个下标,我们记连接第 k 个神经元和第 j 个神经元的连线为 w j k ( L ) \color{blue}w_{jk}^{(L)} wjk(L),这些下标感觉像标反了,可能有点别扭,不过和第一章中的权重矩阵的下标是一致的
同样的,把加权和记为 z 总是很方便,那么最后一层的激活值依然等于指定的函数(如 sigmoid)在 z 处的函数值
你懂我意思吧,现在的方程式和之前每层只有一个神经元的时候本质是一样的,只是看着复杂一些
链式法则形式的导数表达式所描述的代价对某个权重的敏感度也是一样的,这里大家可以暂停推导一下每一项的含义,唯一改变的是代价对 L-1 层激活值的导数
此时,激活值可以通过不同的途径影响代价函数,也就是说,神经元一边通过 a 0 ( L ) a_0^{(L)} a0(L) 来影响代价函数,另一边通过 a 1 ( L ) a_1^{(L)} a1(L) 来影响代价函数,得把这些都加起来,然后…就搞定了
只要计算出倒数第二层代价函数对激活值的敏感度,接下来只要重复上述过程,计算喂给倒数第二层的权重和偏置就好了
7. 回顾
现在长吁一口气吧!如果上面这些明白了,那你就看明白了神经网络的主力—反向传播
链式法则表达式给出了决定梯度每个分量的偏导,使得我们能不断下探,最小化神经网络的代价
静下来想一想你会发现这些复杂的层层叠叠很烧脑,消化这些知识需要花一些时间,这很正常
相关资料
- http://neuralnetworksanddeeplearning.com/chap2.html
- https://github.com/mnielsen/neural-networks-and-deep-learning
- https://colah.github.io/posts/2015-08-Backprop/
结语
这个章节我们主要学习了反向传播以微积分的形式表达,其核心就是链式法则
OK,以上就是本章的全部内容了,下章我们来讲 Transformer,敬请期待😄