【机器学习】交叉熵损失函数(Cross-Entropy Loss)

在深度学习中,我们经常使用均方误差作为拟合任务的损失函数,使用交叉熵作为分类任务的损失函数。这篇文章主要介绍交叉熵损失函数以及它的几个变种。

目录

  • Softmax激活函数
  • 交叉熵损失函数
  • "目标VS非目标"的情况
  • 以上二者的区别

Softmax激活函数

在介绍交叉熵损失函数之前,我们先来看看Softmax激活函数,一般我们会在输出层后加一层Softmax激活函数,用于得到分类概率。注意,请不要将Softmax叫做损失函数,它是激活函数,目的是将输出归一化。假设原始神经网络输出为 y 1 , y 2 , y 3 , y 4 … y n y_{1},y_{2},y_{3},y_{4}…y_{n} y1,y2,y3,y4yn,那么经过Softmax激活函数后,输出为:
p i = s o f t m a x ( y i ) = e y i ∑ j = 1 n e y j p_{i}=softmax(y_{i})=\frac{e^{y_{i}}}{\sum_{j=1}^{n}e^{y_{j}}} pi=softmax(yi)=j=1neyjeyi
可见,Softmax激活函数的作用是将输出规范化到0~1之间,这样可以把 y 1 , y 2 , y 3 , y 4 … y n y_{1},y_{2},y_{3},y_{4}…y_{n} y1,y2,y3,y4yn变成概率分布 p 1 , p 2 , p 3 , p 4 … p n p_{1},p_{2},p_{3},p_{4}…p_{n} p1,p2,p3,p4pn,而且保证所有 p i p_{i} pi之和为1,这样我们就可以得到这张图片在每个类别上的概率。
那么对于这么离散的输出分布,我们应该如何设计一个损失函数进行反向传播优化呢,这时候就诞生了:交叉熵损失函数

交叉熵损失函数

我们假设神经网络最后一层的输出为y,经过softmax激活函数后输出为p,真实标签为t(one-hot编码),则交叉熵损失函数为:
L o s s = − ∑ i = 1 C ( t i ∗ l o g ( p i ) ) Loss=-\sum_{i=1}^{C}(t_{i}*log(p_{i})) Loss=i=1C(tilog(pi))
上式中的C表示一共有C个分类。对于一个属于第j类的物体来说,除了 t j = 1 t_{j}=1 tj=1之外,其他 t t t都为0(因为是one-hot编码)。假设一张图片属于第j类,那么损失函数将变为以下格式:
L o s s = − l o g ( p j ) Loss=-log(p_{j}) Loss=log(pj)
p j p_{j} pj接近0时,Loss接近正无穷,当 p j p_{j} pj接近1时,Loss接近0。使用梯度下降法,优化模型参数让Loss值下降,这时 p j p_{j} pj就越来越接近1,也就是我们期望得到的优化结果,这就是交叉熵损失函数。

"目标VS非目标"的情况

这种情况其实是目标检测中常用的,而且是对单目标进行地检测,比如“人头检测”。因为在这种情况下只有一个分类,所以我们只需要识别出某个区域是“目标”或者是“背景”的概率。那么损失函数可以这样设计:
L o s s = − l o g ( y ∗ p + ( 1 − y ) ∗ ( 1 − p ) ) Loss=-log(y*p+(1-y)*(1-p)) Loss=log(yp+(1y)(1p))

其中,真实标签为y(用0代表背景,用1代表存在目标),模型预测输出为p。
当真实标签 y = 0 y=0 y=0时,原式为: L o s s = − l o g ( 1 − p ) Loss=-log(1-p) Loss=log(1p),那么当p趋近0时,Loss趋近0;当p趋近1时,Loss趋近正无穷,使用反向传播优化参数,使得p趋近0(也就是这种情况下真实标签y的值)。
当真实标签 y = 1 y=1 y=1时,原式变为: L o s s = − l o g ( p ) Loss=-log(p) Loss=log(p),当p趋于0时,Loss趋于正无穷;当p趋于1时,Loss趋于1,使用反向传播优化参数,使得p趋近1(同样是这种情况下真实标签y的值)。

以上二者的区别

我们可以看到,交叉熵损失函数没有对标签为0的分类进行多余的计算,只计算了我们想要检测的那类物体对应的损失值;而第二种算法对标签为0的分类也计算了损失值,这样就可以通过反向传播优化标签为0的类别,也就是将背景的优化也考虑了进去。

结合两种算法的思想,我们可以对每一类对应的损失值都进行计算,然后取这些类别损失值的平均值作为最终的损失值:
L o s s = − ( 1 C ) ∗ ∑ i = 1 C l o g ( y i ∗ p i + ( 1 − y i ) ∗ ( 1 − p i ) ) Loss=-(\frac{1}{C})*\sum_{i=1}^{C}log(y_{i}*p_{i}+(1-y_{i})*(1-p_{i})) Loss=(C1)i=1Clog(yipi+(1yi)(1pi))
但是这样也有一个问题,就是当类别过多的时候,可能很难优化损失函数,也就是损失函数的值下不来。而且模型的注意力可能会被标签为0的类别吸引,而不会特别注意我们想要的那类,因为标签为0的类别贡献的损失值相加可能远大于标签为1的类别贡献的损失值,所以给不同类别分配一个权重可能会好一些,让标签为0的类别计算出的损失值权重小一些,让标签为1的类别计算出的损失值权重分配大一些。

你可能感兴趣的:(【机器学习】交叉熵损失函数(Cross-Entropy Loss))