本站原创文章,转载请说明来自《老饼讲解-深度学习》www.bbbdata.com
标签平滑(LabelSmoothing)交叉熵损失函数是交叉熵损失函数的一种正则化改进,它出自inception-V3模型的原文
本文讲解标签平滑-交叉熵的计算公式,并解读公式中每一项的意义及设计意图,以及展示LabelSmoothing的代码实现
通过本文,可以快速了解什么标签平滑(LabelSmoothing)交叉熵损失函数,以及如何使用代码实现标签平滑交叉熵损失函数
本节讲解标签平滑交叉熵损失函数的公式与意义
什么是标签平滑-交叉熵损失函数
标签平滑(LabelSmoothing)交叉熵损失函数是交叉熵损失函数的一种正则化改进,有利于增强模型的泛化能力
标签平滑-交叉熵损失函数出自inception-V3模型的原文《Rethinking the Inception Architecture for Computer Vision》
它在交叉熵损失函数的基础上,降低对样本标签的信任程度,属于交叉熵损失函数的一种正则化改进
标签平滑交叉熵损失函数的计算公式如下:
其中
:样本个数
:类别个数
:第i个样本的真实类别
:第i个样本属于第k个类别的预测概率
:平滑系数,一般设为0.1
标签平滑交叉熵损失函数-公式解读
交叉熵损失函数与标签平滑交叉熵-公式对比
交叉熵损失函数与标签平滑交叉熵的公式分别如下:
交叉熵损失函数公式为:
标签平滑交叉熵公式为:
可以看到,平滑形式只是将改为了
标签平滑交叉熵损失函数的解读
我们知道,是知道第i个样本是k类时,所带来的信息量(震惊程度)
如果样本的采样标签并不准确,我们不信任采样标签,那么样本可能是任意一个类别
则采样标签不准确时,在知道样本真实类别时,所带来的信息量期望为
标签平滑将“相信采样标签”与"不相信采样标签"两种情况进行加权,作为第i个样本的信息量
即,标签平滑交叉熵就是在交叉熵的基础上,考虑了采样不准确,不信任采样标签的情况
标签平滑交叉熵损失函数的意义
标签平滑考虑了采样不准确的场景,降低样本标签的“自信”,从而模型增强模型的泛化能力
因此标签平滑相当于交叉熵损失函数的一种正则化形式,其中是正则项
本节展示标签平滑交叉熵损失函数的具体代码实现
标签平滑交叉熵损失函数-代码实现
在pytorch中实现"标签平滑交叉熵损失函数"与"普通交叉熵损失函数"是一样的
都是使用torch.nn.CrossEntropyLoss,只是当使用标签平滑时,需要指定label_smoothing参数
同时,下面的代码加入了自写代码实现标签平滑交叉熵损失函数,以便更具体了解CrossEntropyLoss的逻辑
具体示例如下:
import torch
# 本代码用于展示如何在pytorch中实现平滑标签交叉熵损失函数
# 本代码来自《老饼讲解-深度学习》www.bbbdata.com
# ----生成数据-----
py = torch.tensor([[0.5,0.1,0.1],[1.7,0.2,0.1],[0.9,2.7,0.1],[1.1,0.3,2.6]]) # 类别的预测值
y = torch.tensor([0,0,1,2],dtype=torch.int64) # 真实类别
alpha = 0.1 # 设置alpha值
# ----pytorch函数实现的平滑标签损失函数-----
loss = torch.nn.CrossEntropyLoss(label_smoothing=alpha)(py,y) # 调用pytorch函数计算平滑标签损失值
print('\n平滑标签交叉熵损失值(调用函数)',loss.item()) # 打印结果
# ----自实现的平滑标签损失函数-----
def labelSmoothing(py,y,alpha): # 自实现的平滑标签损失函数
sample_num,class_num = py.shape # 样本个数与类别个数
py = torch.nn.Softmax(dim=1)(py) # 对输入进行softmax
loss = 0 # 初始化损失值
for i in range(class_num): # 累计每一类别的损失值
true_loss = -torch.log(py[y==i,i]).sum()/sample_num # 计算信任标签的损失值
all_loss = -torch.log(py[y==i,:]).sum()/class_num/sample_num # 计算不信任标签的损失值
loss = loss+((1-alpha)*true_loss+alpha*all_loss) # 添加本次平滑损失值
return loss
loss2 = labelSmoothing(py,y,alpha) # 调用自写函数计算平滑标签损失值
print('平滑标签交叉熵损失值(自写函数)',loss2.item()) # 打印结果
代码运行结果如下:
从结果可以看到,调用pytorch的CrossEntropyLoss函数的结果与自写代码是一致的
在学习平滑标签交叉熵损失函数时,可以通过"自实现"部分来加深理解
而在实际使用中,则可以直接使用pytorch的CrossEntropyLoss函数来实现
好了,标签平滑交叉熵损失函数就介绍到这里
.
End