Datawhale AI 夏令营 Task03 学习笔记
Datawhale AI 夏令营 Task03 学习笔记
part1 数据增强基础
数据增强(Data Augmentation)在机器学习和深度学习中的应用非常广泛,尤其是对图像和视频数据。在图像处理中,数据增强技术能够有效地提高模型的泛化能力,通过模拟各种可能的现实场景变化,使得模型在未见过的数据上也能表现良好。常见的图像数据增强技术包括但不限于:
- 旋转:对图像进行随机角度的旋转,可以帮助模型学习不同角度下的特征表示。
- 缩放:随机缩放图像的大小,保持物体的比例不变。
- 裁剪:随机裁剪图像的一部分,这有助于模型关注图像的不同部分。
- 翻转:包括水平翻转和垂直翻转,模拟物体在不同方向上的观察。
- 亮度调整:随机调整图像的亮度,以适应不同光照条件。
- 对比度调整:随机改变图像的对比度,使模型能够在不同对比度的情况下识别物体。
- 噪声添加:在图像中添加随机噪声,增强模型的鲁棒性。
然而,数据增强也需要注意适度和相关性。如果所使用的变换与目标任务的实际场景不符,可能会引入不必要的噪音,反而降低模型的性能。例如,对于一个不需要旋转的任务,如果过度使用旋转变换,可能会使模型难以学习到有效的特征。同样,过度的数据增强(如极端的亮度或对比度调整)可能会导致图像失真,使得模型难以训练。
以下是使用PyTorch框架进行图像数据加载和增强的示例代码:
train_loader = torch.utils.data.DataLoader(
FFDIDataset(train_label['path'].head(1000), train_label['target'].head(1000),
transforms.Compose([
transforms.Resize((256, 256)),
transforms.RandomHorizontalFlip(),
transforms.RandomVerticalFlip(),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
), batch_size=40, shuffle=True, num_workers=4, pin_memory=True
)
val_loader = torch.utils.data.DataLoader(
FFDIDataset(val_label['path'].head(1000), val_label['target'].head(1000),
transforms.Compose([
transforms.Resize((256, 256)),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
), batch_size=40, shuffle=False, num_workers=4, pin_memory=True
)
Part2 常见的数据增强模型
在数据增强中,有多种方法可以用来增强训练数据的多样性和丰富性。下面介绍几何变换、颜色变换和自动增强这三种常见的数据增强方法:
1. 几何变换
几何变换主要通过改变图像的空间结构来增加数据多样性。这些变换模拟了物体在不同视角和位置的表现。常见的几何变换包括:
- 旋转(Rotation):随机旋转图像一定角度。
- 平移(Translation):随机移动图像在水平或垂直方向上的位置。
- 缩放(Scaling):随机缩放图像的大小,可以是放大或缩小。
- 剪切(Shearing):对图像进行随机剪切变换,使图像的形状发生变化。
- 翻转(Flipping):包括水平翻转和垂直翻转。
这些几何变换可以通过PyTorch的torchvision.transforms模块来实现。例如:
import torchvision.transforms as transforms
geometric_transforms = transforms.Compose([
transforms.RandomRotation(30), # 随机旋转30度以内
transforms.RandomResizedCrop(224), # 随机裁剪并调整大小到224x224
transforms.RandomHorizontalFlip(), # 随机水平翻转
])
2. 颜色变换
颜色变换通过改变图像的颜色属性来增强数据的多样性。这些变换模拟了不同光照和色彩条件下的图像表现。常见的颜色变换包括:
- 亮度调整(Brightness):随机调整图像的亮度。
- 对比度调整(Contrast):随机调整图像的对比度。
- 饱和度调整(Saturation):随机调整图像的饱和度。
- 色调调整(Hue):随机调整图像的色调。
这些颜色变换也可以通过torchvision.transforms模块来实现。例如:
color_transforms = transforms.Compose([
transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.2) # 随机调整亮度、对比度、饱和度和色调
])
3. 自动增强(AutoAugment)
自动增强是一种更高级的数据增强方法,它自动选择和组合多种基本变换以生成新的训练样本。AutoAugment通过强化学习或搜索算法来找到最优的变换策略,从而提高模型的性能。
在PyTorch中,AutoAugment可以通过torchvision.transforms.AutoAugment来实现。例如:
from torchvision.transforms import AutoAugment, AutoAugmentPolicy
auto_augment = transforms.Compose([
AutoAugment(policy=AutoAugmentPolicy.IMAGENET) # 使用ImageNet的AutoAugment策略
])
综合使用
通常,几何变换、颜色变换和自动增强可以组合使用,以实现更强大的数据增强效果。一个综合的示例如下:
import torchvision.transforms as transforms
from torchvision.transforms import AutoAugment, AutoAugmentPolicy
comprehensive_transforms = transforms.Compose([
transforms.RandomRotation(30),
transforms.RandomResizedCrop(224),
transforms.RandomHorizontalFlip(),
transforms.ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.2),
AutoAugment(policy=AutoAugmentPolicy.IMAGENET),
transforms.ToTensor(),
transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
])
通过结合这些数据增强方法,我们可以显著提高模型的泛化能力和鲁棒性。
Part3 进阶数据增强模型
Mixup和Cutmix是两种在图像数据增强中的先进技术,旨在通过生成新的训练样本来增强模型的泛化能力。这两种方法通过混合图像及其对应的标签,使模型在处理更复杂的样本时具有更强的鲁棒性。下面详细讲解这两种技术:
Mixup
Mixup是一种在训练集中混合图像和标签的方法,通过线性插值生成新的训练样本。这种方法的核心思想是将两张图像及其标签按一定比例混合,从而生成新的训练数据。
具体实现步骤:
- 随机选择两张图像 (x_i) 和 (x_j),以及它们对应的标签 (y_i) 和 (y_j)。
- 生成一个介于0到1之间的随机数 (\lambda),通常服从Beta分布。
- 按照 (\lambda) 混合图像和标签,生成新的训练样本 (x_{\text{new}}) 和 (y_{\text{new}}):
[ x_{\text{new}} = \lambda x_i + (1 - \lambda) x_j ]
[ y_{\text{new}} = \lambda y_i + (1 - \lambda) y_j ]
PyTorch实现示例:
import torch
import numpy as np
def mixup_data(x, y, alpha=1.0):
if alpha > 0:
lambda_ = np.random.beta(alpha, alpha)
else:
lambda_ = 1
batch_size = x.size(0)
index = torch.randperm(batch_size)
mixed_x = lambda_ * x + (1 - lambda_) * x[index, :]
y_a, y_b = y, y[index]
return mixed_x, y_a, y_b, lambda_
def mixup_criterion(criterion, pred, y_a, y_b, lambda_):
return lambda_ * criterion(pred, y_a) + (1 - lambda_) * criterion(pred, y_b)
Cutmix
Cutmix与Mixup类似,但它通过在图像中剪切和粘贴部分区域来进行混合,而不是线性插值。这种方法通过将一张图像的一部分替换为另一张图像的一部分,同时调整标签,生成新的训练样本。
具体实现步骤:
- 随机选择两张图像 (x_i) 和 (x_j),以及它们对应的标签 (y_i) 和 (y_j)。
- 随机确定剪切区域的位置和大小。
- 将图像 (x_j) 的剪切区域替换到图像 (x_i) 的对应位置,生成新的图像 (x_{\text{new}})。
- 根据剪切区域的比例调整标签 (y_i) 和 (y_j),生成新的标签 (y_{\text{new}})。
[ x_{\text{new}} = x_i ]
[ x_{\text{new}}[x_{\text{cut}}] = x_j[x_{\text{cut}}] ]
[ y_{\text{new}} = \lambda y_i + (1 - \lambda) y_j ]
其中,(\lambda) 是剪切区域的面积占原图像的比例。
PyTorch实现示例:
import torch
import numpy as np
import torchvision.transforms.functional as F
def rand_bbox(size, lambda_):
W = size[2]
H = size[3]
cut_rat = np.sqrt(1. - lambda_)
cut_w = np.int(W * cut_rat)
cut_h = np.int(H * cut_rat)
# uniform
cx = np.random.randint(W)
cy = np.random.randint(H)
bbx1 = np.clip(cx - cut_w // 2, 0, W)
bby1 = np.clip(cy - cut_h // 2, 0, H)
bbx2 = np.clip(cx + cut_w // 2, 0, W)
bby2 = np.clip(cy + cut_h // 2, 0, H)
return bbx1, bby1, bbx2, bby2
def cutmix_data(x, y, alpha=1.0):
if alpha > 0:
lambda_ = np.random.beta(alpha, alpha)
else:
lambda_ = 1
batch_size = x.size(0)
index = torch.randperm(batch_size)
y_a, y_b = y, y[index]
bbx1, bby1, bbx2, bby2 = rand_bbox(x.size(), lambda_)
x[:, :, bbx1:bbx2, bby1:bby2] = x[index, :, bbx1:bbx2, bby1:bby2]
lambda_ = 1 - ((bbx2 - bbx1) * (bby2 - bby1) / (x.size()[-1] * x.size()[-2]))
return x, y_a, y_b, lambda_
def cutmix_criterion(criterion, pred, y_a, y_b, lambda_):
return lambda_ * criterion(pred, y_a) + (1 - lambda_) * criterion(pred, y_b)
总结
- Mixup通过线性插值混合图像和标签,生成新的训练样本。
- Cutmix通过剪切和粘贴部分区域来混合图像,同时调整标签。
这两种方法都能有效提高模型的泛化能力,使其在处理不同场景和复杂样本时具有更好的鲁棒性。

浙公网安备 33010602011771号