2.0 通俗地理解三大概念
这三大概念是:反向传播,梯度下降,损失函数。
神经网络训练的最基本的思想就是:先“猜”一个结果,我们叫预测结果a,看看这个预测结果和事先标记好的训练集中的真实结果y之间的差距,然后调整策略,再试一次,这一次就不是“猜”了,而是有依据地向正确的方向靠近。如此反复多次,一直到预测结果和真实结果之间相差无几,亦即|a-y|->0,就结束训练。
总结
简单总结一下反向传播与梯度下降的基本工作原理:
- 初始化;
- 正向计算;
- 损失函数为我们提供了计算损失的方法;
- 梯度下降是在损失函数基础上向着损失最小的点靠近而指引了网络权重调整的方向;
- 反向传播把损失值反向传给神经网络的每一层,让每一层都根据损失值反向调整权重;
- goto 2,直到精度足够好(比如损失函数值小于0.001)。
2.1 线性传播
2.2 反向传播
2.3 梯度下降
2.3.1 从自然现象中理解梯度下降
在大多数文章中,都以“一个人被困在山上,需要迅速下到谷底”来举例,这个人会“寻找当前所处位置最陡峭的地方向下走”。这个例子中忽略了安全因素,这个人不可能沿着最陡峭的方向走,要考虑坡度。
在自然界中,梯度下降的最好例子,就是泉水下山的过程:
- 水受重力影响,会在当前位置,沿着最陡峭的方向流动,有时会形成瀑布(梯度下降);
- 水流下山的路径不是唯一的,在同一个地点,有可能有多个位置具有同样的陡峭程度,而造成了分流(可以得到多个解);
- 遇到坑洼地区,有可能形成湖泊,而终止下山过程(不能得到全局最优解,而是局部最优解)。
2.3.2 梯度下降的数学理解
梯度下降的数学公式:
θ n + 1 = θ n − η ⋅ ∇ J ( θ ) (1) \theta_{n+1} = \theta_{n} - \eta \cdot \nabla J(\theta) \tag{1} θn+1=θn−η⋅∇J(θ)(1)
其中:
- θ n + 1 \theta_{n+1} θn+1:下一个值;
- θ n \theta_n θn:当前值;
- − - −:减号,梯度的反向;
- η \eta η:学习率或步长,控制每一步走的距离,不要太快以免错过了最佳景点,不要太慢以免时间太长;
- ∇ \nabla ∇:梯度,函数当前位置的最快上升点;
- J ( θ ) J(\theta) J(θ):函数。
梯度下降的三要素
- 当前点;
- 方向;
- 步长。
为什么说是“梯度下降”?
“梯度下降”包含了两层含义:
- 梯度:函数当前位置的最快上升点;
- 下降:与导数相反的方向,用数学语言描述就是那个减号。
亦即与上升相反的方向运动,就是下降。
上图解释了在函数极值点的两侧做梯度下降的计算过程,梯度下降的目的就是使得x值向极值点逼近。
2.3.3 单变量函数的梯度下降
假设一个单变量函数:
J ( x ) = x 2 J(x) = x ^2 J(x)=x2
我们的目的是找到该函数的最小值,于是计算其微分:
J ′ ( x ) = 2 x J'(x) = 2x J′(x)=2x
假设初始位置为:
x 0 = 1.2 x_0=1.2 x0=1.2
假设学习率:
η = 0.3 \eta = 0.3 η=0.3
根据公式(1),迭代公式:
x n + 1 = x n − η ⋅ ∇ J ( x ) = x n − η ⋅ 2 x (1) x_{n+1} = x_{n} - \eta \cdot \nabla J(x)= x_{n} - \eta \cdot 2x\tag{1} xn+1=xn−η⋅∇J(x)=xn−η⋅2x(1)
假设终止条件为J(x)<1e-2,迭代过程是:
x=0.480000, y=0.230400
x=0.192000, y=0.036864
x=0.076800, y=0.005898
x=0.030720, y=0.000944
2.3.4 双变量的梯度下降
假设一个双变量函数:
J ( x , y ) = x 2 + sin 2 ( y ) J(x,y) = x^2 + \sin^2(y) J(x,y)=x2+sin2(y)
我们的目的是找到该函数的最小值,于是计算其微分:
∂
J
(
x
,
y
)
∂
x
=
2
x
{\partial{J(x,y)} \over \partial{x}} = 2x
∂x∂J(x,y)=2x
∂
J
(
x
,
y
)
∂
y
=
2
sin
y
cos
y
{\partial{J(x,y)} \over \partial{y}} = 2 \sin y \cos y
∂y∂J(x,y)=2sinycosy
假设初始位置为:
( x 0 , y 0 ) = ( 3 , 1 ) (x_0,y_0)=(3,1) (x0,y0)=(3,1)
假设学习率:
η = 0.1 \eta = 0.1 η=0.1
根据公式(1),迭代过程是的计算公式:
(
x
n
+
1
,
y
n
+
1
)
=
(
x
n
,
y
n
)
−
η
⋅
∇
J
(
x
,
y
)
(x_{n+1},y_{n+1}) = (x_n,y_n) - \eta \cdot \nabla J(x,y)
(xn+1,yn+1)=(xn,yn)−η⋅∇J(x,y)
=
(
x
n
,
y
n
)
−
η
⋅
(
2
x
,
2
⋅
sin
y
⋅
cos
y
)
(1)
= (x_n,y_n) - \eta \cdot (2x,2 \cdot \sin y \cdot \cos y) \tag{1}
=(xn,yn)−η⋅(2x,2⋅siny⋅cosy)(1)
根据公式(1),假设终止条件为 J ( x , y ) < 1 e − 2 J(x,y)<1e-2 J(x,y)<1e−2,迭代过程如表2-3所示。
表2-3 双变量梯度下降的迭代过程
迭代次数 | x | y | J(x,y) |
---|---|---|---|
1 | 3 | 1 | 9.708073 |
2 | 2.4 | 0.909070 | 6.382415 |
… | … | … | … |
15 | 0.105553 | 0.063481 | 0.015166 |
16 | 0.084442 | 0.050819 | 0.009711 |
迭代16次后,J(x,y)的值为0.009711,满足小于1e-2的条件,停止迭代。
上面的过程如表2-4所示,由于是双变量,所以需要用三维图来解释。
2.4 损失函数
2.4.1 概念
在各种材料中经常看到的中英文词汇有:误差,偏差,Error,Cost,Loss,损失,代价…意思都差不多,在本书中,使用“损失函数”和“Loss Function”这两个词汇,具体的损失函数符号用J来表示,误差值用loss表示。
“损失”就是所有样本的“误差”的总和,亦即(m为样本数):
损 失 = ∑ i = 1 m 误 差 i 损失 = \sum^m_{i=1}误差_i 损失=i=1∑m误差i
J = ∑ i = 1 m l o s s J = \sum_{i=1}^m loss J=i=1∑mloss
损失函数的作用
损失函数的作用,就是计算神经网络每次迭代的前向计算结果与真实值的差距,从而指导下一步的训练向正确的方向进行。
如何使用损失函数呢?具体步骤:
- 用随机值初始化前向计算公式的参数;
- 代入样本,计算输出的预测值;
- 用损失函数计算预测值和标签值(真实值)的误差;
- 根据损失函数的导数,沿梯度最小方向将误差回传,修正前向计算公式中的各个权重值;
- goto 2, 直到损失函数值达到一个满意的值就停止迭代。
2.4.2 机器学习常用损失函数
符号规则:a是预测值,y是样本标签值,J是损失函数值。
-
Gold Standard Loss,又称0-1误差
l o s s = { 0 a = y 1 a ≠ y loss=\begin{cases} 0 & a=y \\ 1 & a \ne y \end{cases} loss={01a=ya=y -
绝对值损失函数
l o s s = ∣ y − a ∣ loss = |y-a| loss=∣y−a∣
- Hinge Loss,铰链/折页损失函数或最大边界损失函数,主要用于SVM(支持向量机)中
l o s s = m a x ( 0 , 1 − y ⋅ a ) , y = ± 1 loss=max(0,1-y \cdot a), y=\pm 1 loss=max(0,1−y⋅a),y=±1
- Log Loss,对数损失函数,又叫交叉熵损失函数(cross entropy error)
l o s s = − 1 m ∑ i m y i l o g ( a i ) + ( 1 − y i ) l o g ( 1 − a i ) y i ∈ { 0 , 1 } loss = -\frac{1}{m} \sum_i^m y_i log(a_i) + (1-y_i)log(1-a_i) \qquad y_i \in \{0,1\} loss=−m1i∑myilog(ai)+(1−yi)log(1−ai)yi∈{0,1}
-
Squared Loss,均方差损失函数
l o s s = 1 2 m ∑ i m ( a i − y i ) 2 loss=\frac{1}{2m} \sum_i^m (a_i-y_i)^2 loss=2m1i∑m(ai−yi)2 -
Exponential Loss,指数损失函数
l o s s = 1 m ∑ i m e − ( y i ⋅ a i ) loss = \frac{1}{m}\sum_i^m e^{-(y_i \cdot a_i)} loss=m1i∑me−(yi⋅ai)
2.4.3 神经网络中常用的损失函数
-
均方差函数,主要用于回归
-
交叉熵函数,主要用于分类
二者都是非负函数,极值在底部,用梯度下降法可以求解。
(1)均方差函数
MSE - Mean Square Error
该函数就是最直观的一个损失函数了,计算预测值和真实值之间的欧式距离。预测值和真实值越接近,两者的均方差就越小。
均方差函数常用于线性回归(linear regression),即函数拟合(function fitting)。公式如下:
l o s s = 1 2 ( z − y ) 2 (单样本) loss = {1 \over 2}(z-y)^2 \tag{单样本} loss=21(z−y)2(单样本)
J = 1 2 m ∑ i = 1 m ( z i − y i ) 2 (多样本) J=\frac{1}{2m} \sum_{i=1}^m (z_i-y_i)^2 \tag{多样本} J=2m1i=1∑m(zi−yi)2(多样本)
(1.1)工作原理
要想得到预测值a与真实值y的差距,最朴素的想法就是用 E r r o r = a i − y i Error=a_i-y_i Error=ai−yi。
对于单个样本来说,这样做没问题,但是多个样本累计时, a i − y i a_i-y_i ai−yi有可能有正有负,误差求和时就会导致相互抵消,从而失去价值。所以有了绝对值差的想法,即 E r r o r = ∣ a i − y i ∣ Error=|a_i-y_i| Error=∣ai−yi∣。这看上去很简单,并且也很理想,那为什么还要引入均方差损失函数呢?两种损失函数的比较如表3-1所示。
表3-1 绝对值损失函数与均方差损失函数的比较
样本标签值 | 样本预测值 | 绝对值损失函数 | 均方差损失函数 |
---|---|---|---|
[ 1 , 1 , 1 ] [1,1,1] [1,1,1] | [ 1 , 2 , 3 ] [1,2,3] [1,2,3] | ( 1 − 1 ) + ( 2 − 1 ) + ( 3 − 1 ) = 3 (1-1)+(2-1)+(3-1)=3 (1−1)+(2−1)+(3−1)=3 | ( 1 − 1 ) 2 + ( 2 − 1 ) 2 + ( 3 − 1 ) 2 = 5 (1-1)^2+(2-1)^2+(3-1)^2=5 (1−1)2+(2−1)2+(3−1)2=5 |
[ 1 , 1 , 1 ] [1,1,1] [1,1,1] | [ 1 , 3 , 3 ] [1,3,3] [1,3,3] | ( 1 − 1 ) + ( 3 − 1 ) + ( 3 − 1 ) = 4 (1-1)+(3-1)+(3-1)=4 (1−1)+(3−1)+(3−1)=4 | ( 1 − 1 ) 2 + ( 3 − 1 ) 2 + ( 3 − 1 ) 2 = 8 (1-1)^2+(3-1)^2+(3-1)^2=8 (1−1)2+(3−1)2+(3−1)2=8 |
4 / 3 = 1.33 4/3=1.33 4/3=1.33 | 8 / 5 = 1.6 8/5=1.6 8/5=1.6 |
可以看到5比3已经大了很多,8比4大了一倍,而8比5也放大了某个样本的局部损失对全局带来的影响,用术语说,就是“对某些偏离大的样本比较敏感”,从而引起监督训练过程的足够重视,以便回传误差。
(2)交叉熵损失函数
交叉熵(Cross Entropy)是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息。在信息论中,交叉熵是表示两个概率分布 p , q p,q p,q 的差异,其中 p p p 表示真实分布, q q q 表示预测分布,那么 H ( p , q ) H(p,q) H(p,q)就称为交叉熵:
H ( p , q ) = ∑ i p i ⋅ ln 1 q i = − ∑ i p i ln q i (1) H(p,q)=\sum_i p_i \cdot \ln {1 \over q_i} = - \sum_i p_i \ln q_i \tag{1} H(p,q)=i∑pi⋅lnqi1=−i∑pilnqi(1)
交叉熵可在神经网络中作为损失函数, p p p 表示真实标记的分布, q q q 则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量 p p p 与 q q q 的相似性。
交叉熵函数常用于逻辑回归(logistic regression),也就是分类(classification)。
(2.1)交叉熵的由来
信息量
信息论中,信息量的表示方式:
I ( x j ) = − ln ( p ( x j ) ) (2) I(x_j) = -\ln (p(x_j)) \tag{2} I(xj)=−ln(p(xj))(2)
x j x_j xj:表示一个事件
p ( x j ) p(x_j) p(xj):表示 x j x_j xj发生的概率
I ( x j ) I(x_j) I(xj):信息量, x j x_j xj越不可能发生时,它一旦发生后的信息量就越大
假设对于学习神经网络原理课程,我们有三种可能的情况发生,如表3-2所示。
表3-2 三种事件的概论和信息量
事件编号 | 事件 | 概率 p p p | 信息量 I I I |
---|---|---|---|
x 1 x_1 x1 | 优秀 | p = 0.7 p=0.7 p=0.7 | I = − ln ( 0.7 ) = 0.36 I=-\ln(0.7)=0.36 I=−ln(0.7)=0.36 |
x 2 x_2 x2 | 及格 | p = 0.2 p=0.2 p=0.2 | I = − ln ( 0.2 ) = 1.61 I=-\ln(0.2)=1.61 I=−ln(0.2)=1.61 |
x 3 x_3 x3 | 不及格 | p = 0.1 p=0.1 p=0.1 | I = − ln ( 0.1 ) = 2.30 I=-\ln(0.1)=2.30 I=−ln(0.1)=2.30 |
WoW,某某同学不及格!好大的信息量!相比较来说,“优秀”事件的信息量反而小了很多。
熵
H ( p ) = − ∑ j n p ( x j ) ln ( p ( x j ) ) (3) H(p) = - \sum_j^n p(x_j) \ln (p(x_j)) \tag{3} H(p)=−j∑np(xj)ln(p(xj))(3)
则上面的问题的熵是:
H ( p ) = − [ p ( x 1 ) ln p ( x 1 ) + p ( x 2 ) ln p ( x 2 ) + p ( x 3 ) ln p ( x 3 ) ] = 0.7 × 0.36 + 0.2 × 1.61 + 0.1 × 2.30 = 0.804 \begin{aligned} H(p)&=-[p(x_1) \ln p(x_1) + p(x_2) \ln p(x_2) + p(x_3) \ln p(x_3)] \\ &=0.7 \times 0.36 + 0.2 \times 1.61 + 0.1 \times 2.30 \\ &=0.804 \end{aligned} H(p)=−[p(x1)lnp(x1)+p(x2)lnp(x2)+p(x3)lnp(x3)]=0.7×0.36+0.2×1.61+0.1×2.30=0.804
相对熵(KL散度)
相对熵又称KL散度,如果我们对于同一个随机变量 x x x 有两个单独的概率分布 P ( x ) P(x) P(x) 和 Q ( x ) Q(x) Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异,这个相当于信息论范畴的均方差。
KL散度的计算公式:
D K L ( p ∣ ∣ q ) = ∑ j = 1 n p ( x j ) ln p ( x j ) q ( x j ) (4) D_{KL}(p||q)=\sum_{j=1}^n p(x_j) \ln{p(x_j) \over q(x_j)} \tag{4} DKL(p∣∣q)=j=1∑np(xj)lnq(xj)p(xj)(4)
n n n 为事件的所有可能性。 D D D 的值越小,表示 q q q 分布和 p p p 分布越接近。
交叉熵
把上述公式变形:
D K L ( p ∣ ∣ q ) = ∑ j = 1 n p ( x j ) ln p ( x j ) − ∑ j = 1 n p ( x j ) ln q ( x j ) = − H ( p ( x ) ) + H ( p , q ) (5) \begin{aligned} D_{KL}(p||q)&=\sum_{j=1}^n p(x_j) \ln{p(x_j)} - \sum_{j=1}^n p(x_j) \ln q(x_j) \\ &=- H(p(x)) + H(p,q) \end{aligned} \tag{5} DKL(p∣∣q)=j=1∑np(xj)lnp(xj)−j=1∑np(xj)lnq(xj)=−H(p(x))+H(p,q)(5)
等式的前一部分恰巧就是p的熵,等式的后一部分,就是交叉熵:
H ( p , q ) = − ∑ j = 1 n p ( x j ) ln q ( x j ) (6) H(p,q) =- \sum_{j=1}^n p(x_j) \ln q(x_j) \tag{6} H(p,q)=−j=1∑np(xj)lnq(xj)(6)
在机器学习中,我们需要评估label和predicts之间的差距,使用KL散度刚刚好,即 D K L ( y ∣ ∣ a ) D_{KL}(y||a) DKL(y∣∣a),由于KL散度中的前一部分 H ( y ) H(y) H(y)不变,故在优化过程中,只需要关注交叉熵就可以了。所以一般在机器学习中直接用交叉熵做损失函数来评估模型。
l o s s = − ∑ j = 1 n y j ln a j (7) loss =- \sum_{j=1}^n y_j \ln a_j \tag{7} loss=−j=1∑nyjlnaj(7)
其中, n n n 并不是样本个数,而是分类个数。所以,对于批量样本的交叉熵计算公式是:
J = − ∑ i = 1 m ∑ j = 1 n y i j ln a i j (8) J =- \sum_{i=1}^m \sum_{j=1}^n y_{ij} \ln a_{ij} \tag{8} J=−i=1∑mj=1∑nyijlnaij(8)
m m m 是样本数, n n n 是分类数。
有一类特殊问题,就是事件只有两种情况发生的可能,比如“学会了”和“没学会”,称为 0 / 1 0/1 0/1分布或二分类。对于这类问题,由于 n = 2 n=2 n=2,所以交叉熵可以简化为:
l o s s = − [ y ln a + ( 1 − y ) ln ( 1 − a ) ] (9) loss =-[y \ln a + (1-y) \ln (1-a)] \tag{9} loss=−[ylna+(1−y)ln(1−a)](9)
二分类对于批量样本的交叉熵计算公式是:
J = − ∑ i = 1 m [ y i ln a i + ( 1 − y i ) ln ( 1 − a i ) ] (10) J= - \sum_{i=1}^m [y_i \ln a_i + (1-y_i) \ln (1-a_i)] \tag{10} J=−i=1∑m[yilnai+(1−yi)ln(1−ai)](10)