正则化技巧:标签平滑(Label Smoothing)以及在 PyTorch 中的实现
过拟合和概率校准是训练深度学习模型时出现的两个问题。深度学习中有很多正则化技术可以解决过拟合问题;权重衰减、早停机制和dropout是都是最常见的方式。Platt缩放和保序回归可以用于模型校准。
但是有没有一种方法可以同时对抗过度拟合和过度自信呢?
标签平滑是一种正则化技术,它扰动目标变量,使模型对其预测的确定性降低。它被视为一种正则化技术,因为它限制了softmax 函数的最大概率使最大概率不会比其他标签大得多(过度自信)。
在本文中,我们将解释标签平滑的原理,实现了一个使用这种技术的交叉熵损失函数,并评估了它的性能。
标签平滑
我们有一个多类分类问题。在此类问题中,目标变量通常是一个one-hot向量,其中正确类别的位置为1,其他位置为0。这是与二元分类不同的任务因为在二分类中只有两个可能的类,但是在多标签分类中,一个数据点中可以有多个正确的类。因此,多标签分类问题的需要检测图像中存在的每个对象。
标签平滑将目标向量改变少量 ε。因此,我们不是要求我们的模型为正确的类别预测 1,而是要求它为正确的类别预测 1-ε,并将所有其他类别预测为 ε。
带有标签平滑的交叉熵损失函数转化为下面的公式。
在这个公式中,ce(x) 表示 x 的标准交叉熵损失(例如 -log(p(x))),ε 是一个小的正数,i 是正确的类,N 是类的数量。
直观地说,标签平滑将正确类的概率值限制为更接近其他类的概率值。通过这种方式,它被用作正则化技术和对抗模型过度自信的方法。
PyTorch 实现
在 PyTorch 中实现标签平滑交叉熵损失函数非常简单。在这个例子中,我们使用 fast.ai 课程的一部分代码。
首先,让我们使用一个辅助函数来计算两个值之间的线性组合:
def linear_combination(x, y, epsilon):
return epsilon*x + (1-epsilon)*y
接下来,我们使用 PyTorch nn.Module实现一个新的损失函数
import torch.nn.functional as F
def reduce_loss(loss, reduction='mean'):
return loss.mean() if reduction=='mean' else loss.sum() if reduction=='sum' else loss
class LabelSmoothingCrossEntropy(nn.Module):
def __init__(self, epsilon:float=0.1, reduction='mean'):
super().__init__()
self.epsilon = epsilon
self.reduction = reduction
def forward(self, preds, target):
n = preds.size()[-1]
log_preds = F.log_softmax(preds, dim=-1)
loss = reduce_loss(-log_preds.sum(dim=-1), self.reduction)
nll = F.nll_loss(log_preds, target, reduction=self.reduction)
return linear_combination(loss/n, nll, self.epsilon)
我们现在可以在我们的代码中使用这个类。对于这个例子,我们使用标准的 fast.ai pets 例子。
from fastai.vision import *
from fastai.metrics import error_rate
# prepare the data
path = untar_data(URLs.PETS)
path_img = path/'images'
fnames = get_image_files(path_img)
bs = 64
np.random.seed(2)
pat = r'/([^/]+)_d+.jpg$'
data = ImageDataBunch.from_name_re(path_img, fnames, pat, ds_tfms=get_transforms(), size=224, bs=bs)
.normalize(imagenet_stats)
# train the model
learn = cnn_learner(data, models.resnet34, metrics=error_rate)
learn.loss_func = LabelSmoothingCrossEntropy()
learn.fit_one_cycle(4)
我们将数据转换为可供模型使用的格式,并使用 ResNet ,我们自定义的类作为损失。经过四轮训练后,结果总结如下。
我们得到了只有 7.5% 的错误率,这对于十行左右的代码来说是可以接受的,因为我们使用的都是默认设置。
我们可以调整很多东西来使我们的模型表现得更好。不同的优化器、超参数、模型架构等。
总结
在这篇文章中,我们研究了标签平滑,这是一种试图对抗过度拟合和过度自信的技术。我们看到了何时使用它以及如何在 PyTorch 中实现它。然后,我们训练了一个计算机视觉模型,用十行代码识别不同品种的猫和狗。
模型正则化和校准是两个重要的概念。更好地理解这些概念可以帮你成为一个更好的深度学习实践者。
作者:Dimitris Poulopoulos
相关文章
- 在 Go 里用 CGO?这 7 个问题你要关注!
- 9款优秀的去中心化通讯软件 Matrix 的客户端
- 求职数据分析,项目经验该怎么写
- 在OKR中,我看到了数据驱动业务的未来
- 火山引擎云原生大数据在金融行业的实践
- OpenHarmony富设备移植指南(二)—从postmarketOS获取移植资源
- 《数据成熟度指数》报告:64%的企业领袖认为大多数员工“不懂数据”
- OpenHarmony 小型系统兼容性测试指南
- 肯睿中国(Cloudera):2023年企业数字战略三大趋势预测
- 适用于 Linux 的十大命令行游戏
- GNOME 截图工具的新旧截图方式
- System76 即将推出的 COSMIC 桌面正在酝酿大变化
- 2GB 内存 8GB 存储即可流畅运行,Windows 11 极致精简版系统 Tiny11 发布
- 迎接 ecode:一个即将推出的具有全新图形用户界面框架的现代、轻量级代码编辑器
- loongarch架构介绍(三)—地址翻译
- Go 语言怎么解决编译器错误“err is shadowed during return”?
- 敏捷:可能被开发人员遗忘的部分
- Denodo预测2023年数据管理和分析的未来
- 利用数据推动可持续发展
- 在 Vue3 中实现 React 原生 Hooks(useState、useEffect),深入理解 React Hooks 的