一个小例子搞懂transformer中的label smoothing(标签平滑)

我们知道transformer中的正则化除了使用常见的dropout,还使用了label smoothing,也就是标签平滑。
标签平滑其实就是将硬标签(hard label)转化为软标签(soft label),也就是将标签的one hot编码中的1转化为比1稍小的数,将0转化为比0稍大的数,这样在计算损失函数时(比如交叉熵损失函数),损失函数会把原来值为0的标签也考虑进来,其实就相当于在标签的one hot编码中的每一维上增加了噪声。本质上是向训练集中增加了信息,使得训练集的信息量增大了,更加接近真实分布的数据集的信息量,所以有利于缓解过拟合。
标签平滑的计算公式如下:
output = (1-ϵ)input+ϵ/K
其中ϵ为平滑系数,默认值是0.1,input为K类别组成的K维矩阵,K便是具体任务所分类的类别数(本例中由于使用的是逻辑回归,所以K=2),output为标签平滑时的K类别组成的K维矩阵。
逻辑回归正类和负类的标签分别设为1和0,也就是这里的input为[1,0],ϵ为0.05,那么output = (1-0.05)
[1,0]+0.05/2 = [0.975,0.025]。
可以看到,原来的[0,1]编码变成了[0.025,0.975]了。又由于交叉熵损失函数如下:
在这里插入图片描述
可以设p的阈值为0.5,也就是当p大于该值时样本被划分到正类(y=1),当p小于该值时,样本被划分到负类(y=0)。我们假设模型对某一样本预测为正类的概率为:
如果p=0.8,则传统方式损失为-1log(0.8)=0.097,使用标签平滑后,损失为:-[0.975log(0.8)+(1-0.975)log(1-0.8)] = 0.11
如果p=0.95,传统方式损失为-1
log(0.95) = 0.022,而如果使用标签平滑,损失为-[0.975log(0.95)+(1-0.975)log(1-0.95)] = 0.054。
如果p=0.999,对于传统方式,其损失为-1
log(0.999)=0.00043。做了标签平滑后其损失为:-[0.975
log(0.999)+(1-0.975)*log(1-0.999)] = 0.075。
可以看出,对于同一个样本(假设该样本属于正类),如果不使用标签平滑,则模型预测的概率越大,则对应的损失就越小,也就是模型倾向于把样本预测为某类别的概率尽可能的大。如果使用标签平滑,则随着模型预测的概率增大,损失先变小后又增大,也即模型倾向于将样本预测为某类的概率在一个较大的值但是不是尽可能的大。
这里我们可以看出来了,加入了标签平滑后,使得过拟合模型的损失变得较大,一定程度上阻止了模型过度学习的趋势。

  • 9
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
在CNN加入Transformer结构可以提高模型的语义理解和泛化能力。以下是一个简单的示例,将一个Transformer模块嵌入到CNN: ```python import torch import torch.nn as nn import torch.nn.functional as F class CNN_Transformer(nn.Module): def __init__(self): super(CNN_Transformer, self).__init__() # 卷积层 self.conv1 = nn.Conv2d(3, 64, kernel_size=3, padding=1) self.conv2 = nn.Conv2d(64, 128, kernel_size=3, padding=1) self.conv3 = nn.Conv2d(128, 256, kernel_size=3, padding=1) # Transformer层 self.transformer = nn.TransformerEncoderLayer(d_model=256, nhead=8) # 全连接层 self.fc1 = nn.Linear(256, 128) self.fc2 = nn.Linear(128, 10) def forward(self, x): # 卷积层 x = F.relu(self.conv1(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv2(x)) x = F.max_pool2d(x, 2) x = F.relu(self.conv3(x)) x = F.max_pool2d(x, 2) # Transformer层 x = x.permute(2, 3, 0, 1) # 调整维度 x = self.transformer(x) x = x.permute(2, 3, 0, 1) # 调整维度 # 全连接层 x = torch.mean(x, dim=[2, 3]) x = F.relu(self.fc1(x)) x = self.fc2(x) return x ``` 在这个示例,我们首先定义了一个基本的卷积神经网络结构,包括3个卷积层和2个全连接层。然后,我们在网络加入了一个Transformer层,并将其应用于卷积层的输出。具体来说,我们首先将卷积层的输出转置,使其符合Transformer的输入格式。然后,我们使用`nn.TransformerEncoderLayer`定义了一个Transformer模块,并将其应用于卷积层的输出。最后,我们将Transformer的输出再次转置,以符合后续全连接层的输入格式。 需要注意的是,由于Transformer模块对输入的维度有要求,因此需要对卷积层的输出进行相应的调整。此外,由于使用了Transformer模块,这个示例的CNN_Transformer模型可以自适应地处理不同长度的输入序列,从而具有更好的语义理解和泛化能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值