参考伯禹学习平台《动手学深度学习》课程内容内容撰写的学习笔记
原文链接:https://www.boyuai.com/elites/course/cZu18YmweLv10OeV/lesson/6zsAsvcJ58UKvWtKArTqwq
感谢伯禹平台,Datawhale,和鲸,AWS给我们提供的免费学习机会!!
总的学习感受:伯禹的课程做的很好,课程非常系统,每个较高级别的课程都会有需要掌握的前续基础知识的介绍,因此很适合本人这种基础较差的同学学习,建议基础较差的同学可以关注伯禹的其他课程:
数学基础:https://www.boyuai.com/elites/course/D91JM0bv72Zop1D3
机器学习基础:https://www.boyuai.com/elites/course/5ICEBwpbHVwwnK3C
图像增广
在5.6节(深度卷积神经网络)里我们提到过,大规模数据集是成功应用深度神经网络的前提。图像增广(image augmentation)技术通过对训练图像做一系列随机改变,来产生相似但又不同的训练样本,从而扩大训练数据集的规模。图像增广的另一种解释是,随机改变训练样本可以降低模型对某些属性的依赖,从而提高模型的泛化能力。例如,我们可以对图像进行不同方式的裁剪,使感兴趣的物体出现在不同位置,从而减轻模型对物体出现位置的依赖性。我们也可以调整亮度、色彩等因素来降低模型对色彩的敏感度。可以说,在当年AlexNet的成功中,图像增广技术功不可没。本节我们将讨论这个在计算机视觉里被广泛使用的技术。
首先,导入实验所需的包或模块。
import os
os.listdir("/home/kesci/input/img2083/")
%matplotlib inline
import os
import time
import torch
from torch import nn, optim #nn定义整个模型的,optim定义优化器的
from torch.utils.data import Dataset, DataLoader # 加载数据,保存数据的。
import torchvision #图像亮度等性质的
import sys
from PIL import Image
sys.path.append("/home/kesci/input/")
#置当前使用的GPU设备仅为0号设备
os.environ[“CUDA_VISIBLE_DEVICES”] = “0”
import d2lzh1981 as d2l
#定义device,是否使用GPU,依据计算机配置自动会选择
device = torch.device(‘cuda’ if torch.cuda.is_available() else ‘cpu’)
print(torch.version)
print(device)
常用的图像增广方法
我们来读取一张形状为 400 × 500 400\times 500 400×500(高和宽分别为400像素和500像素)的图像作为实验的样例。
d2l.set_figsize()
img = Image.open(’/home/kesci/input/img2083/img/cat1.jpg’)
d2l.plt.imshow(img) #默认带坐标轴的
下面定义绘图函数show_images。
#本函数已保存在d2lzh_pytorch包中方便以后使用
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) #坐标轴隐藏False
axes[i][j].axes.get_yaxis().set_visible(False)
return axes
大部分图像增广方法都有一定的随机性。为了方便观察图像增广的效果,接下来我们定义一个辅助函数apply。这个函数对输入图像img多次运行图像增广方法aug并展示所有的结果。
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)
翻转和裁剪
左右翻转图像通常不改变物体的类别。它是最早也是最广泛使用的一种图像增广方法。下面我们通过torchvision.transforms模块创建RandomHorizontalFlip实例来实现一半概率的图像水平(左右)翻转。
apply(img, torchvision.transforms.RandomHorizontalFlip())
上下翻转不如左右翻转通用。但是至少对于样例图像,上下翻转不会造成识别障碍。下面我们创建RandomVerticalFlip实例来实现一半概率的图像垂直(上下)翻转。
apply(img, torchvision.transforms.RandomVerticalFlip())
在我们使用的样例图像里,猫在图像正中间,但一般情况下可能不是这样。在5.4节(池化层)里我们解释了池化层能降低卷积层对目标位置的敏感度。除此之外,我们还可以通过对图像随机裁剪来让物体以不同的比例出现在图像的不同位置,这同样能够降低模型对目标位置的敏感性。
在下面的代码里,我们每次随机裁剪出一块面积为原面积 10 %