# 【从零开始学习深度学习】44. 图像增广的几种常用方式并使用图像增广训练模型【Pytorch】

%matplotlib inline
import time
import torch
from torch import nn, optim
import torchvision
from PIL import Image
import sys
import d2lzh_pytorch as d2l
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')

## 1. 常用的图像增广方法

d2l.set_figsize()
img = Image.open('./img/cat1.jpg')
d2l.plt.imshow(img)

def show_images(imgs, num_rows, num_cols, scale=2):
figsize = (num_cols * scale, num_rows * scale)
_, axes = d2l.plt.subplots(num_rows, num_cols, figsize=figsize)
for i in range(num_rows):
for j in range(num_cols):
axes[i][j].imshow(imgs[i * num_cols + j])
axes[i][j].axes.get_xaxis().set_visible(False)
axes[i][j].axes.get_yaxis().set_visible(False)
return axes

def apply(img, aug, num_rows=2, num_cols=4, scale=1.5):
# aug为传入的图像增广方法函数
Y = [aug(img) for _ in range(num_rows * num_cols)]
show_images(Y, num_rows, num_cols, scale)

### 1.1 翻转和裁剪

# transforms.RandomHorizontalFlip(p=0.5)默认p=0.5表示一半概率翻转
apply(img, torchvision.transforms.RandomHorizontalFlip())

apply(img, torchvision.transforms.RandomVerticalFlip())

shape_aug = torchvision.transforms.RandomResizedCrop(200, scale=(0.1, 1), ratio=(0.5, 2))
apply(img, shape_aug)

### 1.2 变化颜色

apply(img, torchvision.transforms.ColorJitter(brightness=0.5))

apply(img, torchvision.transforms.ColorJitter(hue=0.5))

apply(img, torchvision.transforms.ColorJitter(contrast=0.5))

color_aug = torchvision.transforms.ColorJitter(
brightness=0.5, contrast=0.5, saturation=0.5, hue=0.5)
apply(img, color_aug)

### 1.3 叠加多个图像增广方法

augs = torchvision.transforms.Compose([
torchvision.transforms.RandomHorizontalFlip(), color_aug, shape_aug])
apply(img, augs)

## 2 使用图像增广训练模型

all_imges = torchvision.datasets.CIFAR10(train=True, root="~/Datasets/CIFAR", download=True)
# all_imges的每一个元素都是(image, label)
show_images([all_imges[i][0] for i in range(32)], 4, 8, scale=0.8);

flip_aug = torchvision.transforms.Compose([
torchvision.transforms.RandomHorizontalFlip(),
torchvision.transforms.ToTensor()])
no_aug = torchvision.transforms.Compose([
torchvision.transforms.ToTensor()])

num_workers = 0 if sys.platform.startswith('win32') else 4
return DataLoader(dataset, batch_size=batch_size, shuffle=is_train, num_workers=num_workers)

### 2.1 训练模型

def train(train_iter, test_iter, net, loss, optimizer, device, num_epochs):
net = net.to(device)
print("training on ", device)
batch_count = 0
for epoch in range(num_epochs):
train_l_sum, train_acc_sum, n, start = 0.0, 0.0, 0, time.time()
for X, y in train_iter:
X = X.to(device)
y = y.to(device)
y_hat = net(X)
l = loss(y_hat, y)
l.backward()
optimizer.step()
train_l_sum += l.cpu().item()
train_acc_sum += (y_hat.argmax(dim=1) == y).sum().cpu().item()
n += y.shape[0]
batch_count += 1
test_acc = d2l.evaluate_accuracy(test_iter, net)
print('epoch %d, loss %.4f, train acc %.3f, test acc %.3f, time %.1f sec'
% (epoch + 1, train_l_sum / batch_count, train_acc_sum / n, test_acc, time.time() - start))


def train_with_data_aug(train_augs, test_augs, lr=0.001):
batch_size, net = 256, d2l.resnet18(10)
loss = torch.nn.CrossEntropyLoss()
# 对训练数据使用图像增广
# 对测试数据不使用图像增广
train(train_iter, test_iter, net, loss, optimizer, device, num_epochs=10)

train_with_data_aug(flip_aug, no_aug)

training on  cuda
epoch 1, loss 1.3615, train acc 0.505, test acc 0.493, time 123.2 sec
epoch 2, loss 0.5003, train acc 0.645, test acc 0.620, time 123.0 sec
epoch 3, loss 0.2811, train acc 0.703, test acc 0.616, time 123.1 sec
epoch 4, loss 0.1890, train acc 0.735, test acc 0.686, time 123.0 sec
epoch 5, loss 0.1346, train acc 0.765, test acc 0.671, time 123.1 sec
epoch 6, loss 0.1029, train acc 0.787, test acc 0.674, time 123.1 sec
epoch 7, loss 0.0803, train acc 0.804, test acc 0.749, time 123.1 sec
epoch 8, loss 0.0644, train acc 0.822, test acc 0.717, time 123.1 sec
epoch 9, loss 0.0526, train acc 0.836, test acc 0.750, time 123.0 sec
epoch 10, loss 0.0433, train acc 0.851, test acc 0.754, time 123.1 sec

## 总结

• 图像增广基于现有训练数据生成随机图像从而应对过拟合。
• 为了在预测时得到确定的结果，通常只将图像增广应用在训练样本上，而不在预测时使用含随机操作的图像增广。
• 可以从torchvision的transforms模块中获取有关图片增广的类。

|
2天前
|

24 3
|
2天前
|

【7月更文挑战第19天】 使用Python实现深度学习模型：语音合成与语音转换
17 1
|
3天前
|

【7月更文挑战第18天】 使用Python实现深度学习模型：人脸识别与人脸表情分析
14 2
|
4天前
|

【7月更文挑战第17天】 使用Python实现深度学习模型：图像超分辨率与去噪
18 4
|
5天前
|

【7月更文挑战第16天】 使用Python实现深度学习模型：视频处理与动作识别
39 17
|
6天前
|

38 9
|
6天前
|

【7月更文挑战第15天】 使用Python实现深度学习模型：图像语义分割与对象检测
27 2
|
7天前
|

【7月更文挑战第14天】 使用Python实现深度学习模型：文本生成与自然语言处理
35 12
|
8天前
|

21 9
|
8天前
|

13 0