1. 神经网络(neural networks)简介
这部分直接截了3Blue1Brown关于神经网络介绍视频的图(做的太漂亮了)
普通的神经网络结构如图所示,每一个“神经元”的输出值乘以权重并相加,再加上一个Bias,经过一个压缩函数(Sigmoid,Relu等),生成下一层的“神经元”的值。
现在有一个神经网络,我们希望它能识别数字0到9。
一个未训练好的神经网络,输出值会与实际结果有较大误差(以节点的明暗表示,图片应当被识别为3)
由于输出层的“神经元”的激活值,与上一层中每一个“神经元”都有关,为了减小误差,我们会想要调整上一层神经元的激活值(实际不能调整激活值,只能调整权重和偏置!)
输出层的每一个“神经元”,对如何调整,都有“自己的想法”。相加之后,就能知道如何调整倒数第二层“神经元”的激活值。
将倒数第二层的调整值也看作“误差”,进而思考倒数第三层“神经元”的激活值如何调整,层层倒推,这一条训练数据对神经网络全体参数的优化就完成了。
将所有训练数据,都进行一次反向传播,计算每条训练数据对权重和偏置调整的平均值,就得到了代价函数的负梯度。
但是神经网络中参数相当多,如何求偏导就是个大问题!
接下来跟着李宏毅的网课学习。
2. 反向传播算法
2.1 链式求导法则
无需多言。
2.2 反向传播
只要能计算一个数据的损失函数C(交叉熵)对w的偏导,就能得到整个损失函数L对w的偏导。
根据链式法则,可将偏导分为两部分
∂
z
∂
w
∂
C
∂
z
\frac{\partial z}{\partial w}\frac{\partial C}{\partial z}
∂w∂z∂z∂C
前一部分很好计算,因为是正向传播,输入已知
难点在于后一部分
继续变形公式
假设已知C对z’和z’‘的偏导
就好像一个从输出到输入方向的神经网络(但是没有sigmoid这样的压缩函数)
接下来只要分情况计算C对z’和z’‘的偏导,就可以完成整个反向传播公式了。
情况1:z’和z’‘即为输出层的输入,可以直接计算
情况2:更一般的情况,z’和z’'处于隐含层中的某一层,则重复上述算法
发现又需要求两个偏导,如此层层递进,不免繁琐。
如果我们反过来从输出层,一步步求所有C对z的偏导,则每个只需计算一次,方便快捷
最后总结,做一次正向传播和一次反向传播,就能计算出所有C对w的偏导。
3. 推广到矩阵形式
只是了解原理,并写不出代码,因为我还是不知道如何对矩阵求导。
这里学习了一篇知乎专栏
道理我都懂,但是神经网络反向传播时的梯度到底怎么求?
第一个关键点在于L(Loss Function)是一个标量,而标量对一个矩阵求导,其大小和这个矩阵的大小永远是一样的。
设某一层的Forward Pass为
z
=
X
W
+
b
z = XW+b
z=XW+b, X是NxD的矩阵,W是DxC的矩阵,b是1xC的矩阵,那么z就是一个NxC的矩阵。接下来求L对W和b的导数。
∂
L
∂
z
\frac{\partial L}{\partial z}
∂z∂L一定是一个NxC的矩阵(因为Loss是一个标量,score的每一个元素变化,Loss也会随之变化)
利用链式法则,就有
∂
L
∂
W
=
∂
L
∂
z
∂
z
∂
W
\frac{\partial L}{\partial W} =\frac{\partial L}{\partial z}\frac{\partial z}{\partial W}
∂W∂L=∂z∂L∂W∂z
我们没有必要直接求z对W的导数,我们可以利用另外两个导数间接地把它算出来。
∂
L
∂
W
\frac{\partial L}{\partial W}
∂W∂L的大小为DxC,
∂
L
∂
z
\frac{\partial L}{\partial z}
∂z∂L的大小为NxC,为满足矩阵乘法,
∂
z
∂
W
\frac{\partial z}{\partial W}
∂W∂z的大小为DxN,且矩阵相乘顺序应为
∂
L
∂
W
=
∂
z
∂
W
∂
L
∂
z
\frac{\partial L}{\partial W} =\frac{\partial z}{\partial W}\frac{\partial L}{\partial z}
∂W∂L=∂W∂z∂z∂L
既然z=XW+b,如果都是标量的话,z对W求导,本身就是X;X是NxD大小的矩阵,我们要DxN的,进行一次转置,得到结果如下:
∂
L
∂
W
=
X
⊺
∂
L
∂
z
\frac{\partial L}{\partial W} =\mathbf{X}^\intercal\frac{\partial L}{\partial z}
∂W∂L=X⊺∂z∂L
第二个关键点在于用好链式法则,不要一步到位
比如
H
=
e
X
W
+
b
H = e^{XW+b}
H=eXW+b,如果要求L对W的偏导,就回发现,
∂
H
∂
W
\frac{\partial H}{\partial W}
∂W∂H无从下手,卡壳的原因在于,它根本不是一个矩阵,而是一个4维的tensor。
如果不直接求对W的导数,而将XW+b作为一个中间变量
(element-wise即为对应位置元素相乘)
(未完待续)