最近在跟着Datawhale组队学习打卡,学习李宏毅的机器学习/深度学习的课程。
课程视频:https://www.bilibili.com/video/BV1Ht411g7Ef
开源内容:https://github.com/datawhalechina/leeml-notes
本篇文章对应视频中的P13-14。另外,最近我也在学习邱锡鹏教授的《神经网络与深度学习》,会补充书上的一点内容。
通过上一次课3.误差和梯度下降,我们了解到误差中的bias和variance,以及梯度下降中调整学习率、随机梯度下降和特征缩放。本篇文章主要介绍深度学习介绍和反向传播机制。
1. 深度学习
在前面的文章中提到过机器学习有三个步骤,对于deep learning其实也是3个步骤:(1)神经网络(Neural network);(2)模型评估(Goodness of function);(3)选择最优函数(Pick best function)
1.1 神经网络
神经网络里面的节点,类似神经元。有很多逻辑回归函数,其中每个逻辑回归都有自己的权重和自己的偏差,这些权重和偏差就是参数
θ
\theta
θ。
- 完全连接前馈神经网络 Fully Connect Feedforward Network
如果一个神经网络中的权重和偏差都知道的话,可以把它看做一个function。图中每个神经元都是一个sigmoid函数。
(1)fully connect:两层之间的neuron神经元两两相连。(2)Feedforward前馈:传递的方向是由后往前传
通常分为3层:输入层,隐藏层,输出层
- 矩阵计算 matrix operation
整个神经网络运算就相当于一连串的矩阵运算。
本质:通过隐藏层进行特征转换。(1)隐藏层通过特征提取来替代原来的特征工程,提取得到的一组最好的特征;(2)输出层就是把前面的隐藏层的输出当做输入,再通过一个多分类器(可以是softmax函数)得到最后的输出y。
举一个手写数字体识别的例子:
(1)输入:一个16*16=256维的向量,每个pixel对应一个dimension,有颜色用(ink)用1表示,没有颜色(no ink)用0表示 输出:10个维度,每个维度代表一个数字的置信度。
(2)输出:每一个维度对应输出一个数字,说明这张图片是2的可能性。
(3)function:输入是256维的向量,输出是10维的向量
1.2 模型评估
一般采用损失函数来反应模型的好差。不仅要计算一笔数据的,而是要计算整体所有训练数据的损失,然后把所有的训练数据的损失都加起来,得到一个总体损失L。
1.3 选择最优函数
在深度学习中,仍然是使用gradient descent 梯度下降。
2. 反向传播
在深度学习中有一个问题,就是网络中的参数有上百万维,如何才能把这个上百万维的矩阵有效的计算出来。因此,我们需要用到反向传播backpropagation,它其实就是一种能够有效率地计算矩阵的梯度下降。
2.1 链式法则求导 Chain Rule
这里我们只需要记住两个数学公式
如
果
y
=
g
(
x
)
,
z
=
h
(
y
)
则
有
d
z
d
x
=
d
z
d
y
d
y
d
x
如
果
x
=
g
(
s
)
,
y
=
h
(
s
)
,
z
=
k
(
x
,
y
)
则
有
d
z
d
s
=
∂
z
∂
x
d
z
d
x
+
∂
z
∂
y
d
z
d
y
如果y=g(x) ,z=h(y)则有\\ \frac{dz}{dx} = \frac{dz}{dy} \frac{dy}{dx} \\ 如果x=g(s),y=h(s), z=k(x,y)则有\\ \frac{dz}{ds} = \frac{\partial z}{\partial x}\frac{dz}{dx} + \frac{\partial z}{\partial y}\frac{dz}{dy}
如果y=g(x),z=h(y)则有dxdz=dydzdxdy如果x=g(s),y=h(s),z=k(x,y)则有dsdz=∂x∂zdxdz+∂y∂zdydz
2.2 反向传播代价函数 Cost Function
- 损失函数(Loss function)是单个训练样本上的误差
- 代价函数(Cost function)是在整个训练集上所有样本的误差的总和的平均,也就是损失函数的总和的平均
- 总体损失函数(Total loss function)是定义在整个训练集上面的误差的和,即反向传播需要最小化的值。
之后我们不会用损失函数,而是关注用代价函数来计算偏微分。我们只需要(1)计算对某一部分数据的
∂
C
n
∂
w
\frac{\partial C^n}{\partial w}
∂w∂Cn ,(2)再提交所有的training data,(3)就可以得出total loss,
L
(
θ
)
L(\theta)
L(θ) 对某一个参数的偏微分。
先考虑一个神经元来计算分析。这里,我们把计算梯度分成两个部分(可以看到下图左下方,利用链式法则变换成2项):
(1)Forward pass的部分:计算
∂
z
∂
w
\frac{\partial z}{\partial w}
∂w∂z
(2)Backward pass的部分:计算
∂
l
∂
z
\frac{\partial l}{\partial z}
∂z∂l
- 对于(1)Forward pass的部分:计算
∂
z
∂
w
\frac{\partial z}{\partial w}
∂w∂z ,有一个计算规律:其计算结果就看weight前面的input是什么,如
x
1
,
x
2
x_1, x_2
x1,x2 ,这就是为什么该步骤被叫做Forward pass。
- 对于(2)Backward pass的部分:这个步骤比较困难,因为 l l l 是最后计算出来的。
(1)看到下图的神经元(蓝色圆圈),假设 z z z 通过sigmoid方程得到输出 a a a ;
(2)然后我们知道, a a a会乘上 w 3 w_3 w3以及其他东西得到 z ′ z' z′,同样, a a a也会乘上 w 4 w_4 w4以及其他东西得到 z ′ ′ z'' z′′;
通过链式法则的计算,我们可以得到下图的式子。 ∂ a ∂ z \frac{\partial a}{\partial z} ∂z∂a比较容易计算,所以我们需要解决 ∂ l ∂ a \frac{\partial l}{\partial a} ∂a∂l的求解。
(1) a a a 通过 z ′ z' z′和 z ′ ′ z'' z′′可以影响 l l l(下图右边的式子)。
(2) ∂ z ′ ∂ a \frac{\partial z'}{\partial a} ∂a∂z′ 的计算我们在Forward pass的部分就已经知道如何求解,所以我们需要解决 ∂ l ∂ z ′ \frac{\partial l}{\partial z'} ∂z′∂l和 ∂ l ∂ z ′ ′ \frac{\partial l}{\partial z''} ∂z′′∂l 的求解。
所以我们可以得到,
∂
l
∂
z
\frac{\partial l}{\partial z}
∂z∂l的式子如下图。
这里,我们可以从另外一个角度看这个事情,现在有另外一个神经元,把forward的过程逆向过来,其中 σ ′ ( z ) {\sigma}'(z) σ′(z)是常数,因为它在向前传播的时候就已经确定了。
现在,我们继续求 ∂ l ∂ z ′ \frac{\partial l}{\partial z'} ∂z′∂l和 ∂ l ∂ z ′ ′ \frac{\partial l}{\partial z''} ∂z′′∂l 。我们分情况讨论,看 ∂ l ∂ z ′ \frac{\partial l}{\partial z'} ∂z′∂l和 ∂ l ∂ z ′ ′ \frac{\partial l}{\partial z''} ∂z′′∂l是否为最后一层隐藏层(即蓝色的神经元的下一层是否为输出层 Output Layer)。
- 下一层是输出层
- 下一层不是输出层
如果上图绿色神经元不是输出层,我们需要继续往后面层计算,一直到碰到输出值,得到输出值之后再反向往输入那个方向走。
Backward pass总结:我们的目标是要求计算
∂
z
∂
w
\frac{\partial z}{\partial w}
∂w∂z(Forward pass的部分)和计算
∂
l
∂
z
\frac{\partial l}{\partial z}
∂z∂l ( Backward pass的部分 ),然后把
∂
z
∂
w
\frac{\partial z}{\partial w}
∂w∂z 和
∂
l
∂
z
\frac{\partial l}{\partial z}
∂z∂l相乘,我们就可以得到
∂
l
∂
w
\frac{\partial l}{\partial w}
∂w∂l,所有我们就可以得到神经网络中所有的参数,然后用梯度下降就可以不断更新,得到损失最小的函数。