PyTorch: TORCHVISION.TRANSFORMS
变换是常见的图像变换。可以使用Compose将它们链接在一起。此外,还有torchvision.transforms.functional 模块。
函数转换提供对转换的细粒度控制。如果你需要构建一个更复杂的转换管道(例如,在分割任务的情况下),这非常有用。
所有的转换都接受PIL图像,张量图像或批张量图像作为输入。
张量图像是一个具有(C, H, W)形状的张量,其中C是一些通道,H和W是图像的高度和宽度。
Batch of Tensor Images是(B, C, H, W) 形状的张量,其中B是Batch中图像的个数。对这批张量图像应用确定性或随机变换,就能对这批图像的所有图像进行相同的变换。
警告
自从v0.8.0以来,所有的随机转换都使用torch默认的随机生成器来采样随机参数。这是一个向后兼容性破坏更改,用户应该设置随机状态如下:
# Previous versions
# import random
# random.seed(12)
# Now
import torch
torch.manual_seed(17)
请记住,torch随机发生器和Python随机发生器的相同种子不会产生相同的结果。
编写脚本的转换
为了编写转换脚本,请使用torch.nn.Sequential而不是Compose。
transforms = torch.nn.Sequential(
transforms.CenterCrop(10),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
)
scripted_transforms = torch.jit.script(transforms)
确保只使用可脚本化的转换,也就是使用torch.Tensor的转换,不需要lambda函数或PIL.Image。
对于与torch.jit.script一起使用的任何自定义转换,它们应该派生自torch.nn.Module。
Compositions of transforms
CLASS torchvision.transforms.
Compose
(transforms)
将几个变换组合在一起。这个转换不支持torchscript。请看下面的说明。
参数: transforms (Transform对象列表)-要组合的转换列表。
例子
transforms.Compose([
transforms.CenterCrop(10),
transforms.ToTensor(),
])
请注意:为了编写转换脚本,请使用torch.nn。顺序如下。
transforms = torch.nn.Sequential(
transforms.CenterCrop(10),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
)
scripted_transforms = torch.jit.script(transforms)
确保只使用可脚本化的转换,也就是使用torch.Tensor的转换,不需要lambda函数或PIL.Image。
Transforms on PIL Image and torch.*Tensor
CLASS torchvision.transforms.
CenterCrop
(size)
在中心裁剪给定的图像。图像可以是PIL图像或torch Tensor,在这种情况下,它被期望有[…,H, W]形状,其中…表示领先维度的任意数目。
参数: size(sequence或int):裁剪期望的输出大小。如果size是一个int而不是序列(如(h, w)),则生成一个正方形的裁剪(size, size)。如果提供了长度为1的元组或列表,它将被解释为(size[0], size[0])。
CLASS torchvision.transforms.
ColorJitter
(brightness=0, contrast=0, saturation=0, hue=0)
随机改变一个图像的亮度,对比度和饱和度。
参数:
brightness(float或python的元组:float (min, max)) :多大程度上的亮度抖动。从[max(0,1-brightness),1 +brightness]或给定的[min, max]中均匀地选择亮度因子。应该是非负数。
contrast(python的float或元组:float (min, max)):对比度的抖动程度。对比因子从[max(0,1 -contrast),1 +contrast]或给定的[min, max]中统一选择。应该是非负数。
saturation(float或python的元组:float (min, max)):多少抖动饱和度。从[max(0,1 - saturation), 1 + saturation]或给定的[min, max]中均匀地选择saturation_factor。应该是非负数。
hue(python的float或元组:float (min, max)):多少来抖动hue。hue_factor从[-hue, hue]或给定的[min, max]中统一选择。应该有0<= hue <= 0.5或-0.5 <= min <= max <= 0.5。
CLASStorchvision.transforms.
FiveCrop
(size)
将给定的图像裁剪成四个角和中间的裁剪。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
请注意:此转换返回一个图像元组,并且数据集返回的输入和目标数量可能不匹配。下面是如何处理这个问题的示例。
参数: size (sequence或int):裁剪期望的输出大小。如果size是一个int而不是序列(如(h, w)),则生成一个大小为size (size, size)的方形作物。如果提供了长度为1的元组或列表,它将被解释为(size[0], size[0])。
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
CLASS torchvision.transforms.
Grayscale
(num_output_channels=1)
转换图像到灰度。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,3,H, W]形状,其中…表示领先维度的任意数量。
参数: num_output_channels
返回: 输入的灰度图。
如果num_output_channels == 1: 返回的图像是单通道。
如果num_output_channels == 3: 返回的图像是r == g == b的3个通道。
CLASS torchvision.transforms.
Pad
(padding, fill=0, padding_mode='constant')
用给定的“填充”值填充给定的图像。图像可以是PIL图像或torch Tensor,在这种情况下,它被期望有[…,H, W]形状,其中…表示领先维度的任意数目。
参数:
padding(int或元组或列表):每个边界上的填充。如果提供了一个int值,它将被用来填充所有边框。如果提供了长度为2的元组,则分别在左/右和顶部/底部填充。
如果提供了长度为4的元组,则分别为左、上、右和下边框填充。在torchscript模式下,不支持单个int填充,使用一个元组或长度为1:[padding,]的列表。
fill
padding_mode
constant: 具有常量值的垫块,该值由fill指定。
edge: 图像边缘上的最后一个值。
reflect: 在边缘上不重复上次值的图像反射的衬垫。
例如,在反射模式下,两边各有2个元素的填充[1, 2, 3, 4]会得到 [3, 2, 1, 2, 3, 4, 3, 2]。
symmetric: 在边缘上重复最后一个值的映像的衬垫。
例如,对称模式下,两边各有2个元素的填充[1, 2, 3, 4]会得到[2, 1, 1, 2, 3, 4, 4, 3]。
CLASS torchvision.transforms.
RandomAffine
(degrees, translate=None, scale=None, shear=None, resample=0, fillcolor=0)
图像保持中心不变的随机仿射变换。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
参数:
degrees(序列或浮点数或整数):度数的选择范围。如果度数是一个数字,而不是序列(如(min, max)),度数的范围将是(-degrees, +degrees)。设置为0表示取消旋转。
translate
scale(元组,可选):缩放因子间隔,例如(a, b),那么scale将从范围a <= scale <= b中随机抽样。默认情况下将保持原来的scale。
shear(序列或浮动或int,可选):范围的角度选择。如果剪切是一个数字,一个剪切平行于x轴的范围(-shear,+shear)将被应用。否则,如果剪切是一个元组或2个值的列表,在范围内平行于x轴的剪切(shear[0],shear[1])将被应用。否则,如果剪切是一个元组或4个值的列表,x轴剪切(shear[0],shear[1])和y轴剪切(shear[2],shear[3])将被应用。默认情况下不会应用剪切。
resample
fillcolor(元组或int):可选的填充颜色(元组为RGB图像和int为灰度)的区域外的转换输出图像(Pillow>=5.0.0)。张量输入不支持此选项。输出图像中变换外部区域的填充值始终为0。
CLASS torchvision.transforms.
RandomApply
(transforms, p=0.5)
以给定的概率随机应用一系列转换。
请注意:为了编写转换脚本,请使用torch.nn.ModuleList作为输入,而不是转换的list/tuple,如下所示:
transforms = transforms.RandomApply(torch.nn.ModuleList([
transforms.ColorJitter(),
]), p=0.3)
scripted_transforms = torch.jit.script(transforms)
CLASS torchvision.transforms.
RandomCrop
(size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant')
在随机的位置裁剪给定的图像。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
参数:
size
padding (int或序列,可选):图像的每个边框上的可选填充。默认是没有的。如果提供了一个int值,它将被用来填充所有边框。如果提供了长度为2的元组,则分别在左/右和顶部/底部填充。如果提供了长度为4的元组,则分别为左、上、右和下边框填充。在torchscript模式下,不支持单个int填充,使用一个元组或长度为1:[padding,]的列表。
pad_if_needed (boolean):如果图像小于期望的大小,它将填充图像,以避免引发异常。因为裁剪是在填充之后完成的,所以填充看起来是随机偏移的。
fill (int或元组):常量填充的像素填充值。默认值为0。如果一个长度为3的元组,则分别用于填充R、G、B通道。该值仅在padding_mode为常量时使用。
padding_mode
constant: 具有常量值的垫块,该值由fill指定。
edge: 图像边缘上的最后一个值。
reflect: 在边缘上不重复上次值的图像反射的衬垫。
例如,在反射模式下,两边各有2个元素的填充[1, 2, 3, 4]会得到 [3, 2, 1, 2, 3, 4, 3, 2]。
symmetric: 在边缘上重复最后一个值的映像的衬垫。
例如,对称模式下,两边各有2个元素的填充[1, 2, 3, 4]会得到[2, 1, 1, 2, 3, 4, 4, 3]。
CLASS torchvision.transforms.
RandomGrayscale
(p=0.1)
以概率p(默认0.1)随机转换图像为灰度图。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,3,H, W]形状,其中…表示领先维度的任意数量。
参数: p
返回: 输入图像的灰度图,概率为p,不变为概率(1-p)。—输入图像为1通道时,灰度图为1通道。—输入图像为3通道时,灰度图为3通道,r == g == b。
CLASS torchvision.transforms.
RandomHorizontalFlip
(p=0.5)
以给定的概率水平翻转给定的图像。图像可以是PIL图像或torch Tensor,在这种情况下,它被期望有[…,H, W]形状,其中…表示领先维度的任意数目。
参数: p
CLASS torchvision.transforms.
RandomPerspective
(distortion_scale=0.5, p=0.5, interpolation=2, fill=0)
以给定的概率对给定的图像执行随机的透视变换。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
参数:
distortion_scale
p
interpolation(int):插值类型。如果输入是张量,只支持PIL.Image.NEAREST 和PIL.Image.BILINEAR。默认情况下,采用PIL.Image.BILINEAR。
fill (n-tuple或int或float):旋转图像外部区域的像素填充值。如果是int或float,则该值分别用于所有波段。默认值为0。此选项仅适用于枕头>=5.0.0。张量输入不支持此选项。输出图像中变换外部区域的填充值始终为0。
CLASS torchvision.transforms.
RandomResizedCrop
(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=2)
将给定图像随机裁剪为不同的大小和宽高比,然后缩放所裁剪得到的图像为指定的大小;(即先随机采集,然后对裁剪得到的图像缩放为同一大小)。
图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
一个原始尺寸的随机大小(默认值:0.08到1.0)和原始宽高比的随机宽高比(默认值:3/4到4/3)的裁剪被制成。这个裁剪最终被调整到给定的大小。这通常被用于训练Inception网络。
参数:
size (int或sequence):每条边的期望输出大小。如果size是一个int而不是序列(如(h, w)),则输出大小为正方形(size, size)。如果提供了长度为1的元组或列表,它将被解释为(size[0], size[0])。
scale (python的元组:float):被裁剪的原始大小的范围。默认scale=(0.08, 1.0),面积百分比。
0.08意味着在100×100的图像中,最小的crop_img约为28×28(800像素)。
ratio (python的元组:float):被裁剪的原始长宽比的长宽比范围。
interpolation(int):过滤器定义的所需插值枚举。默认是PIL.Image.BILINEAR。如果输入是张量,只支持双PIL.Image.NEAREST, PIL.Image.BILINEAR 和 PIL.Image.BICUBIC。
image = Image.open("./Lena.jpg")
print("原图大小:", image.size)
data1 = transforms.RandomResizedCrop(224)(image)
print("随机裁剪后的大小:", data1.size)
data2 = transforms.RandomResizedCrop(224)(image)
data3 = transforms.RandomResizedCrop(224)(image)
mpl.rcParams['font.sans-serif'] = ['SimHei']
pyplot.subplot(2, 2, 1), pyplot.imshow(image), pyplot.title("原始图像")
pyplot.subplot(2, 2, 2), pyplot.imshow(data1), pyplot.title("转换后的图1")
pyplot.subplot(2, 2, 3), pyplot.imshow(data2), pyplot.title("转换后的图2")
pyplot.subplot(2, 2, 4), pyplot.imshow(data3), pyplot.title("转换后的图3")
pyplot.show()
CLASS torchvision.transforms.
RandomRotation
(degrees, resample=False, expand=False, center=None, fill=None)
按角度旋转图像。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
参数:
degrees(序列或浮点数或整数):度数的选择范围。如果度数是一个数字,而不是序列(如(min, max)),度数的范围将是(-degrees, +degrees)。
resample(int,可选):一个可选的重采样过滤器。有关更多信息,请参阅过滤器。如果省略,或者图像有模式“1”或“P”,它被设置为PIL.Image.NEAREST。如果输入是张量,只支持PIL.Image.NEAREST 和 PIL.Image.BILINEAR。
expand(bool,可选):可选的扩展标志。如果为真,则展开输出,使其足够大以容纳整个旋转后的图像。如果为false或省略,则使输出图像与输入图像相同大小。注意,expand标志假定围绕中心旋转,而没有平移。
center(列表或元组,可选):可选的旋转中心,(x, y)。原点是左上角。默认为图像的中心。
fill(n-tuple或int或float):旋转图像外部区域的像素填充值。如果是int或float,则该值分别用于所有波段。默认为0的所有波段。此选项仅适用于Pillow>=5.2.0。张量输入不支持此选项。输出图像中变换外部区域的填充值始终为0。
CLASS torchvision.transforms.
RandomVerticalFlip
(p=0.5)
以给定的概率垂直翻转给定的图像。图像可以是PIL图像或torch Tensor,在这种情况下,它被期望有[…,H, W]形状,其中…表示领先维度的任意数目。
参数: p
CLASS torchvision.transforms.
Resize
(size, interpolation=2)
将输入图像的大小调整为给定的大小。图像可以是PIL图像或torch Tensor,在这种情况下,它被期望有[…,H, W]形状,其中…表示领先维度的任意数目。
参数:
size(sequence或int):期望的输出大小。如果size是类似(h, w)的序列,则输出size将与此匹配。如果size为int,则图像的较小边缘将与这个数字匹配。也就是说,如果高度>宽度,那么图像将被重新调整为(大小*高度/宽度,大小)。在torchscript模式下不支持单个int填充,使用一个元组或长度为1:[size,]的列表。
interpolation(int,可选):过滤器定义的所需插值enum。默认是PIL.Image.BILINEAR。如果输入是张量,只支持PIL.Image.NEAREST, PIL.Image.BILINEAR 和 PIL.Image.BICUBIC。
CLASS torchvision.transforms.
TenCrop
(size, vertical_flip=False)
Crop the given image into four corners and the central crop plus the flipped version of these (horizontal flipping is used by default).
裁剪给定的图像到四个角和中央裁剪加上翻转的版本(默认使用水平翻转)。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,H, W]形状,其中…表示领先维度的任意数量。
请注意:此转换返回一个图像元组,并且数据集返回的输入和目标数量可能不匹配。下面是如何处理这个问题的示例。
参数:
size(sequence或int):裁剪的期望输出大小。如果size是一个int而不是序列(如(h, w)),则生成一个正方形的裁剪(size, size)。如果提供了长度为1的元组或列表,它将被解释为(size[0], size[0])。
vertical_flip(bool):使用垂直翻转代替水平翻转。
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
CLASS torchvision.transforms.
GaussianBlur
(kernel_size, sigma=(0.1, 2.0))
以随机选择的高斯模糊模糊图像。图像可以是PIL图像或Tensor,在这种情况下,它被期望具有[…,C, H, W]形状,其中…意味着领先维度的任意数量。
参数:
kernel_size(int或sequence):高斯核的大小。
sigma(python的float或元组:float (min, max)):用于创建执行模糊的内核的标准偏差。如果是浮动的,则是固定的。如果它是float (min, max)的元组,则sigma被均匀随机地选择在给定范围内。
Transforms on PIL Image only
CLASS torchvision.transforms.
RandomChoice
(transforms)
应用从列表中随机选取的单个转换。这个转换不支持torchscript。
CLASS torchvision.transforms.
RandomOrder
(transforms)
以随机顺序应用一个转换列表。这个转换不支持torchscript。
Transforms on torch.*Tensor only
CLASS torchvision.transforms.
LinearTransformation
(transformation_matrix, mean_vector)
Transform a tensor image with a square transformation matrix and a mean_vector computed offline.
Given transformation_matrix and mean_vector, will flatten the torch.*Tensor and subtract mean_vector from it which is then followed by computing the dot product with the transformation matrix and then reshaping the tensor to its original shape.
应用:
whitening transformation(白化变换): 假设X是列向量的零中心数据。然后用torch.mm(X.t(), x)计算数据协方差矩阵[dx D],对该矩阵进行SVD,作为transformation_matrix传递。
参数:
transformation_matrix(张量):张量[dx D], D = C x H x W。
mean_vector(张量):张量[D], D = C x H x W。
CLASS torchvision.transforms.
Normalize
(mean, std, inplace=False)
用均值和标准差标准化张量图像。给定n个通道的mean: (mean[1],…,mean[n])和std: (std[1],..,std[n]),该变换将标准化输入ttorch.*Tensor每个通道,即:
output[channel] = (input[channel] - mean[channel]) / std[channel]。
请注意:这个变换不会改变输入张量。
参数:
mean(序列):每个通道的均值序列。
std(序列):每个通道的标准差序列。
inplace(bool,可选):bool使该操作就位。
示例:
transform.ToTensor(),
transform.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))
前面的(0.5,0.5,0.5) 是 R G B 三个通道上的均值, 后面(0.5, 0.5, 0.5)是三个通道的标准差。
注意通道顺序是 R G B ,用过opencv的同学应该知道openCV读出来的图像是 BRG顺序。
这两个tuple数据是用来对RGB 图像做归一化的,如其名称 Normalize 所示,这里都取0.5只是一个近似的操作,实际上其均值和方差并不是这么多,但是就这个示例而言,影响可不计。
如果你用的是自己创建的数据集从头训练,那最好还是要自己统计自己数据集的这两个量:
如果你加载的的是pytorch上的预训练模型,自己只是微调模型;
或者你用了常见的数据集比如VOC或者COCO之类的,但是用的是自己的网络结构,即pytorch上没有可选的预训练模型,那么可以使用一个pytorch上给的通用的统计值:
mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225])。
ToTensor()能够把灰度范围从0~255变换到0.00~1.00之间,而后面的transform.Normalize()则把0-1变换到(-1,1)。
具体地说,对每个通道而言,Normalize执行以下操作:
image=(image-mean)/std
其中mean和std分别通过(0.5,0.5,0.5)和(0.5,0.5,0.5)进行指定。原来的0-1:最小值0则变成(0-0.5)/0.5=-1,而最大值1则变成(1-0.5)/0.5=1。
CLASS torchvision.transforms.
RandomErasing
(p=0.5, scale=(0.02, 0.33), ratio=(0.3, 3.3), value=0, inplace=False)
在图像中随机选择一个矩形区域并删除它的像素。‘Random Erasing Data Augmentation’ by Zhong et al. See https://arxiv.org/abs/1708.04896
参数:
p:执行随机删除操作的概率。
scale:被擦除的区域与输入图像的比例范围。
ratio:抹去面积的长宽比的范围。
value:删除值。默认值为0。如果是单个int,则使用它来清除所有像素。如果一个长度为3的元组,它被用来分别擦除R, G, B通道。如果字符串为' random ',则用随机值删除每个像素。
inplace:布尔值,使此转换就位。默认为False。
CLASS torchvision.transforms.
ConvertImageDtype
(dtype: torch.dtype) → None
将张量图像转换为给定的dtype并相应地缩放值。
参数: dtype(torch.dpython:type):输出所需的数据类型。
请注意:当从较小的整数转换为较大的整数dtype时,最大值不会被精确映射。如果来回转换,这种不匹配将没有影响。
Conversion Transforms
CLASS torchvision.transforms.
ToPILImage
(mode=None)
转换Tensor或ndarray到PIL图像。这个转换不支持torchscript。
转换一个形状为C x H x W的torch.*Tensor或形状为H x W x C的numpy ndarray为PIL图像,同时保留值范围。
参数:
mode(PIL.Image mode):输入数据的颜色空间和像素深度(可选)。如果模式是None(默认):有一些关于输入数据的假设:—如果输入有4个通道,模式被假定为RGBA。-如果输入有3个通道,模式假设为RGB。—如果输入有两个通道,则假设模式为LA。-如果输入有1个通道,模式由数据类型决定(即int, float, short)。
CLASS torchvision.transforms.
ToTensor
转换PIL图像或numpy.ndarray为Tensor。这个转换不支持torchscript。
转换灰度范围在[0,255]内,形状为(H × W × C)的PIL图像或numpy.ndarray为形状 (C x H x W) 取值为[0.0, 1.0]的torch.FloatTensor。
如果PIL图像属于其中一种模式(L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1)或如果numpy.ndarray has dtype = np.uint8
在其他情况下,返回的张量没有标度。
请注意:因为输入图像被缩放到[0.0,1.0],所以在转换目标图像蒙版时不应该使用这个转换。请参阅有关实现图像掩码转换的参考资料。
Generic Transforms
CLASS torchvision.transforms.
Lambda
(lambd)
应用用户定义的lambda作为转换。这个转换不支持torchscript。
参数: lambd(函数):用于转换的Lambda/函数。