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
数据集生成数据
= untar_data(URLs.PETS)
path = r'([^/]+)_\d+.*$'
pat = get_image_files(path/'images')
fnames = [Resize(256, method='crop')]
item_tfms = [*aug_transforms(size=224), Normalize.from_stats(*imagenet_stats)]
batch_tfms = ImageDataLoaders.from_name_re(path, fnames, pat, bs=64, item_tfms=item_tfms,
dls =batch_tfms) batch_tfms
我们可以通过在 fit
期间,在 before_batch
事件中获取数据来检查我们的 Callback
的结果,如下所示:
= MixUp(1.)
mixup with Learner(dls, nn.Linear(3,4), loss_func=CrossEntropyLossFlat(), cbs=mixup) as learn:
= 0,True
learn.epoch,learn.training = dls.train
learn.dl = dls.one_batch()
b
learn._split(b)'before_train')
learn('before_batch')
learn(
= plt.subplots(3,3, figsize=(9,9))
_,axs =(mixup.x,mixup.y), ctxs=axs.flatten()) dls.show_batch(b
轮次 | 训练损失 | 验证损失 | 时间 |
---|---|---|---|
0 | 00:00 |
我们可以看到,图像会时不时地与另一张图像“混合”。
如何训练?你可以直接将 Callback
传递给 Learner
,或者在你的 fit 函数中传递给 cbs
。
= vision_learner(dls, resnet18, loss_func=CrossEntropyLossFlat(), metrics=[error_rate])
learn 1, cbs=mixup) learn.fit_one_cycle(
轮次 | 训练损失 | 验证损失 | 错误率 | 时间 |
---|---|---|---|---|
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(1.)
cutmix with Learner(dls, nn.Linear(3,4), loss_func=CrossEntropyLossFlat(), cbs=cutmix) as learn:
= 0,True
learn.epoch,learn.training = dls.train
learn.dl = dls.one_batch()
b
learn._split(b)'before_train')
learn('before_batch')
learn(
= plt.subplots(3,3, figsize=(9,9))
_,axs =(cutmix.x,cutmix.y), ctxs=axs.flatten()) dls.show_batch(b
轮次 | 训练损失 | 验证损失 | 时间 |
---|---|---|---|
0 | 00:00 |
我们也以完全相同的方式进行训练。
= vision_learner(dls, resnet18, loss_func=CrossEntropyLossFlat(), metrics=[accuracy, error_rate])
learn 1, cbs=cutmix) learn.fit_one_cycle(
轮次 | 训练损失 | 验证损失 | 准确率 | 错误率 | 时间 |
---|---|---|---|---|---|
0 | 3.440883 | 0.793059 | 0.769959 | 0.230041 | 00:12 |