Lable Smoothing
是分类问题中错误标注的一种解决方法。
对于分类问题,特别是多分类问题,常常把向量转换成one-hot-vector(独热向量)
one-hot带来的问题:(对于独热的简单解释:https://blog.csdn.net/qq_43211132/article/details/96141409)
对于损失函数,我们需要用预测概率去拟合真实概率,而拟合one-hot的真实概率函数会带来两个问题:
1)无法保证模型的泛化能力,容易造成过拟合;
2) 全概率和0概率鼓励所属类别和其他类别之间的差距尽可能加大,而由梯度有界可知,这种情况很难适应。会造成模型过于相信预测的类别。
使用下面的 label smoothing 可以缓解这个问题:
原理:对于以Dirac函数分布的真实标签,我们将它变成分为两部分获得(替换)。
第一部分:将原本Dirac分布的标签变量替换为(1 - ϵ)的Dirac函数;
第二部分:以概率 ϵ ,在u(k) 中份分布的随机变量(u(k)是类别分之一)
代码:
def label_smoothing(inputs, epsilon=0.1):
K = inputs.get_shape().as_list()[-1] # number of channels
return ((1-epsilon) * inputs) + (epsilon / K)
交叉熵(Cross-Entropy)损失函数是分类模型中的一种非常重要的目标函数。在二分类问题中,交叉熵损失函数的形式如下:
如果分类准确,交叉熵损失函数的结果是0(即上式中p和y一致的情况),否则交叉熵为无穷大。也就是说交叉熵对分类正确给的是最大激励。换句话说,对于标注数据来说,这个时候我们认为其标注结果是准确的(不然这个结果就没意义了)。但实际上,有一些标注数据并不一定是准确的。那么这时候,使用交叉熵损失函数作为目标函数并不一定是最优的。
对于这个问题,我们还可以这么去理解。在分类任务中,我们通常对类别标签的编码使用[0,1,2,…]这种形式。在深度学习中,通常在全连接层的最后一层,加入一个softmax来计算输入数据属于每个类别的概率,并把概率最高的作为这个类别的输入,然后使用交叉熵作为损失函数。这会导致模型对正确分类的情况奖励最大,错误分类惩罚最大。如果训练数据能覆盖所有情况,或者是完全正确,那么这种方式没有问题。但事实上,这不可能。所以这种方式可能会带来泛化能力差的问题,即过拟合。
在2016年,Szegedy等人提出了inception v2的模型(论文:Rethinking the inception architecture for computer vision.)。其中提到了Label Smoothing技术,用以减轻这个问题。
我们先来看一下原理。假设我们的分类只有两个,一个是猫一个不是猫,分别用1和0表示。Label Smoothing的工作原理是对原来的[0 1]这种标注做一个改动,假设我们给定Label Smoothing的值为0.1:
可以看到,原来的[0,1]编码变成了[0.05,0.95]了。这个label_smoothing的值假设为ϵ,那么就是说,原来分类准确的时候,p=1,不准确为p=0,现在变成了p=1−ϵ和ϵ,也就是说对分类准确做了一点惩罚。
Label Smoothing在很多问题上对模型都有一定的提升。
在Tensorflow中使用方法时候只要在损失函数中加上label_smoothing的值即可,如下:
tf.losses.softmax_cross_entropy(
onehot_labels,
logits,
weights=1.0,
label_smoothing=0,
scope=None,
loss_collection=tf.GraphKeys.LOSSES,
reduction=Reduction.SUM_BY_NONZERO_WEIGHTS
)
参考:
【1】https://blog.csdn.net/neveer/article/details/91646657
【2】https://www.datalearner.com/blog/1051561454844661
————————————————
版权声明:本文为CSDN博主「奔跑的小仙女」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_43211132/article/details/100510113
标签平滑的想法首先被提出用于训练 Inception-v2 [26]。它将真实概率的构造改成:
其中ε是一个小常数,K 是标签总数量。
图 4:ImageNet 上标签平滑效果的可视化。顶部:当增加ε时,目标类别与其它类别之间的理论差距减小。下图:最大预测与其它类别平均值之间差距的经验分布。很明显,通过标签平滑,分布中心处于理论值并具有较少的极端值。
# -*- coding: utf-8 -*-
"""
qi=1-smoothing(if i=y)
qi=smoothing / (self.size - 1) (otherwise)#所以默认可以fill这个数,只在i=y的地方执行1-smoothing
另外KLDivLoss和crossentroy的不同是前者有一个常数
predict = torch.FloatTensor([[0, 0.2, 0.7, 0.1, 0],
[0, 0.9, 0.2, 0.1, 0],
[1, 0.2, 0.7, 0.1, 0]])
对应的label为
tensor([[ 0.0250, 0.0250, 0.9000, 0.0250, 0.0250],
[ 0.9000, 0.0250, 0.0250, 0.0250, 0.0250],
[ 0.0250, 0.0250, 0.0250, 0.9000, 0.0250]])
区别于one-hot的
tensor([[ 0., 0., 1., 0., 0.],
[ 1., 0., 0., 0., 0.],
[ 0., 1., 0., 0., 0.]])
"""
import torch
import torch.nn as nn
from torch.autograd import Variable
import matplotlib.pyplot as plt
import numpy as np
class LabelSmoothing(nn.Module):
"Implement label smoothing. size表示类别总数 "
def __init__(self, size, smoothing=0.0):
super(LabelSmoothing, self).__init__()
self.criterion = nn.KLDivLoss(size_average=False)
#self.padding_idx = padding_idx
self.confidence = 1.0 - smoothing#if i=y的公式
self.smoothing = smoothing
self.size = size
self.true_dist = None
def forward(self, x, target):
"""
x表示输入 (N,M)N个样本,M表示总类数,每一个类的概率log P
target表示label(M,)
"""
assert x.size(1) == self.size
true_dist = x.data.clone()#先深复制过来
#print true_dist
true_dist.fill_(self.smoothing / (self.size - 1))#otherwise的公式
#print true_dist
#变成one-hot编码,1表示按列填充,
#target.data.unsqueeze(1)表示索引,confidence表示填充的数字
true_dist.scatter_(1, target.data.unsqueeze(1), self.confidence)
self.true_dist = true_dist
return self.criterion(x, Variable(true_dist, requires_grad=False))
if __name__=="__main__":
# Example of label smoothing.
crit = LabelSmoothing(size=5,smoothing= 0.1)
#predict.shape 3 5
predict = torch.FloatTensor([[0, 0.2, 0.7, 0.1, 0],
[0, 0.9, 0.2, 0.1, 0],
[1, 0.2, 0.7, 0.1, 0]])
v = crit(Variable(predict.log()),
Variable(torch.LongTensor([2, 1, 0])))
# Show the target distributions expected by the system.
plt.imshow(crit.true_dist)
调用的时候注意
module的init函数里面,fc后面要加上LogSoftmax函数,因为KLV要求输入log概率
self.Logsoftmax=nn.LogSoftmax()
forward函数里
x = self.fc(x)
x=self.Logsoftmax(x)
————————————————
版权声明:本文为CSDN博主「Snoopy_Dream」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/e01528/article/details/85019274
来源:oschina
链接:https://my.oschina.net/u/4358563/blog/4296871