PyTorch torchvision.transforms的方法

在实际应用过程中,我们需要在数据进入模型之前进行一些预处理,例如数据中心化(仅减均值),数据标准化(减均值,再除以标准差),随机裁剪,旋转一定角度,镜像等一系列操作。PyTorch有一系列数据增强方法供大家使用。在PyTorch中,这些数据增强方法放在了transforms.py文件中。这些数据处理可以满足我们大部分的需求,而且通过熟悉transforms.py,我们也可以自定义数据处理函数,实现自己的数据增强。 本文对transforms.py中的各个预处理方法进行介绍和总结。主要从官方文档中总结而来,官方文档只是将方法罗列,并没有进行归纳整理。使用的版本是1.7.0。我们采用的是余霆嵩的分类[1],共有四大类:

  1. 裁剪——Crop 中心裁剪:transforms.CenterCrop 随机裁剪:transforms.RandomCrop 随机长宽比裁剪:transforms.RandomResizedCrop 上下左右中心裁剪:transforms.FiveCrop 上下左右中心裁剪后翻转,transforms.TenCrop
  2. 翻转和旋转——Flip and Rotation 依概率p水平翻转:transforms.RandomHorizontalFlip(p=0.5) 依概率p垂直翻转:transforms.RandomVerticalFlip(p=0.5) 随机旋转:transforms.RandomRotation
  3. 图像变换 resize:transforms.Resize 标准化:transforms.Normalize 转为tensor,并归一化至[0-1]:transforms.ToTensor 填充:transforms.Pad 修改亮度、对比度和饱和度:transforms.ColorJitter 转灰度图:transforms.Grayscale 线性变换:transforms.LinearTransformation() 仿射变换:transforms.RandomAffine 依概率p转为灰度图:transforms.RandomGrayscale 将数据转换为PILImage:transforms.ToPILImage transforms.Lambda:Apply a user-defined lambda as a transform
  4. 对transforms操作,使数据增强更灵活 transforms.RandomChoice(transforms), 从给定的一系列transforms中选一个进行操作 transforms.RandomApply(transforms, p=0.5),给一个transform加上概率,依概率进行操作 transforms.RandomOrder,将transforms中的操作随机打乱

一、裁剪

1.随机裁剪

class torchvision.transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant')
 """
 功能:
 从一个随机位置开始裁剪给定的图片;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     size- (sequence or int),裁剪后图片的尺寸;若传入(h,w)形式的sequence,输出尺寸为(h,w);
        若传入长度为1的sequence,输出尺寸为(sequence[0],sequence[0]);若传入int,输出尺寸为(size,size).
     
     padding-(sequence or int, optional),可选参数,指定在图片各个边界处填充的值。若传入int,图像上下左右均填充padding个值。
        若传入为sequence时,长度为2时,第一个数表示左右的填充数目,第二个数表示上下的填充数目,长度为4时,则分别表示左,上,右,下的填充数目。
     
     pad_if_needed - (boolean),控制参数,用在避免因为图片的尺寸小于设定输出导致抛出错误,由于在padding之后就进行了裁剪,所以会看起来像是pandding在随机的偏移位置处。
        若有疑问,建议阅读源码https://pytorch.org/docs/stable/_modules/torchvision/transforms/transforms.html#RandomCrop
 
     fill- (int or tuple) 用于padding时填充的值(仅当填充模式为constant时有用)。
        若传入int,各通道均填充该值;若传入长度为3的tuple时,分别表示RGB通道需要填充的值。
     
     padding_mode - (str) 填充模式,可选项有:1.constant,填充值为常量,即fill参数传入的值。2.edge 重复图片边缘的像素值来填充。
        3.reflect,用图像的反射作为填充值,且边缘像素不重复.举例来说,对 [1, 2, 3, 4]进行reflect模式填充2个元素的结果时 [3, 2, 1, 2, 3, 4, 3, 2],
        可以观察到图片边缘元素1和4是作为镜子的存在,其两边的元素是对称的。 
        4. symmetric,与reflect模式类似,但边缘像素需要重复一次,举例来说,对 [1, 2, 3, 4]进行symmetric模式填充3个元素的结果时 [3,2, 1, 1, 2, 3, 4, 4, 3,2],
        可以观察到图片边缘元素1和4都被重复了一次,然后这两个元素作为镜子的存在,其两边的元素是对称的。
 """

2.中心裁剪

class torchvision.transforms.CenterCrop(size)
 """
 功能:
 从中心位置开始裁剪给定的图片;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     size - (sequence or int),裁剪后图片的尺寸;若传入(h,w)形式的sequence,输出尺寸为(h,w);
        若传入长度为1的sequence,输出尺寸为(sequence[0],sequence[0]);若传入int,输出尺寸为(size,size).
 """

3.随机长宽比裁剪

class torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=2)
 """
 功能:
 随机尺寸,随机长宽比裁剪图片,最后将图片resize到设定好的size;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 随机尺寸的默认值是(0.08,1.0),表示原始尺寸的 and a random aspect ratio (default: of 3/4 to 4/3) of the original aspect ratio is made. This crop is finally resized to given size. This is popularly used to train the Inception networks.
 参数:
     size - (sequence or int),裁剪后图片的尺寸;若传入(h,w)形式的sequence,输出尺寸为(h,w);
        若传入长度为1的sequence,输出尺寸为(sequence[0],sequence[0]);若传入int,输出尺寸为(size,size).
     
     scale - (tuple of python:float),表示随机尺寸的范围,默认值(0.08,1.0)表示裁剪后的尺寸是在原始尺寸的0.08倍和1倍之间随机。
     
     ratio - (tuple of python:float) 表示随机长宽比的范围,默认值(3/4,4/3)表示裁剪后的长宽比是在原始尺寸长宽比的3/4倍和4/3倍之间随机。
     
     interpolation - (int) 表示插值的方法,默认为双线性插值(PIL.Image.BILINEAR)。如果输入的是Tensor类型, 仅支持PIL.Image.NEAREST, PIL.Image.BILINEAR and PIL.Image.BICUBIC。
 """

4.上下左右中心裁剪

class torchvision.transforms.FiveCrop(size)
 """
 功能:
 裁剪给定的图片为5个图片,分别是从4个角落和中心裁剪;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     size - (sequence or int),裁剪后图片的尺寸;若传入(h,w)形式的sequence,输出尺寸为(h,w);若传入长度为1的sequence,输出尺寸为(sequence[0],sequence[0]);若传入int,输出尺寸为(size,size).
 """
 #Example
 >>> transform = Compose([
 >>>    FiveCrop(size), # this is a list of PIL Images
 >>>    Lambda(lambda crops: torch.stack([ToTensor()(crop) for crop in crops])) # returns a 4D tensor
 >>> ])
 >>> #In your test loop you can do the following:
 >>> input, target = batch # input is a 5d tensor, target is 2d
 >>> bs, ncrops, c, h, w = input.size()
 >>> result = model(input.view(-1, c, h, w)) # fuse batch size and ncrops
 >>> result_avg = result.view(bs, ncrops, -1).mean(1) # avg over crops

5.上下左右中心裁剪后翻转

class torchvision.transforms.TenCrop(size, vertical_flip=False)
 """
 功能:
 裁剪给定的图片为5个图片,分别是从4个角落和中心裁剪,并进行翻转,形成10个图片输出(默认是水平翻转);
给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     size - (sequence or int),裁剪后图片的尺寸;若传入(h,w)形式的sequence,输出尺寸为(h,w);
        若传入长度为1的sequence,输出尺寸为(sequence[0],sequence[0]);若传入int,输出尺寸为(size,size).
     
     vertical_flip - (bool) 是否使用垂直翻转代替水平翻转
 """
 #example
 >>> transform = Compose([
 >>>    TenCrop(size), # this is a list of PIL Images
 >>>    Lambda(lambda crops: torch.stack([ToTensor()(crop) for crop in crops])) # returns a 4D tensor
 >>> ])
 >>> #In your test loop you can do the following:
 >>> input, target = batch # input is a 5d tensor, target is 2d
 >>> bs, ncrops, c, h, w = input.size()
 >>> result = model(input.view(-1, c, h, w)) # fuse batch size and ncrops
 >>> result_avg = result.view(bs, ncrops, -1).mean(1) # avg over crops

二、翻转和旋转

6.依概率p水平翻转

class torchvision.transforms.RandomHorizontalFlip(p=0.5)
 """
 功能:
 以给定的概率水平翻转给定的图片;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     p - (float),翻转图片的概率.
 """

7.依概率p垂直翻转

class torchvision.transforms.RandomVerticalFlip(p=0.5)
 """
 功能:
 以给定的概率垂直翻转给定的图片;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     p - (float),翻转图片的概率.
 """

8.随机旋转

class torchvision.transforms.RandomRotation(degrees, resample=False, expand=False, center=None, fill=None)
 """
 功能:
 以一定的角度旋转图片;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
 参数:
     degrees - (sequence or float or int) 旋转角度的范围,若传入sequence,则范围是(min,max);若传入的是int 或者 float,则范围是[-degrees,+degrees].
     
     resample - (int, optional) 复采样方法. 若不传入参数或者输入的图片具有模式“1”或“P”,则设为PIL.Image.NEAREST.若输入是Tensor, 仅支持PIL.Image.NEAREST和PIL.Image.BILINEAR。
     
     expand - (bool, optional) 可选参数,作为拓展标志。 若是true, 则拓展到可以放下旋转后图片的所有像素(原因是旋转后的图片的H或W肯定比未旋转之前的要大,原理参照矩形的对角线总是大于长和宽)。
        若是false 或者不传参,保持尺寸不变. 需要注意的是,这里假设旋转是以图片中心为原点旋转的,并且没有做任何转化(transform).
     
     center - (list or tuple, optional) – 旋转中心, 参数形式必须有两个值(x, y),表示旋转中心的位置,原点是图片左上角;默认值是图片中心.
     
     fill - (n-tuple or int or float) – 用于填充在旋转图片之外的像素点的值. 若传入int或float, 这个值被用于所有需要填充的范围,默认值是0,需要Pillow>=5.2.0,并且不支持Tensor格式的输入.
        在转化范围之外的填充值始终是0。
 """

三、图像变换

9.修改尺寸

class torchvision.transforms.Resize(size, interpolation=2)
"""
功能:
重新设置图片的分辨率;给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
参数:
	size - (sequence or int) 输出尺寸,若传入sequence,比如(h, w),则输出尺寸就是(h, w);
        若传入int,则原本小的边会被置为size,例如height > width, 输出尺寸是 (size * height / width, size). 
        在torchscript模式中不支持直接传入单个int,需要使用长度为1的tuple或list: [size, ].
	
	interpolation - (int, optional) – 插值方法. 默认是PIL.Image.BILINEAR. 若输入格式是Tensor, 则支持PIL.Image.NEAREST, PIL.Image.BILINEAR和PIL.Image.BICUBIC.
"""

10.标准化

class torchvision.transforms.Normalize(mean, std, inplace=False)
"""
功能:
用均值和标准差做标准化. 参数mean: (mean[1],...,mean[n])和参数std: (std[1],..,std[n])都是sequence,维度均是channel数, 
对输入的Tensor的每个维度分别进行标准化,比如output[channel] = (input[channel] - mean[channel]) / std[channel]。
参数:
	mean - (sequence) – 包含各channel均值的Sequence.
	
	std - (sequence) – 包含各channel标准差的Sequence.
	
	inplace - (bool,optional) – 是否原地修改数据.
"""

11.转为tensor

class torchvision.transforms.ToTensor
"""
功能:
把PIL Image或numpy.ndarray转换成tensor.当numpy.ndarray的dtype是np.uint8时,或PIL Image的模式是(L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1)时,
将shape是 (H x W x C)且取值范围为[0, 255]的PIL Image或numpy.ndarray转换成shape为(C x H x W)取值范围为[0.0, 1.0]的torch.FloatTensor。
其他情况下,tensors原样返回,不做归一。
"""

12.填充

class torchvision.transforms.Pad(padding, fill=0, padding_mode='constant')
"""
功能:
在输入图片的各个边界外用给定的值填充. 给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W] 的形式,其中, … 表示任意正整数。
参数:
	padding - (int or tuple or list) – 用于填充的值.指定在图片各个边界处填充的值。若传入int,图像上下左右均填充padding个值。
        若传入为sequence时,长度为2时,第一个数表示左右的填充数目,第二个数表示上下的填充数目,长度为4时,则分别表示左,上,右,下的填充数目。
        在torchscript模式不支持传入单个int需传入长度为1的tuple或list: [padding, ].
	
	fill - (int or tuple) – 用于padding时填充的值(仅当填充模式为constant时有用)。若传入int,各通道均填充该值;若传入长度为3的tuple时,分别表示RGB通道需要填充的值。
	
	padding_mode - (str) 填充模式,可选项有:1.constant,填充值为常量,即fill参数传入的值。2.edge 重复图片边缘的像素值来填充。
        3.reflect,用图像的反射作为填充值,且边缘像素不重复,举例来说,对 [1, 2, 3, 4]进行reflect模式填充2个元素的结果时 [3, 2, 1, 2, 3, 4, 3, 2],
        可以观察到图片边缘元素1和4是作为镜子的存在,其两边的元素是对称的。 
        4. symmetric,与reflect模式类似,但边缘像素需要重复一次,举例来说,对 [1, 2, 3, 4]进行symmetric模式填充3个元素的结果时 [3,2, 1, 1, 2, 3, 4, 4, 3,2],
        可以观察到图片边缘元素1和4都被重复了一次,然后这两个元素作为镜子的存在,其两边的元素是对称的。
"""

13.修改亮度、对比度和饱和度

class torchvision.transforms.ColorJitter(brightness=0, contrast=0, saturation=0, hue=0)
"""
功能:
随机修改图片的亮度、对比度和饱和度. 
参数:
	brightness - (float or tuple of python:float (min, max)) 限定亮度范围的参数,最终亮度brightness_factor的值从
    均匀分布[max(0, 1 - brightness), 1 + brightness]或给定的[min, max]中随机选择.参数值要求非负.
	
	contrast - (float or tuple of python:float (min, max)) – 限定对比度范围的参数.最终对比度contrast_factor的值
    从均匀分布[max(0, 1 - contrast), 1 + contrast]或给定的[min, max]中随机选择.参数值要求非负.
	
	saturation - (float or tuple of python:float (min, max)) – 限定饱和度范围的参数.最终饱和度saturation_factor的值
    从均匀分布[max(0, 1 - saturation), 1 + saturation]或给定的[min, max]中随机选择.参数值要求非负.
	
	hue - (float or tuple of python:float (min, max)) – 限定色调范围的参数. 最终色调值hue_factor
    从均匀分布[-hue, hue]或给定的[min, max]中随机选择. 须满足 0<= hue <= 0.5 or -0.5 <= min <= max <= 0.5.
"""

14.转灰度图

class torchvision.transforms.Grayscale(num_output_channels=1)
"""
功能:
将图片转成灰度图.给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, 3, H, W]的形式,其中, … 表示任意正整数。
参数:
	num_output_channels - (int) 输出图片的通道数,取值为1时,输出图片时单通道,取值为3时,输出图片的3通道r == g == b
"""

15.线性变换

class torchvision.transforms.LinearTransformation(transformation_matrix, mean_vector)
"""
功能:
用一个转换矩阵和一个离线计算出的均值向量将图片进行转换。给定转换矩阵transformation_matrix后,会将torch.*Tensor平铺并按位减mean_vector,
之后与转换矩阵做点积(dot product)运算,最后将shape转换成原始尺寸。
应用场景:
白化处理(whitening transformation): 假定X是零均值化后的列向量,用torch.mm(X.t(), X)计算协方差矩阵(维度是[D x D]),进行奇异值分解(SVD)后作为转换矩阵传入。
参数:
	transformation_matrix - (Tensor) shape为[D x D]的tensor , D = C x H x W
	
	mean_vector - (Tensor) – shape为[D]的tensor, D = C x H x W
"""

16.仿射变换

class torchvision.transforms.RandomAffine(degrees, translate=None, scale=None, shear=None, resample=0, fillcolor=0)
"""
功能:
对输入图片进行随机仿射变换并保持图片中心不变;仿射变换是二维的线性变换,由五种基本原子变换构成,分别是旋转、平移、缩放、错切和翻转。
给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…, H, W]的形式,其中, … 表示任意正整数。
参数:
	degrees (sequence or float or int) - 旋转角度的范围,若传入sequence,则范围是(min,max);
        若传入的是int 或者 float,则范围是[-degrees,+degrees]. 设置为0可以关闭旋转功能.
	
	translate (tuple, optional) – 指定水平和垂直平移的最大比例的tuple.例如,translate=(a, b), 则水平的平移幅度dx的取值范围是 -img_width * a < dx < img_width * a,
        垂直的平移幅度dy的取值范围是-img_height * b < dy < img_height * b. dx和dy都是从范围内随机选择,默认功能不开启.
	
	scale (tuple, optional) – 缩放范围参数(以面积为单位),例如(a, b),则缩放比例从(a, b)中随机选择.默认不进行缩放.
	
	shear (sequence or float or int, optional) – 指定错切的角度范围. 若传入int或float, 范围为(-shear, +shear)且平行于x轴的错切将被使用. 
        若传入长度为2的tuple或list,范围为(shear[0], shear[1])且平行于x轴的错切将被使用. 
        若传入长度为4的tuple或list, 范围为(shear[0], shear[1])且平行于x轴的错切将被使用,范围为(shear[2], shear[3])且平行于y轴的错切将被使用.默认功能不开启.
	
	resample (int, optional) – 复采样方法. 若不传入参数或者输入的图片具有模式“1”或“P”,则设为PIL.Image.NEAREST.
        若输入是Tensor, 仅支持PIL.Image.NEAREST和PIL.Image.BILINEAR。
	
	fillcolor (tuple or int) – 用于填充像素点的值(填充RGB图需要传入tuple,填充灰度图需要传入int). 
        仅支持Pillow>=5.0.0,并且不支持Tensor格式的输入.在转化范围之外的填充值始终是0。
"""

17.依概率p转为灰度图

class torchvision.transforms.RandomGrayscale(p=0.1)
"""
功能:
以概率p(默认值0.1)随机转换输入图片为灰度图. 给定的图片可以是PIL image格式或者Tensor格式,且其shape需要满足[…,3, H, W] 的形式,其中, … 表示任意正整数。
参数:
	p (float) – 转换概率.
"""

18.将数据转换为PILImage

class torchvision.transforms.ToPILImage(mode=None)
"""
功能:
将tensor或ndarray转换成PIL Image.不支持torchscript.将shape为C x H x W的torch.*Tensor或shape为H x W x C的numpy ndarray转换成PIL Image,同时保持值范围不变.
参数:
	mode (PIL.Image mode) – 设定输入图片颜色空间(color space)和像素范围(pixel depth.若mode 是None,则会对输入图片作一些假设: 若输入图片有4个channel, 则mode被假定为RGBA.若输入图片有3个channel, 则mode被假定为RGB.若输入图片有2个channel, 则mode被假定为LA.若输入图片有1个channel, 则mode由数据类型决定(比如 int, float, short).
"""

19.Lambda

class torchvision.transforms.Lambda(lambd)
"""
功能:
用户自定义的lambda函数作为transform.不支持torchscript.
参数:
	lambd (function) – 用于转换的Lambda函数.
"""

四、对transforms的操作

20.transforms.RandomChoice

class torchvision.transforms.RandomChoice(transforms)
"""
功能:
从transform列表中随机选择一个来使用. 不支持torchscript.
参数:
	transforms (list or tuple)– 待选的转换们.
"""

21.transforms.RandomApply

class torchvision.transforms.RandomApply(transforms, p=0.5)
"""
功能:
以概率p来决定是否使用transforms(列表)中的转换.
参数:
	transforms (list or tuple)– 待选的转换列表.
"""
#NOTE:
#为了script转换,请使用torch.nn.ModuleList格式作为输入,如下所示:
#example
>>> transforms = transforms.RandomApply(torch.nn.ModuleList([
>>>     transforms.ColorJitter(),
>>> ]), p=0.3)
>>> scripted_transforms = torch.jit.script(transforms)

22.transforms.RandomOrder

class torchvision.transforms.RandomOrder(transforms)
"""
功能:
随机打乱transforms中的顺序.不支持torchscript.
参数:
	transforms (list or tuple)– 待选的转换们.
"""

参考文献

[1]《Pytorch模型训练实用教程》 余霆嵩 https://github.com/TingsongYu/PyTorch_Tutorial

[2]https://www.pythonheidong.com/blog/article/147611/92d69853c6c8f67525d5/