什么是损失函数
对于损失函数网上已经有充分的解释:“机器学习中所有的算法都需要最大化或最小化一个函数,这个函数被称为目标函数。其中,我们一般把最小化的一类函数,称为损失函数。它能根据预测结果,衡量出模型预测能力的好坏。 ”
总而言之,损失函数用来衡量当前模型的糟糕程度,它的值越大,模型就越糟糕,反之,它的值越小,模型就越好。我们训练模型的最终目标就是要最小化损失函数。
可用作损失函数的函数有很多,但一般用均方误差和交叉熵误差。
均方误差与交叉熵
均方误差
均方误差(mean-square error, MSE)是反映估计量与被估计量之间差异程度的一种度量。其公式如下
M
S
E
=
1
n
∑
k
=
1
N
(
t
k
−
y
k
)
2
MSE=\frac1n\sum_{k=1}^N{(t_k-y_k)}^2
MSE=n1k=1∑N(tk−yk)2
其中
t
k
t_k
tk表示真实值,
y
k
y_k
yk表示预测值
交叉熵
交叉熵(Cross Entropy)是信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息。 设概率分布
A
(
x
)
A(x)
A(x)和
B
(
x
)
B(x)
B(x)为随机变量的两个概率分布,他们的交叉熵公式如下
H
(
A
,
B
)
=
−
∑
i
A
(
x
i
)
log
B
(
x
i
)
H(A,B)=-\sum_iA(x_i)\log B(x_i)
H(A,B)=−i∑A(xi)logB(xi)
为什么要使用交叉熵
(这里需要逻辑回归基础!)
在监督学习中主要有两类问题,一类是回归问题,而另一类是分类问题,交叉熵通常用于分类问题。
为什么在分类问题上要使用交叉熵,损失函数 - 交叉熵损失函数一文中给出了非常简单明了的例子(推荐阅览),以下是我个人的理解(可能有逻辑不严谨的地方,请务必仅仅作为参考,有错误不吝指出)。
- Classification Error(分类错误率)
分类错误率的公式如下
classification error = count of error items count of all items \text{classification error} = \frac{\text{count of error items}}{\text{count of all items}} classification error=count of all itemscount of error items
这个公式很直观,分类错误的样本数比上总共的样本数,这确实在一定程度上反应了模型预测能力的好坏。可是它有点过于简单了,对于Classification Error来说,模型输出的结果是“非黑即白”的。
以二分类为例,共有0、1两个类别。假设我们的模型为逻辑回归模型,现有两个模型A和B,对于一个类别为1的样本,模型A以90%的概率判断样本类别为1,而模型B以60%的概率判断样本类别为1。模型A明显比模型B要好,但是Classification Error无法分辨出这一点,只要模型判断对了,它就认为模型是好的,哪怕是瞎猜的结果。
因此,直接使用 Classification Error 作为损失函数可能不是一个好主意,但是可以基于 Classification Error 进行改进,使用所有样本的分类错误的概率之和替代分类错误的样本数。
这是什么意思呢?以二分类为例,共有0、1两个类别。设总样本数为 n n n, y k y_k yk为第 k k k个样本的分类结果, t k t_k tk为第 k k k个样本的真实类别。则经过上述改进的损失函数可以表示为:
E = 1 n ∑ k = 1 N t k ( 1 − y k ) + ( 1 − t k ) y k E=\frac1n\sum_{k=1}^N{t_k(1-y_k)+(1-t_k)y_k} E=n1k=1∑Ntk(1−yk)+(1−tk)yk
这个公式很好理解,当真实值等于0时 ( t k = 0 ) (t_k=0) (tk=0), y k y_k yk越接近0越好,它的值本身可以视为分类错误的概率;同理,当真实值等于1时 ( t k = 1 ) (t_k=1) (tk=1), y k y_k yk越接近1越好, 1 − y k 1-y_k 1−yk的值可以视为分类错误的概率。所以上式就是所有样本的分类错误的概率之和比上样本数的结果。
然后下面将 E 展开并进一步化简:
E = 1 n ∑ k = 1 N ( t k − y k ) 2 E=\frac1n\sum_{k=1}^N{(t_k-y_k)}^2 E=n1k=1∑N(tk−yk)2
这个式子看起来很眼熟?这不就是均方误差吗。下面对均方误差进行讨论。 - 均方误差(mean-square error, MSE)
前面介绍过,均方误差的公式如下:
M S E = 1 n ∑ k = 1 N ( t k − y k ) 2 MSE=\frac1n\sum_{k=1}^N{(t_k-y_k)}^2 MSE=n1k=1∑N(tk−yk)2
如何考量均方误差对于分类问题的效果呢?不妨从参数更新的角度入手,在深度学习中,通常使用梯度下降法对损失函数进行最优化,在最优化的过程中需要使用损失函数的梯度来更新参数。下面求均方误差的梯度(参照李弘毅老师的机器学习课程)。
以二分类为例,共有0、1两个类别。假设我们的模型为逻辑回归模型,参数为 ω \omega ω,求 ( t k − y k ) 2 {(t_k-y_k)}^2 (tk−yk)2 的梯度,结果如下
∂ ( y k − t k ) 2 ∂ ω = 2 ( y k − t k ) y k ( 1 − y k ) x \frac{\partial{(y_k-t_k)}^2}{\partial\omega}=2(y_k-t_k)y_k(1-y_k)x ∂ω∂(yk−tk)2=2(yk−tk)yk(1−yk)x
对上式进行分析,如果真实值等于0 ( t k = 0 ) (t_k=0) (tk=0):
当 y k = 0 y_k=0 yk=0时,则模型的表现非常好,此时 ∂ ( y k − t k ) 2 ∂ ω = 0 \frac{\partial{(y_k-t_k)}^2}{\partial\omega}=0 ∂ω∂(yk−tk)2=0;
当 y k = 1 y_k=1 yk=1时,则模型的表现非常糟糕,此时仍然有 ∂ ( y k − t k ) 2 ∂ ω = 0 \frac{\partial{(y_k-t_k)}^2}{\partial\omega}=0 ∂ω∂(yk−tk)2=0;
容易发现,如果真实值等于0 ( t k = 1 ) (t_k=1) (tk=1)时有类似的结果。
这不是一个好的现象,当我们的初始模型的表现非常糟糕时(通常都是这样),它的梯度将趋于0,这使得它无法有效地更新参数,从而久久不能收敛。
因此,直接使用均方误差作为损失函数也不是一个好主意 - 交叉熵(Cross Entropy)
前面两种方法都不适合解决分类问题,这下只剩下交叉熵了,交叉熵的工作原理上节介绍过,不再赘述,直接给出其公式
H ( A , B ) = − ∑ i A ( x i ) log B ( x i ) H(A,B)=-\sum_iA(x_i)\log B(x_i) H(A,B)=−i∑A(xi)logB(xi)
依然从参数更新的角度入手,求交叉熵的梯度。以二分类为例,共有0、1两个类别。假设我们的模型为逻辑回归模型,参数为 ω \omega ω, y k y_k yk为第 k k k个样本的分类结果, t k t_k tk为第 k k k个样本的真实类别,则交叉熵公式表示如下
H ( y , t ) = − ∑ k [ t k log y k + ( 1 − t k ) l o g ( 1 − y k ) ] H(y,t)=-\sum_k[t_k\log y_k+(1-t_k)log(1-y_k)] H(y,t)=−k∑[tklogyk+(1−tk)log(1−yk)]
求上式的梯度,结果如下
∂ H ( y , t ) ∂ ω = − ∑ [ k t k ( 1 − y k ) − ( 1 − t k ) y k ] x ∂ H ( y , t ) ∂ ω = − ∑ [ k t k − y k ] x \frac{\partial H(y,t)}{\partial\omega}=-\underset k{\sum\lbrack}t_k(1-y_k)-(1-t_k)y_k\rbrack x\\ \frac{\partial H(y,t)}{\partial\omega}=-\underset k{\sum\lbrack}t_k-y_k\rbrack x ∂ω∂H(y,t)=−k∑[tk(1−yk)−(1−tk)yk]x∂ω∂H(y,t)=−k∑[tk−yk]x
容易发现, t k t_k tk与 y k y_k yk相差越大,交叉熵的梯度就越大,即使初始模型的表现非常糟糕时,也能够使用梯度下降有效地更新参数。
下面引用李宏毅老师机器学习课程中的一张图来说明交叉熵和均方误差的区别:
由图可见,均方误差在距离最优点较远的地方变化比较平缓,这阻碍了梯度下降的工作,而交叉熵在距离最优点较远的地方变化十分陡峭,这有利于加速梯度下降的收敛。
综上所述,在分类问题上,相对于Classification Error和均方误差,使用交叉熵无疑是更好的选择。
交叉熵与KL散度之间的关系
一句话,最小化模型分布和目标分布的交叉熵等价于最小化模型分布和目标分布的KL散度。
在进行公式推导之前,首先要明晰三个概念:熵、K散度和交叉熵。
- 熵
熵用来衡量一个系统的混乱程度,它的值越大,表明这个系统的不确定性就越大。记 A ( x ) A(x) A(x) 为某一概率分布,则它的熵公式如下:
H ( A ) = − ∑ i A ( x i ) log A ( x i ) ① H(A)=-\sum_iA(x_i)\log A(x_i)\;\;\;① H(A)=−i∑A(xi)logA(xi)① - KL散度
KL散度可以描述两个概率分布 A ( x ) A(x) A(x) 和 B ( x ) B(x) B(x) 的相似度,记为 D ( A ∣ ∣ B ) D(A\vert\vert B) D(A∣∣B),对于离散变量,KL散度有如下定义:
D ( A ∣ ∣ B ) = ∑ i A ( x i ) log A ( x i ) B ( x i ) ② D(A\vert\vert B)=\sum_iA(x_i)\log\frac{A(x_i)}{B(x_i)}\;\;\;② D(A∣∣B)=i∑A(xi)logB(xi)A(xi)② - 交叉熵
这里再重复介绍一下交叉熵。
熵用来衡量单一概率分布的不确定性,而交叉熵主要用来度量两个分布间的差异性信息。记 A ( x ) A(x) A(x)和 B ( x ) B(x) B(x) 为随机变量X的两个概率分布,则 A A A与 B B B的交叉熵公式如下:
H ( A , B ) = − ∑ i A ( x i ) log B ( x i ) ③ H(A,B)=-\sum_iA(x_i)\log B(x_i)\;\;\;③ H(A,B)=−i∑A(xi)logB(xi)③
明晰上述三个概念后,我们很容易发现在上面三个式子中,有③ = ①+②,用公式表示就是:
H
(
A
,
B
)
=
D
(
A
∣
∣
B
)
+
H
(
A
)
H(A,B)=D(A\vert\vert B)+H(A)
H(A,B)=D(A∣∣B)+H(A)
在一个机器学习任务中,假设
A
(
x
)
A(x)
A(x)代表训练集的分布,
B
(
x
)
B(x)
B(x)代表当前模型的分布,可知
H
(
A
)
H(A)
H(A)为一个常量(这里训练集是事先给好且固定不变的,所以它的混乱程度也是固定不变的),我们发现交叉熵和KL散度之间仅差一个常量,此时最小化KL散度当然等价于最小化交叉熵。