数据预处理 和 数据增强,我们一般都是使用 torchvision.transforms
模块来完成的。
我敢说,当你掌握了 torchvision.transforms
的使用方法之后,一定在数据预处理 和 数据增强 方面毫无压力
官网地址 :https://pytorch.org/vision/stable/transforms.html#others
简单使用举例
1、训练阶段
from torchvision.transforms import transforms
my_transform = transforms.Compose([transforms.RandomResizedCrop(img_size),
transforms.RandomHorizontalFlip(),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
2、推理阶段
from torchvision.transforms import transforms
my_transform = transforms.Compose([transforms.Resize(original_size*1.143)
transforms.CenterCrop(img_size),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])])
注:
-
操作顺序 : 几何变换 / 颜色变换 --->>
ToTensor()
--->>Normalize()
-
ToTensor()
和Normalize()
是数据处理的最后2步 -
经过
Normalize()
处理后,得到的数据,一般可直接输入到模型中使用
1、图像尺寸变换 与 裁剪
1)transforms.Resize
官方文档 : 点击跳转
torchvision.transforms.Resize(size,
interpolation=InterpolationMode.BILINEAR,
max_size=None)
作用:将图像按照指定的插值方式,resize到指定的尺寸。
参数:
-
size
: 输出的图像尺寸。可以是元组 (h, w) ,也可以是单个整数。-
如果 size 是元组,则输出大小将分别匹配 h, w 的大小
-
如果 size 是整数,则图像较小的边将被resize 到此数字,并保持宽高比
-
-
interpolation
: 选用如下插值方法将图像 resize 到输出尺寸-
PIL.Image.NEAREST
最近邻差值 -
PIL.Image.BILINEAR
双线性差值(默认) -
PIL.Image.BICUBIC
双三次差值
-
-
max_size
:输出图像的较长边的最大值。仅当 size 为单个整数时才支持此功能。如果图像的较长边在根据 size 缩放后大于 max_size,则 size 将被覆盖,使较长边等于 max_size,这时较短边会小于 size。
举例:
from PIL import Image
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
original_img = Image.open('image.jpg') # https://p.ipic.vip/7pvisy.jpg
print(original_img.size) # (3280, 1818)
img_1 = transforms.Resize(1500, max_size=None)(original_img)
print(img_1.size) # (2706, 1500)
img_2 = transforms.Resize((1500, 1500))(original_img)
print(img_2.size) # (1500, 1500)
img_3 = transforms.Resize(1500, max_size=1600)(original_img)
print(img_3.size) # (1600, 886)
plt.subplot(141)
plt.axis("off")
plt.imshow(original_img)
plt.subplot(142)
plt.axis("off")
plt.imshow(img_1)
plt.subplot(143)
plt.axis("off")
plt.imshow(img_2)
plt.subplot(144)
plt.axis("off")
plt.imshow(img_3)
plt.show()
2)transforms.CenterCrop
官方文档 : 点击跳转
torchvision.transforms.CenterCrop(size)
功能:从图片中心裁剪出尺寸为 size 的图片
参数:
size
: 所需裁剪的图片尺寸,即输出图像尺寸
注意:
-
若切正方形,
transforms.CenterCrop(100)
和transforms.CenterCrop((100, 100))
,两种写法,效果一样 -
如果设置的输出的尺寸 大于原图像尺寸,则会在四周补 padding,padding 颜色为黑色(像素值为0)
举例:
from PIL import Image
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
original_img = Image.open('image.jpg') # https://p.ipic.vip/7pvisy.jpg
print(original_img.size) # (3280, 1818)
img_1 = transforms.CenterCrop(1500)(original_img)
img_2 = transforms.CenterCrop((1500, 1500))(original_img)
img_3 = transforms.CenterCrop((3000, 3000))(original_img)
plt.subplot(141)
plt.axis("off")
plt.imshow(original_img)
plt.subplot(142)
plt.axis("off")
plt.imshow(img_1)
plt.subplot(143)
plt.axis("off")
plt.imshow(img_2)
plt.subplot(144)
plt.axis("off")
plt.imshow(img_3)
plt.show()
3)transforms.RandomCrop
官方文档 : 点击跳转
torchvision.transforms.RandomCrop(size,
padding = None,
pad_if_needed = False,
fill=0,
padding_mode ='constant')
功能:
-
从图片中随机裁剪出尺寸为 size 的图片
-
如果设置了参数
padding
,先添加 padding,再从padding后的图像中随机裁剪出大小为size的图片
参数:
-
size
:所需裁剪的图片尺寸,即输出图像尺寸 -
padding
: 设置填充大小-
当
padding
值形式式为 a 时,上下左右均填充 a 个像素 -
当
padding
值形式式为 (a, b) 时,左右填充 a 个像素,上下填充 b 个像素 -
当
padding
值形式式为 (a, b, c, d) 时,左上右下分别填充 a,b,c,d
-
-
pad_if_needed
:当原图像尺寸小于设置的输出图像尺寸(由参数size指定),是否填充,默认为 False -
padding_mode
:若pad_if_needed
设置为 True,则此参数起作用, 默认值为"constant"
-
"constant"
: 像素值由参数fill
指定 (默认填充黑色,像素值为0) -
"edge"
: padding 的像素值 为图像边缘像素值 -
"reflect"
: 镜像填充,最后一个像素不镜像。([1,2,3,4] --> [3,2,1,2,3,4,3,2]) -
"symmetric"
: 镜像填充,最后一个像素也镜像。([1,2,3,4] -->[2,1,1,2,3,4,4,3])
-
-
fill
:指定填充像素值,当 padding_mode 为 constant 时起作用,默认填充黑色,像素值为0
注意:
-
同时指定参数
padding_mode
和 参数fill
时,若padding_mode
值不为"constant"
,则 参数fill
不起作用。 -
若指定的输出图像尺寸size 大于输入图像尺寸,并且指定参数
pad_if_needed = False
,则会报错类似如下
举例:
from PIL import Image
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
original_img = Image.open('image.jpg') # https://p.ipic.vip/7pvisy.jpg
print(original_img.size) # (3280, 1818)
img_1 = transforms.RandomCrop(1500, padding=500)(original_img)
img_2 = transforms.RandomCrop(3000, pad_if_needed=True, fill=(255, 0, 0))(original_img)
img_3 = transforms.RandomCrop(3000, pad_if_needed=True, padding_mode="symmetric")(original_img)
plt.subplot(141)
plt.axis("off")
plt.imshow(original_img)
plt.subplot(142)
plt.axis("off")
plt.imshow(img_1)
plt.subplot(143)
plt.axis("off")
plt.imshow(img_2)
plt.subplot(144)
plt.axis("off")
plt.imshow(img_3)
plt.show()
4)transforms.RandomResizedCrop
官方文档 : 点击跳转
torchvision.transforms.RandomResizedCrop(size,
scale=(0.08, 1.0),
ratio=(0.75, 1.3333333333333333),
interpolation=InterpolationMode.BILINEAR)
功能:
-
Step 1 : 将图像进行随机裁剪,裁剪出的图像需满足:
-
裁剪后的图像面积 占原图像面积的比例 在指定的范围内
-
裁剪后的图像高宽比 在指定范围内
-
-
Step 2 :将 Step 1 得到的图像通过指定的方式,进行缩放
参数:
-
size
: 输出的图像尺寸 -
scale
: 随机缩放面积比例,默认随机选取 (0.08, 1) 之间的一个数 -
ratio
: 随机长宽比,默认随机选取 (0.75, 1.33333 ) 之间的一个数。超过这个比例范围会有明显的失真 -
interpolation
: 选用如下插值方法将图像 resize 到输出尺寸-
PIL.Image.NEAREST
最近邻差值 -
PIL.Image.BILINEAR
双线性差值(默认) -
PIL.Image.BICUBIC
双三次差值
-
举例:
from PIL import Image
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
original_img = Image.open('image.jpg') # https://p.ipic.vip/7pvisy.jpg
print(original_img.size) # (3280, 1818)
img = transforms.RandomResizedCrop(1500)(original_img)
plt.subplot(121)
plt.imshow(original_img)
plt.subplot(122)
plt.imshow(img)
plt.show()