seo排名工具外包,橘子seo历史查询,为知笔记 导入wordpress,计算机前端培训图像增广
sec_alexnet提到过大型数据集是成功应用深度神经网络的先决条件。 图像增广在对训练图像进行一系列的随机变化之后#xff0c;生成相似但不同的训练样本#xff0c;从而扩大了训练集的规模。 此外#xff0c;应用图像增广的原因是#xff0c;随机改变训练样本可以…图像增广
sec_alexnet提到过大型数据集是成功应用深度神经网络的先决条件。 图像增广在对训练图像进行一系列的随机变化之后生成相似但不同的训练样本从而扩大了训练集的规模。 此外应用图像增广的原因是随机改变训练样本可以减少模型对某些属性的依赖从而提高模型的泛化能力。 例如我们可以以不同的方式裁剪图像使感兴趣的对象出现在不同的位置减少模型对于对象出现位置的依赖。 我们还可以调整亮度、颜色等因素来降低模型对颜色的敏感度。 可以说图像增广技术对于AlexNet的成功是必不可少的。本节将讨论这项广泛应用于计算机视觉的技术。
%matplotlib inline
import torch
import torchvision
from torch import nn
from d2l import torch as d2l常用的图像增广方法
在对常用图像增广方法的探索时我们将使用下面这个尺寸为 400 × 500 400\times 500 400×500的图像作为示例。
d2l.set_figsize()
img d2l.Image.open(../img/cat1.jpg)
d2l.plt.imshow(img);
大多数图像增广方法都具有一定的随机性。为了便于观察图像增广的效果我们下面定义辅助函数apply。 此函数在输入图像img上多次运行图像增广方法aug并显示所有结果。
def apply(img, aug, num_rows2, num_cols4, scale1.5):Y [aug(img) for _ in range(num_rows * num_cols)]d2l.show_images(Y, num_rows, num_cols, scalescale)翻转和裁剪
[左右翻转图像]通常不会改变对象的类别。这是最早且最广泛使用的图像增广方法之一。 接下来我们使用transforms模块来创建RandomFlipLeftRight实例这样就各有50%的几率使图像向左或向右翻转。
apply(img, torchvision.transforms.RandomHorizontalFlip())
[上下翻转图像]不如左右图像翻转那样常用。但是至少对于这个示例图像上下翻转不会妨碍识别。接下来我们创建一个RandomFlipTopBottom实例使图像各有50%的几率向上或向下翻转。
apply(img, torchvision.transforms.RandomVerticalFlip())
在我们使用的示例图像中猫位于图像的中间但并非所有图像都是这样。 在 sec_pooling中我们解释了汇聚层可以降低卷积层对目标位置的敏感性。 另外我们可以通过对图像进行随机裁剪使物体以不同的比例出现在图像的不同位置。 这也可以降低模型对目标位置的敏感性。
下面的代码将[随机裁剪]一个面积为原始面积10%到100%的区域该区域的宽高比从0.52之间随机取值。 然后区域的宽度和高度都被缩放到200像素。 在本节中除非另有说明 a a a和 b b b之间的随机数指的是在区间 [ a , b ] [a, b] [a,b]中通过均匀采样获得的连续值。
shape_aug torchvision.transforms.RandomResizedCrop((200, 200), scale(0.1, 1), ratio(0.5, 2))
apply(img, shape_aug)
改变颜色
另一种增广方法是改变颜色。 我们可以改变图像颜色的四个方面亮度、对比度、饱和度和色调。 在下面的示例中我们[随机更改图像的亮度]随机值为原始图像的50% 1 − 0.5 1-0.5 1−0.5到150% 1 0.5 10.5 10.5之间。
apply(img, torchvision.transforms.ColorJitter(brightness0.5, contrast0, saturation0, hue0))
同样我们可以[随机更改图像的色调]。
apply(img, torchvision.transforms.ColorJitter(brightness0, contrast0, saturation0, hue0.5))
我们还可以创建一个RandomColorJitter实例并设置如何同时[随机更改图像的亮度brightness、对比度contrast、饱和度saturation和色调hue]。
color_aug torchvision.transforms.ColorJitter(brightness0.5, contrast0.5, saturation0.5, hue0.5)
apply(img, color_aug)
[结合多种图像增广方法]
在实践中我们将结合多种图像增广方法。比如我们可以通过使用一个Compose实例来综合上面定义的不同的图像增广方法并将它们应用到每个图像。
augs torchvision.transforms.Compose([torchvision.transforms.RandomHorizontalFlip(), color_aug, shape_aug])
apply(img, augs)
[使用图像增广进行训练]
让我们使用图像增广来训练模型。 这里我们使用CIFAR-10数据集而不是我们之前使用的Fashion-MNIST数据集。 这是因为Fashion-MNIST数据集中对象的位置和大小已被规范化而CIFAR-10数据集中对象的颜色和大小差异更明显。 CIFAR-10数据集中的前32个训练图像如下所示。
all_images torchvision.datasets.CIFAR10(trainTrue, root../data,downloadTrue)
d2l.show_images([all_images[i][0] for i in range(32)], 4, 8, scale0.8);Downloading https://www.cs.toronto.edu/~kriz/cifar-10-python.tar.gz to ../data/cifar-10-python.tar.gz0%| | 0/170498071 [00:00?, ?it/s]Extracting ../data/cifar-10-python.tar.gz to ../data为了在预测过程中得到确切的结果我们通常对训练样本只进行图像增广且在预测过程中不使用随机操作的图像增广。 在这里我们[只使用最简单的随机左右翻转]。 此外我们使用ToTensor实例将一批图像转换为深度学习框架所要求的格式即形状为批量大小通道数高度宽度的32位浮点数取值范围为01。
train_augs torchvision.transforms.Compose([torchvision.transforms.RandomHorizontalFlip(),torchvision.transforms.ToTensor()])test_augs torchvision.transforms.Compose([torchvision.transforms.ToTensor()])接下来我们[定义一个辅助函数以便于读取图像和应用图像增广]。PyTorch数据集提供的transform参数应用图像增广来转化图像。有关DataLoader的详细介绍请参阅 :numref:sec_fashion_mnist。
def load_cifar10(is_train, augs, batch_size):dataset torchvision.datasets.CIFAR10(root../data, trainis_train,transformaugs, downloadTrue)dataloader torch.utils.data.DataLoader(dataset, batch_sizebatch_size,shuffleis_train, num_workersd2l.get_dataloader_workers())return dataloader多GPU训练
我们在CIFAR-10数据集上训练 :numref:sec_resnet中的ResNet-18模型。 回想一下 :numref:sec_multi_gpu_concise中对多GPU训练的介绍。 接下来我们[定义一个函数使用多GPU对模型进行训练和评估]。
#save
def train_batch_ch13(net, X, y, loss, trainer, devices):用多GPU进行小批量训练if isinstance(X, list):# 微调BERT中所需X [x.to(devices[0]) for x in X]else:X X.to(devices[0])y y.to(devices[0])net.train()trainer.zero_grad()pred net(X)l loss(pred, y)l.sum().backward()trainer.step()train_loss_sum l.sum()train_acc_sum d2l.accuracy(pred, y)return train_loss_sum, train_acc_sum#save
def train_ch13(net, train_iter, test_iter, loss, trainer, num_epochs,devicesd2l.try_all_gpus()):用多GPU进行模型训练timer, num_batches d2l.Timer(), len(train_iter)animator d2l.Animator(xlabelepoch, xlim[1, num_epochs], ylim[0, 1],legend[train loss, train acc, test acc])net nn.DataParallel(net, device_idsdevices).to(devices[0])for epoch in range(num_epochs):# 4个维度储存训练损失训练准确度实例数特点数metric d2l.Accumulator(4)for i, (features, labels) in enumerate(train_iter):timer.start()l, acc train_batch_ch13(net, features, labels, loss, trainer, devices)metric.add(l, acc, labels.shape[0], labels.numel())timer.stop()if (i 1) % (num_batches // 5) 0 or i num_batches - 1:animator.add(epoch (i 1) / num_batches,(metric[0] / metric[2], metric[1] / metric[3],None))test_acc d2l.evaluate_accuracy_gpu(net, test_iter)animator.add(epoch 1, (None, None, test_acc))print(floss {metric[0] / metric[2]:.3f}, train acc f{metric[1] / metric[3]:.3f}, test acc {test_acc:.3f})print(f{metric[2] * num_epochs / timer.sum():.1f} examples/sec on f{str(devices)})现在我们可以[定义train_with_data_aug函数使用图像增广来训练模型]。该函数获取所有的GPU并使用Adam作为训练的优化算法将图像增广应用于训练集最后调用刚刚定义的用于训练和评估模型的train_ch13函数。
batch_size, devices, net 256, d2l.try_all_gpus(), d2l.resnet18(10, 3)def init_weights(m):if type(m) in [nn.Linear, nn.Conv2d]:nn.init.xavier_uniform_(m.weight)net.apply(init_weights)def train_with_data_aug(train_augs, test_augs, net, lr0.001):train_iter load_cifar10(True, train_augs, batch_size)test_iter load_cifar10(False, test_augs, batch_size)loss nn.CrossEntropyLoss(reductionnone)trainer torch.optim.Adam(net.parameters(), lrlr)train_ch13(net, train_iter, test_iter, loss, trainer, 10, devices)让我们使用基于随机左右翻转的图像增广来[训练模型]。
train_with_data_aug(train_augs, test_augs, net)loss 0.173, train acc 0.941, test acc 0.854
4183.9 examples/sec on [device(typecuda, index0), device(typecuda, index1)]小结
图像增广基于现有的训练数据生成随机图像来提高模型的泛化能力。为了在预测过程中得到确切的结果我们通常对训练样本只进行图像增广而在预测过程中不使用带随机操作的图像增广。深度学习框架提供了许多不同的图像增广方法这些方法可以被同时应用。