Datawhale AI 夏令营 Task03 学习笔记

Datawhale AI 夏令营 Task03 学习笔记

part1 数据增强基础

数据增强(Data Augmentation)在机器学习和深度学习中的应用非常广泛,尤其是对图像和视频数据。在图像处理中,数据增强技术能够有效地提高模型的泛化能力,通过模拟各种可能的现实场景变化,使得模型在未见过的数据上也能表现良好。常见的图像数据增强技术包括但不限于:

  1. 旋转:对图像进行随机角度的旋转,可以帮助模型学习不同角度下的特征表示。
  2. 缩放:随机缩放图像的大小,保持物体的比例不变。
  3. 裁剪:随机裁剪图像的一部分,这有助于模型关注图像的不同部分。
  4. 翻转:包括水平翻转和垂直翻转,模拟物体在不同方向上的观察。
  5. 亮度调整:随机调整图像的亮度,以适应不同光照条件。
  6. 对比度调整:随机改变图像的对比度,使模型能够在不同对比度的情况下识别物体。
  7. 噪声添加:在图像中添加随机噪声,增强模型的鲁棒性。

然而,数据增强也需要注意适度和相关性。如果所使用的变换与目标任务的实际场景不符,可能会引入不必要的噪音,反而降低模型的性能。例如,对于一个不需要旋转的任务,如果过度使用旋转变换,可能会使模型难以学习到有效的特征。同样,过度的数据增强(如极端的亮度或对比度调整)可能会导致图像失真,使得模型难以训练。

以下是使用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是一种在训练集中混合图像和标签的方法,通过线性插值生成新的训练样本。这种方法的核心思想是将两张图像及其标签按一定比例混合,从而生成新的训练数据。

具体实现步骤:

  1. 随机选择两张图像 (x_i) 和 (x_j),以及它们对应的标签 (y_i) 和 (y_j)。
  2. 生成一个介于0到1之间的随机数 (\lambda),通常服从Beta分布。
  3. 按照 (\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类似,但它通过在图像中剪切和粘贴部分区域来进行混合,而不是线性插值。这种方法通过将一张图像的一部分替换为另一张图像的一部分,同时调整标签,生成新的训练样本。

具体实现步骤:

  1. 随机选择两张图像 (x_i) 和 (x_j),以及它们对应的标签 (y_i) 和 (y_j)。
  2. 随机确定剪切区域的位置和大小。
  3. 将图像 (x_j) 的剪切区域替换到图像 (x_i) 的对应位置,生成新的图像 (x_{\text{new}})。
  4. 根据剪切区域的比例调整标签 (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通过剪切和粘贴部分区域来混合图像,同时调整标签。

这两种方法都能有效提高模型的泛化能力,使其在处理不同场景和复杂样本时具有更好的鲁棒性。

posted @ 2024-07-20 17:14  zfz04  阅读(37)  评论(0)    收藏  举报