from fastai.vision.all import *MixUp 和朋友
可将 MixUp(及变体)数据增强应用于训练的回调函数
reduce_loss
reduce_loss (loss:torch.Tensor, reduction:str='mean')
根据 reduction 减少损失
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| loss | Tensor | ||
| reduction | str | mean | PyTorch 损失减少方式 |
| 返回值 | Tensor |
MixHandler
MixHandler (alpha:float=0.5)
用于实现 MixUp 风格调度的处理类
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| alpha | float | 0.5 | 确定 Beta 分布在范围 (0.,inf] 内 |
大多数 Mix 变体将在批次上执行数据增强,因此要实现你的 Mix,你应该根据你的训练方案调整 before_batch 事件。如果需要不同的损失函数,你也应该调整 lf。alpha 被传递给 Beta 以创建一个采样器。
MixUp
MixUp (alpha:float=0.4)
实现 https://arxiv.org/abs/1710.09412
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| alpha | float | 0.4 | 确定 Beta 分布在范围 (0.,inf] 内 |
这是 MixUp 的一个修改实现,它总是至少混合原始图像的 50%。原始论文要求使用 Beta 分布,该分布在损失函数中的每个位置都传递相同的 alpha 值(alpha = beta = #)。与原始论文不同的是,此 MixUp 实现选择 lambda 的最大值,这意味着如果采样到的 lambda 值小于 0.5(即原始图像表示率小于 50%),则使用 1-lambda 代替。
两张图像的混合程度由 alpha 决定。
\(alpha=1.\):
- 所有介于 0 和 1 之间的值都有相等的采样机会。
- 两张图像之间可以进行任何程度的混合
\(alpha<1.\):
- 接近 0 和 1 的值比接近 0.5 的值更有可能被采样。
- 更有可能选择其中一张图像,并加入少量另一张图像。
\(alpha>1.\):
- 接近 0.5 的值比接近 0 或 1 的值更有可能被采样。
- 更有可能将图像均匀混合。
首先,我们将看一个非常简洁的例子,展示如何使用 PETS 数据集生成数据
path = untar_data(URLs.PETS)
pat = r'([^/]+)_\d+.*$'
fnames = get_image_files(path/'images')
item_tfms = [Resize(256, method='crop')]
batch_tfms = [*aug_transforms(size=224), Normalize.from_stats(*imagenet_stats)]
dls = ImageDataLoaders.from_name_re(path, fnames, pat, bs=64, item_tfms=item_tfms,
batch_tfms=batch_tfms)我们可以通过在 fit 期间,在 before_batch 事件中获取数据来检查我们的 Callback 的结果,如下所示:
mixup = MixUp(1.)
with Learner(dls, nn.Linear(3,4), loss_func=CrossEntropyLossFlat(), cbs=mixup) as learn:
learn.epoch,learn.training = 0,True
learn.dl = dls.train
b = dls.one_batch()
learn._split(b)
learn('before_train')
learn('before_batch')
_,axs = plt.subplots(3,3, figsize=(9,9))
dls.show_batch(b=(mixup.x,mixup.y), ctxs=axs.flatten())| 轮次 | 训练损失 | 验证损失 | 时间 |
|---|---|---|---|
| 0 | 00:00 |

我们可以看到,图像会时不时地与另一张图像“混合”。
如何训练?你可以直接将 Callback 传递给 Learner,或者在你的 fit 函数中传递给 cbs。
learn = vision_learner(dls, resnet18, loss_func=CrossEntropyLossFlat(), metrics=[error_rate])
learn.fit_one_cycle(1, cbs=mixup)| 轮次 | 训练损失 | 验证损失 | 错误率 | 时间 |
|---|---|---|---|---|
| 0 | 2.041960 | 0.495492 | 0.162382 | 00:12 |
CutMix
CutMix (alpha:float=1.0)
实现 https://arxiv.org/abs/1905.04899
| 类型 | 默认值 | 详情 | |
|---|---|---|---|
| alpha | float | 1.0 | 确定 Beta 分布在范围 (0.,inf] 内 |
类似于 MixUp,CutMix 会从两张图像中随机剪切一个区域并互相交换。我们可以看看下面的一些例子。
cutmix = CutMix(1.)
with Learner(dls, nn.Linear(3,4), loss_func=CrossEntropyLossFlat(), cbs=cutmix) as learn:
learn.epoch,learn.training = 0,True
learn.dl = dls.train
b = dls.one_batch()
learn._split(b)
learn('before_train')
learn('before_batch')
_,axs = plt.subplots(3,3, figsize=(9,9))
dls.show_batch(b=(cutmix.x,cutmix.y), ctxs=axs.flatten())| 轮次 | 训练损失 | 验证损失 | 时间 |
|---|---|---|---|
| 0 | 00:00 |

我们也以完全相同的方式进行训练。
learn = vision_learner(dls, resnet18, loss_func=CrossEntropyLossFlat(), metrics=[accuracy, error_rate])
learn.fit_one_cycle(1, cbs=cutmix)| 轮次 | 训练损失 | 验证损失 | 准确率 | 错误率 | 时间 |
|---|---|---|---|---|---|
| 0 | 3.440883 | 0.793059 | 0.769959 | 0.230041 | 00:12 |