深度学习基础之-1.5交叉熵损失函数

交叉熵

交叉熵(Cross Entropy)是Shannon信息论中一个重要概念,主要用于度量两个概率分布间的差异性信息。在信息论中,交叉熵是表示两个概率分布p,q的差异,其中p表示真实分布,q表示非真实分布,那么H(p,q)就称为交叉熵:
H ( p , q ) = ∑ i p i ⋅ l o g 1 q i = − ∑ i p i log ⁡ q i H(p,q)=\sum_i p_i \cdot log {1 \over q_i} = - \sum_i p_i \log q_i H(p,q)=ipilogqi1=ipilogqi
交叉熵可在神经网络中作为损失函数,p表示真实标记的分布,q则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量p与q的相似性。
交叉熵函数常用于逻辑回归(logistic regression),也就是分类(classification)。

交叉熵的由来

信息量

信息论中,信息量的表示方式:
I ( x j ) = − log ⁡ ( p ( x j ) ) I(x_j) = -\log (p(x_j)) I(xj)=log(p(xj))

x j x_j xj:表示一个事件

p ( x j ) p(x_j) p(xj):表示 x i x_i xi发生的概率

I ( x j ) I(x_j) I(xj):信息量, x j x_j xj不可能发生时,它一旦发生后的信息量就越大

假设对于学习神经网络原理课程,我们有三种可能的情况发生:

序号 事件 概率 p 信息量 I
A 完全学会 p=0.7 I = − l o g ( 0.7 ) = 0.36 I=-log(0.7)=0.36 I=log(0.7)=0.36
B 一知半解 p=0.2 I = − l o g ( 0.2 ) = 1.61 I=-log(0.2)=1.61 I=log(0.2)=1.61
C 半途而废 p=0.1 I = − l o g ( 0.1 ) = 2.30 I=-log(0.1)=2.30 I=log(0.1)=2.30

WoW,某某同学退学了!好大的信息量!相比较来说,“完全学会了课程”事件的信息量反而小了很多

H ( p ) = − ∑ j n p ( x j ) log ⁡ ( p ( x j ) ) H(p) = - \sum_j^n p(x_j) \log (p(x_j)) H(p)=jnp(xj)log(p(xj))

则上面的问题的熵是:

H ( p ) = − [ p ( A ) log ⁡ p ( A ) + p ( B ) log ⁡ p ( B ) + p ( C ) log ⁡ p ( C ) ] H(p) = -[p(A) \log p(A) + p(B) \log p(B) + p(C) \log p(C)] H(p)=[p(A)logp(A)+p(B)logp(B)+p(C)logp(C)] = 0.7 × 0.36 + 0.2 × 1.61 + 0.1 × 2.30 =0.7 \times 0.36 + 0.2 \times 1.61 + 0.1 \times 2.30 =0.7×0.36+0.2×1.61+0.1×2.30 = 0.804 =0.804 =0.804

相对熵(KL散度)

相对熵又称KL散度,如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异,这个相当于信息论范畴的均方差。

KL散度的计算公式:

D K L ( p ∣ ∣ q ) = ∑ j = 1 n p ( x j ) log ⁡ p ( x j ) q ( x j ) D_{KL}(p||q)=\sum_{j=1}^n p(x_j) \log{p(x_j) \over q(x_j)} DKL(pq)=j=1np(xj)logq(xj)p(xj)

n为事件的所有可能性。 D的值越小,表示q分布和p分布越接近

交叉熵

把上述公式变形:

D K L ( p ∣ ∣ q ) = ∑ j = 1 n p ( x j ) log ⁡ p ( x j ) − ∑ j = 1 n p ( x j ) log ⁡ q ( x j ) D_{KL}(p||q)=\sum_{j=1}^n p(x_j) \log{p(x_j)} - \sum_{j=1}^n p(x_j) \log q(x_j) DKL(pq)=j=1np(xj)logp(xj)j=1np(xj)logq(xj) = H ( p ( x ) ) − ∑ j = 1 n p ( x j ) log ⁡ q ( x j ) =H(p(x)) - \sum_{j=1}^n p(x_j) \log q(x_j) =H(p(x))j=1np(xj)logq(xj)

等式的前一部分恰巧就是p的熵,等式的后一部分,就是交叉熵:

H ( p , q ) = − ∑ j = 1 n p ( x j ) log ⁡ q ( x j ) H(p,q) =- \sum_{j=1}^n p(x_j) \log q(x_j) H(p,q)=j=1np(xj)logq(xj)

在机器学习中,我们需要评估label和predicts之间的差距,使用KL散度刚刚好,即 D K L ( y ∣ ∣ a ) D_{KL}(y||a) DKL(ya),由于KL散度中的前一部分 H ( y ) H(y) H(y)不变,故在优化过程中,只需要关注交叉熵就可以了。所以一般在机器学习中直接用用交叉熵做loss,评估模型。

l o s s = − ∑ j = 1 n y j log ⁡ a j loss =- \sum_{j=1}^n y_j \log a_j loss=j=1nyjlogaj

其中,n并不是样本个数,而是分类个数。所以,对于批量样本的交叉熵计算公式是:

J = − ∑ i = 1 m ∑ j = 1 n y i j log ⁡ a i j J =- \sum_{i=1}^m \sum_{j=1}^n y_{ij} \log a_{ij} J=i=1mj=1nyijlogaij

m是样本数,n是分类数。

有一类特殊问题,就是事件只有两种情况发生的可能,比如“学会了”和“没学会”,称为0-1分布或二分类。对于这类问题,由于n=2,所以交叉熵可以简化为:

l o s s = − [ y log ⁡ a + ( 1 − y ) log ⁡ ( 1 − a ) ] loss =-[y \log a + (1-y) \log (1-a)] loss=[yloga+(1y)log(1a)]

二分类对于批量样本的交叉熵计算公式是:

J = − ∑ i = 1 m [ y i log ⁡ a i + ( 1 − y i ) log ⁡ ( 1 − a i ) ] J= - \sum_{i=1}^m [y_i \log a_i + (1-y_i) \log (1-a_i)] J=i=1m[yilogai+(1yi)log(1ai)]

交叉熵在二分类问题上的使用

当y=1时,即标签值是1,是个正例:

l o s s = − l o g ( a ) loss = -log(a) loss=log(a)

横坐标是预测输出,纵坐标是损失函数值。y=1意味着当前样本标签值是1,当预测输出越接近1时,Loss值越小,训练结果越准确。当预测输出越接近0时,Loss值越大,训练结果越糟糕。

当y=0时,即标签值是0,是个反例: l o s s = − log ⁡ ( 1 − a ) loss = -\log (1-a) loss=log(1a)

此时,损失值与预测值的关系是:

我们改变一下上面的例子,假设出勤率高的同学都学会了课程,我们想建立一个预测器,对于一个特定的学员,根据TA的出勤率来预测:

出勤率
学会了课程的真实值统计 1 0
根据学员的高出勤率的预测
预测1 0.6 0.4
预测2 0.7 0.3

那么这个预测与真实统计之间的交叉熵损失函数值是:

l o s s 1 = − ( 1 × log ⁡ 0.6 + ( 1 − 1 ) × log ⁡ ( 1 − 0.6 ) ) = 0.51 loss_1 = -(1 \times \log 0.6 + (1-1) \times \log (1-0.6)) = 0.51 loss1=(1×log0.6+(11)×log(10.6))=0.51

l o s s 2 = − ( 1 × log ⁡ 0.7 + ( 1 − 1 ) × log ⁡ ( 1 − 0.7 ) ) = 0.36 loss_2 = -(1 \times \log 0.7 + (1-1) \times \log (1-0.7)) = 0.36 loss2=(1×log0.7+(11)×log(10.7))=0.36

由于0.7是相对准确的值,所以loss2要比loss1小,反向传播的力度也会小。

交叉熵在多分类问题熵的使用

最后输出层使用Softmax激活函数,并且配合One-Hot编码使用。

等级 初级 中级
出勤率很低 1 0 0
出勤率中等 0 1 0
出勤率很高 0 0 1
对于一个出勤率很高的同学的预测
预测1 0.1 0.6 0.3
预测2 0.1 0.3 0.6

我们想建立一个预测器,预测一个出勤率很高的学员的学习等级,很显然,根据标签值,应该属于 [ 0 , 0 , 1 ] [0,0,1] [0,0,1]

假设开始时不太准确,一个学员的出勤率很高,但预测出的值为: [ 0.1 , 0.6 , 0.3 ] [0.1, 0.6, 0.3] [0.1,0.6,0.3],这样得到的交叉熵是:

l o s s 1 = − ( 0 × log ⁡ 0.1 + 0 × log ⁡ 0.6 + 1 × log ⁡ 0.3 ) = 1.2 loss_1 = -(0 \times \log 0.1 + 0 \times \log 0.6 + 1 \times \log 0.3) = 1.2 loss1=(0×log0.1+0×log0.6+1×log0.3)=1.2

如果预测出的值为: [ 0.1 , 0.3 , 0.6 ] [0.1, 0.3, 0.6] [0.1,0.3,0.6],标签为: [ 0 , 0 , 1 ] [0, 0, 1] [0,0,1],这样得到的交叉熵是:

l o s s 2 = − ( 0 × log ⁡ 0.1 + 0 × log ⁡ 0.3 + 1 × log ⁡ 0.6 ) = 0.51 loss_2 = -(0 \times \log 0.1 + 0 \times \log 0.3 + 1 \times \log 0.6) = 0.51 loss2=(0×log0.1+0×log0.3+1×log0.6)=0.51

可以看到,0.51比1.2的损失值小很多,这说明预测值越接近真实标签值(0.6 vs 0.3),交叉熵损失函数值越小,反向传播的力度越小。

为什么不能使用均方差做为分类问题的损失函数?

  • 回归问题通常用均方差损失函数,可以保证损失函数是个凸函数,即可以得到最优解。而分类问题如果用均方差的话,损失函数的表现不是凸函数,就很难得到最优解。而交叉熵函数可以保证区间内单调。
  • 分类问题的最后一层网络,需要分类函数,Sigmoid或者Softmax,如果再接均方差函数的话,其求导结果很复杂,运算量比较大。用交叉熵函数的话,可以得到比较简单的计算结果,利用程序性能。

https://github.com/microsoft/ai-edu/blob/master/B-教学案例与实践/B6-神经网络基本原理简明教程/03.2-交叉熵损失函数.md

你可能感兴趣的:(深度学习)