交叉熵
在深度学习领域出现交叉熵(cross entropy)的地方就是交叉熵损失函数了。通过交叉熵来衡量目标与预测值之间的差距。了解交叉熵还需要从信息论中的几个概念说起。
信息量
如何衡量一条信息包含的信息量?加入我们有以下的两个事件:
事件1:年底昆明要下雪
事件2:年底哈尔滨要下雪
凭直觉来说,事件1的信息量比事件2的信息量大,因为昆明一年四季如春,下雪的几率非常小。所以当越不可能的事件发生了,我们获取到的信息量就越大。越可能发生的事件发生了,我们获取到的信息量就越小,这也是香浓信息论中的一部分。信息量的定义就与事件发生的概率有关。
将其数学化。概率的取值范围是 [ 0 , 1 ] [0, 1] [0,1],并且满足值越大信息量越小的走势,信息量的取值范围是 ( 0 , + ∞ ) (0, +\infty) (0,+∞),假设事件 x x x发生的概率为 p ( x ) p(x) p(x),在数学上我们选取负对数来表示一个事件的信息量,如下:
I ( x ) = − log ( p ( x ) ) I(x) = - \log (p(x)) I(x)=−log(p(x))
我们再看看在定义域内,这个函数的走势,如下图:
熵
在自然生活中,我们所描述的事件并不是只有两种状态,例如掷骰子,结果会有6种可能,那么如何衡量掷一次骰子的期望信息量呢?这个所有期望的信息量就是熵。
现在将一般问题抽象化,也就是对于某事件,事件状态有 n n n种可能,每一种可能性都有一定概率 p ( x i ) p(x_i) p(xi)。那么就可以根据这些概率数据计算各可能性的信息量了,例如:
序号 | 事件 | 概率p | 信息量I |
---|---|---|---|
A | 电脑正常开机 | 0.7 | -log(p(A))=0.36 |
B | 电脑无法开机 | 0.2 | -log(p(B))=1.61 |
C | 电脑爆炸了 | 0.1 | -log(p©)=2.30 |
注:上面的计算使用的是自然对数
熵的公式如下:
H ( X ) = − ∑ i = 1 n p ( x i ) l o g ( p ( x i ) ) H(X) = - \sum_{i=1}^{n}p(x_i)log(p(x_i)) H(X)=−i=1∑np(xi)log(p(xi))
那么这个"开电脑"的熵就是:
H ( X ) = 0.7 × 0.36 + 0.2 × 1.61 + 0.1 × 2.3 = 0.804 H(X) = 0.7\times 0.36 + 0.2\times 1.61 + 0.1 \times 2.3=0.804 H(X)=0.7×0.36+0.2×1.61+0.1×2.3=0.804
注:可能是一件事,但是不同描述就会有不同的熵,例如:开电脑我们通常就是两种情况,就是能开机和不能开机,当你描述开电脑有第三种情况时,那么这个事件就变了。
生活中还有一类比较特殊的问题如抛硬币,结果只有两种可能,正面和反面。正面、反面的结果在数学上就满足0-1(二项)分布。对于这种0-1分布的问题,熵的计算就可以简化,有如下公式:
H ( X ) = − p ( x ) log p ( x ) − ( 1 − p ( x ) ) log ( 1 − p ( x ) ) H(X) = -p(x)\log p(x) - (1- p(x))\log (1- p(x)) H(X)=−p(x)logp(x)−(1−p(x))log(1−p(x))
相对熵(KL散度)
相对熵又称KL散度,如果我们对于同一个随机变量 x 有两个单独的概率分布 P(x) 和 Q(x),我们可以使用 KL 散度(Kullback-Leibler (KL) divergence)来衡量这两个分布的差异。
在机器学习中,P往往用来表示样本的真实分布,比如[1,0,0]表示当前样本属于第一类。Q用来表示模型所预测的分布,比如[0.7,0.2,0.1]
直观的理解就是如果用P来描述样本,那么就非常完美。而用Q来描述样本,虽然可以大致描述,但是不是那么的完美,信息量不足,需要额外的一些“信息增量”才能达到和P一样完美的描述。如果我们的Q通过反复训练,也能完美的描述样本,那么就不再需要额外的“信息增量”,Q等价于P。
KL散度的计算公式:
D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ( p ( x i ) q ( x i ) ) D_{KL}(p||q) = \sum_{i=1}^np(x_i)\log \left(\frac{p(x_i)}{q(x_i)}\right) DKL(p∣∣q)=i=1∑np(xi)log(q(xi)p(xi))
n为事件的所有可能性。 D K L D_{KL} DKL的值越小,表示q分布和p分布越接近。
交叉熵
将KL散度进行化简有
D K L ( p ∣ ∣ q ) = ∑ i = 1 n p ( x i ) log ( p ( x i ) q ( x i ) ) = ∑ i = 1 n p ( x i ) log ( p ( x i ) ) − ∑ i = 1 n p ( x i ) log ( q ( x i ) ) = − H ( p ( x ) ) + [ − ∑ i = 1 n p ( x i ) log ( q ( x i ) ) ] \begin{aligned} D_{KL}(p||q) &= \sum_{i=1}^np(x_i)\log \left(\frac{p(x_i)}{q(x_i)}\right)\\ &= \sum_{i=1}^n p(x_i)\log\left( p(x_i) \right) - \sum_{i=1}^n p(x_i)\log \left(q(x_i) \right)\\ &= -H(p(x)) + [- \sum_{i=1}^np(x_i)\log(q(x_i))] \end{aligned} DKL(p∣∣q)=i=1∑np(xi)log(q(xi)p(xi))=i=1∑np(xi)log(p(xi))−i=1∑np(xi)log(q(xi))=−H(p(x))+[−i=1∑np(xi)log(q(xi))]
等式的第一部分就是p的熵,第二部分就是交叉熵,也称为信息增益:
H ( p , q ) = − ∑ i = 1 n p ( x i ) log ( q ( x i ) ) H(p, q)=-\sum_{i=1}^n p(x_i)\log(q(x_i)) H(p,q)=−i=1∑np(xi)log(q(xi))
在机器学习中,我们需要评估label和predict之间的差距,使用KL散度刚刚好,即: D K L ( y ∣ ∣ y ^ ) D_{KL}(y||\hat{y}) DKL(y∣∣y^),由于KL散度中的前一部分 − H ( y ) -H(y) −H(y)不变,在优化的过程中只需要关注交叉熵就行了。所以一般在机器学习中可以直接使用交叉熵做损失函数,评估模型。
交叉熵损失函数
为什么要用交叉熵做loss函数?
在线性回归中,常常使用MSE(Mean Squared Error)作为loss函数,如下:
l o s s = 1 2 m ∑ i = 1 m ( y i − y i ^ ) 2 loss = \frac{1}{2m}\sum_{i=1}^m(y_i -\hat{y_i})^2 loss=2m1i=1∑m(yi−yi^)2
其中 m m m表示样本量。
在单标签分类任务中,通常使用的就是交叉熵损失函数。所谓单标签分类就是一个样本就属于一个类别。损失函数定义如下:
l o s s = ∑ i = 1 n y i log ( y i ^ ) loss = \sum_{i=1}^ny_i \log (\hat{y_i}) loss=i=1∑nyilog(yi^)
假如有如下预测结果:
* | 猫 | 青蛙 | 老鼠 |
---|---|---|---|
Label | 0 | 1 | 0 |
Pred | 0.3 | 0.6 | 0.1 |
那么该条样本计算的损失值如下:
l o s s = − ( 0 × log ( 0.3 ) + 1 × log ( 0.6 ) + 0 × log ( 0.1 ) ) = − log ( 0.6 ) loss = - (0 \times \log(0.3) + 1\times \log(0.6) + 0\times \log(0.1)) = - \log (0.6) loss=−(0×log(0.3)+1×log(0.6)+0×log(0.1))=−log(0.6)
对应一个batch数据loss值就是:
l o s s = − 1 m ∑ j = 1 m ∑ i = 1 n y j i log ( y j i ^ ) loss = - \frac{1}{m}\sum_{j=1}^{m}\sum_{i=1}^{n} y_{ji} \log\left(\hat{y_{ji}}\right) loss=−m1j=1∑mi=1∑nyjilog(yji^)
其中m为batch的批次数量。
当然实际任务中不仅有单标签的数据,还有多标签数据。假如有如下预测结果数据:
* | 猫 | 青蛙 | 老鼠 |
---|---|---|---|
Label | 0 | 1 | 1 |
Pred | 0.1 | 0.7 | 0.8 |
注:这里你会发现pred的和不是1,这里对每个预测结果进行了sigmoid处理,而不是使用softmax,那么每个类别的打分输出结果就被归一化到(0,1)之间了。这里也就认为各个标签都是独立分布的,相互之间没有影响。这时,交叉熵在这里是单独对每一个类别进行计算,每个类别就只有两种可能,算作一种二项分布了。那么对于一条样本就可以得到以下结果:
l o s s c a t = − 0 × log ( 0.1 ) − ( 1 − 0 ) × log ( 1 − 0.1 ) = − log ( 0.9 ) l o s s f r o g = − 1 × log ( 0.7 ) − ( 1 − 1 ) × log ( 1 − 0.7 ) = − log ( 0.7 ) l o s s m o u s e = − 1 × log ( 0.8 ) − ( 1 − 1 ) × log ( 1 − 0.8 ) = − log ( 0.8 ) l o s s = l o s s c a t + l o s s f r o g + l o s s m o u s e \begin{array}{c} loss_{cat} = -0\times \log(0.1) - (1-0)\times\log(1-0.1) = - \log(0.9)\\ loss_{frog} = -1\times \log(0.7) - (1-1)\times \log(1-0.7) = - \log(0.7)\\ loss_{mouse} = -1\times \log(0.8) - (1-1)\times \log(1-0.8) = - \log(0.8)\\ loss = loss_{cat} + loss_{frog} + loss_{mouse} \end{array} losscat=−0×log(0.1)−(1−0)×log(1−0.1)=−log(0.9)lossfrog=−1×log(0.7)−(1−1)×log(1−0.7)=−log(0.7)lossmouse=−1×log(0.8)−(1−1)×log(1−0.8)=−log(0.8)loss=losscat+lossfrog+lossmouse
同理对于一个batch数据的loss则有:
loss = 1 m ∑ j = 1 m ∑ i = 1 n − y j i log ( y j i ^ ) − ( 1 − y j i ) log ( 1 − y j i ^ ) \operatorname{loss}=\frac{1}{m}\sum_{j=1}^{m} \sum_{i=1}^{n}-y_{j i} \log \left(\hat{y_{j i}}\right)-\left(1-y_{j i}\right) \log \left(1-\hat{y_{j i}}\right) loss=m1j=1∑mi=1∑n−yjilog(yji^)−(1−yji)log(1−yji^)
其中m为一个batch中样本数目。