标签平滑 label smoothing

简介

label smoothing其实是机器学习和深度学习上比较常用的一个小 trick。

这里简单做一些记录。

什么是label smoothing

什么是标签平滑呢?

这里举一个例子:

面对一个多分类问题

假设我们的当前对于xi的ground truth 是[0, 0, 0, 1]
说明对于xi来说他属于第四类,但是一般来说我们输出的会是经过softmax激活的一个概率向量,也就是可能为:

[0.013, 0.001, 0.264, 0.721]

不可能输出一个非0即1的向量,这样的概率向量就会是用来计算loss的。

那么什么是label smoothing呢,就是我们将得到的target向量进行多一步的处理:

Element-wise:
targets = targets * (1.0 - smoothing) + 0.5 * smoothing

smoothing 是平滑系数,在0,1之间

这就是label smoothing。

label smoothing作用

很显然,当我们增加label smoothing的时候,loss就会增加。
但是为什么还要使用这样的处理呢。

因为这样能带来几方面的好处:

  1. 防止过拟合,防止了出现非0即1的情况出现
  2. 提高模型的泛性
  3. 提高鲁棒性,当然这我倒是并没有亲身体验,如果有对抗方向的朋友应该就会比较有感触了。

torch实现label smoothing

这里我写代码用到了label smoothing,这是一个分类问题,用的是BCELoss,然后增加了label smoothing。

这里提供一个label smoothing在torch框架下的实现模板:

from torch.nn.modules.loss import _WeightedLoss
## 继承_WeightedLoss类
class SmoothingBCELossWithLogits(_WeightedLoss):
	def __init__(self, weight=None, reduction='mean', smoothing=0.0):
		super(SmoothingBCELossWithLogits, self).__init__(weight=weight, reduction=reduction)
		self.smoothing = smoothing
		self.weight  = weight
		self.reduction = reduction
	@staticmethod
	def _smooth(targets, n_labels, smoothing=0.0):
		assert 0 <= smoothing < 1
		with torch.no_grad():
			targets = targets  * (1 - smoothing) + 0.5 * smoothing
		return targets
	def forward(self, inputs, targets):
		targets = _smooth(targets, inputs.size(-1), self.smoothing)
		loss = F.binary_cross_entropy_with_logits(inputs, targets, self.weights)
		
		if self.reduction == 'sum':
			loss = loss.item()
		elif self.reduction == 'mean':
			loss = loss.mean()
		return loss
		

如果有什么错误,还请大家指正。

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,首先我们需要了解一下朴素贝叶斯分类器的原理。朴素贝叶斯分类器是一种基于贝叶斯定理和特征条件独立假设的分类方法,其核心思想是通过已知的样本数据来计算出不同特征值下样本属于不同类别的概率,然后根据概率大小来判断待分类样本属于哪个类别。 对于平滑系数的调整,我们可以使用拉普拉斯平滑(Laplace smoothing)来实现。具体来说,就是在计算概率时,在分子和分母都加上一个常数k,这样可以避免出现某个特征值在训练集中没有出现过的情况,从而使得概率计算更加准确。 接下来,我们可以使用交叉验证的方法来评估分类器的性能,具体步骤如下: 1. 将数据集划分为K份,其中K-1份作为训练集,剩下的1份作为测试集。 2. 对训练集进行训练,得到朴素贝叶斯分类器。 3. 对测试集进行分类,计算分类的正确率。 4. 重复步骤2-3,直到所有的测试集都被用过一次,计算平均正确率。 5. 尝试不同的平滑系数k,重复步骤2-4,绘制平均正确率与平滑系数的关系曲线。 下面是Python实现代码,以文本分类为例: ```python import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.model_selection import KFold from sklearn.metrics import accuracy_score # 加载数据集 def load_data(): # 加载数据集 # ... return X, y # 交叉验证评估分类器性能 def evaluate_classifier(X, y, k): kf = KFold(n_splits=k, shuffle=True, random_state=42) scores = [] for train_index, test_index in kf.split(X): X_train, X_test = X[train_index], X[test_index] y_train, y_test = y[train_index], y[test_index] clf = MultinomialNB(alpha=k) clf.fit(X_train, y_train) y_pred = clf.predict(X_test) score = accuracy_score(y_test, y_pred) scores.append(score) return np.mean(scores) # 调整平滑系数 def adjust_alpha(X, y, k_range): scores = [] for k in k_range: score = evaluate_classifier(X, y, k) scores.append(score) return scores if __name__ == '__main__': X, y = load_data() k_range = [0.01, 0.1, 1, 10, 100] scores = adjust_alpha(X, y, k_range) print(scores) ``` 这段代码中,我们首先定义了一个load_data函数,用来加载数据集。然后是evaluate_classifier函数,用来进行交叉验证评估分类器性能。最后是adjust_alpha函数,用来调整平滑系数,返回平均正确率列表。我们可以尝试不同的平滑系数范围,比如[0.001, 0.01, 0.1, 1, 10, 100]等,来绘制平均正确率与平滑系数的关系曲线。 绘制曲线可以使用matplotlib库,代码如下: ```python import matplotlib.pyplot as plt plt.plot(k_range, scores) plt.xlabel('alpha') plt.ylabel('accuracy') plt.xscale('log') plt.show() ``` 这段代码中,我们使用plt.plot函数来绘制曲线,plt.xlabel和plt.ylabel函数用来设置x轴和y轴的标签,plt.xscale函数用来设置x轴的刻度,使得平滑系数的取值范围更加合理。最后使用plt.show函数显示曲线。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值