torchvision 模块包含常用的数据集,模型建构,图像变换算法,分别是torchvision.datasets,torchvision.models,torchvision.transforms。本次主要学习torchvision.transforms对数据集进行预处理。
transforms.Compose() 用于整合一系列的图像变换函数,将图片按照 Compose() 中的顺序依次处理。torch.nn.Sequential() 与 transforms.Compose() 起到相同的功能。torch.nn.Sequential() 和 torch.jit.script() 结合来导出模型。
'''Compose'''
transform1 = transforms.Compose([
transforms.CenterCrop(10),
transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),
])
'''Sequential'''
transform2 = 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)
大多数的图像变换函数图像可以是 PIL 或 tensor 类型,部分函数只接受 PIL 或只接受 tensor 。可以使用 transforms.ToPILImage() 和 transforms.ToTensor 进行类型转换。
# 读取图片
from PIL import Image
from torchvision import transforms as T
img = Image.open('C:\\Users\\myt\\Desktop\\test.png') # (400 * 300)
img.show()
以图像中心为中心点,将图片裁剪成指定的大小。如果输入图像尺寸小于指定的输出的大小,则在图像的边界进行”填0“,之后再进行裁剪。如果是 torch.Tensor 类型则大小为 […, H, W]。
size(sequence or int): 裁剪后的尺寸大小
输入为一个 int 型,输出 (size, size) 图像;输入为长度1的 sequence 时,输出 (size[0], size[0]) ;输入为 (h, w) ,输出为 (h, w)。
# CenterCrop
imgCC = T.CenterCrop((128, 256)).forward(img)
imgCC.show()
imgCC.save('C:\\Users\\myt\\Desktop\\imgcc.png')
print(imgCC.size)
随机改变图像的亮度,对比度,饱和度,色调。如果是 torch.Tensor 类型则大小为 […, H, W]。
brightness (float or tuple of python:float (min, max)) :[max(0, 1-brightness), 1+brightness] 或 [min, max] 随机选择的非负数。
contrast (float or tuple of python:float (min, max)) :[max(0, 1-contrast), 1+contrast] 或 [min, max] 随机选择的非负数。
saturation (float or tuple of python:float (min, max)) :[max(0, 1-saturation), 1+saturation] 或 [min, max] 随机选择的非负数。
hue (float or tuple of python:float (min, max)) :[-hue, hue] 或 [min, max] 随机选择,且 0<=hue<=0.5或-0.5<=min<=max<=0.5。
# ColorJitter(brightness=0, contrast=0, saturation=0, hue=0)
imgCJ = T.ColorJitter(brightness=0.5, hue= 0.3).forward(img)
imgCJ.show()
imgCJ.save('C:\\Users\\myt\\Desktop\\imgcj.png')
print(imgCJ.size)
分别裁剪图像的四个角和中心。size(sequence or int): 裁剪的尺寸大小,输入为一个 int 型,输出 (size, size) 图像;输入为长度1的 sequence 时,输出 (size[0], size[0]) ;输入为 (h, w) ,输出为 (h, w)。
# FiveCrop
imgFC1, imgFC2, imgFC3, imgFC4, imgFC5 = T.FiveCrop(size=(64, 64))(img)
plot([imgFC1, imgFC2, imgFC3, imgFC4, imgFC5])
print(imgFC1.size)
分别裁剪图像的四个角和中心,再将五张裁剪的图片进行翻转,默认是水平翻转。
# Resize
(TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7, TC8, TC9) = T.TenCrop(size=64, vertical_flip=True)(img)
plot([TC0, TC1, TC2, TC3, TC4])
plot([TC5, TC6, TC7, TC8, TC9])
将图像转换为灰度图像。如果是 torch.Tensor 类型则大小为 […, 3, H, W]。
num_output_channels(int)-(1 or 3): 输出图像通道数,当”3“时则三通道R=G=B。
# Grayscale(num_output_channels)
imgGS = T.Grayscale(1)(img)
imgGS.show()
imgGS.save('C:\\Users\\myt\\Desktop\\imgcj.png')
print(imgGS.size)
将图片所有的边界填充上 padding 像素值。如果是 torch.Tensor 类型则大小为 […, H, W]。
# Pad
imgPd = T.Pad(padding=5, fill=125 ,padding_mode='constant')(img)
imgPd.show()
imgPd.save('C:\\Users\\myt\\Desktop\\imgPd.png')
print(imgPd.size)
transforms.RandomAffine(degrees, translate=None, scale=None, shear=None, interpolation=
图像随机仿射变换,保持图像中心不变。如果是 torch.Tensor 类型则大小为 […, H, W]。
# RandomAffine
affine_transfomer = T.RandomAffine(degrees=(30,70), translate=(0.1, 0.3), scale=(0.5, 0.75) ,shear=30, fill=(255, 255, 0))
imgAF = affine_transfomer(img)
imgAF.show()
imgAF.save('C:\\Users\\myt\\Desktop\\imgAF.png')
imgAF.size
按照给定的概率,随机应用一系列的图像变换函数。
# RandomApply
applier = T.RandomApply(transforms=[T.RandomCrop(size=(64, 64)), T.ColorJitter(brightness=0.5, hue=0.3), T.CenterCrop((128, 256))], p=0.25)
transformed_imgs = [applier(orig_img) for _ in range(4)]
plot(transformed_imgs)
transforms.RandomCrop(size, padding=None, pad_if_needed=False, fill=0, padding_mode=‘constant’): 随机位置裁剪图像,如果是 torch.Tensor 类型则大小为 […, H, W]。
# RandomCrop
imgRC = T.RandomCrop(size=(128, 128))(img)
imgRC.show()
imgRC.save('C:\\Users\\myt\\Desktop\\imgRC.png')
imgRC.size
按照给定的概率,随机将图片转化为灰度图像。如果是 torch.Tensor 类型则大小为 […, 3, H, W]。
# RandomGrayscale
Grayscale = T.RandomGrayscale(p=0.25)
transformed_imgs = [Grayscale(orig_img) for _ in range(4)]
plot(transformed_imgs)
print(Grayscale(orig_img).size)
按照给定的概率,随机水平翻转图像。如果是 torch.Tensor 类型则大小为 […, H, W]。
# RandomHorizontalFlip
hfilpper = T.RandomHorizontalFlip(p=0.25)
transformed_imgs = [hfilpper(orig_img) for _ in range(4)]
plot(transformed_imgs)
按照给定的概率,随机垂直翻转图像。如果是 torch.Tensor 类型则大小为 […, H, W]。
# RandomVerticalFlip
vfilpper = T.RandomVerticalFlip(p=0.25)
transformed_imgs = [vfilpper(orig_img) for _ in range(4)]
plot(transformed_imgs)
torchvision.transforms.RandomPerspective(distortion_scale=0.5, p=0.5, interpolation=
# RandomPerspective
perspective_transformer = T.RandomPerspective(distortion_scale=0.6, p=0.5)
perspective_imgs = [perspective_transformer(orig_img) for _ in range(3)]
plot(perspective_imgs)
torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=
# RandomResizedCrop
resize_cropper = T.RandomResizedCrop(size=(64,64), scale=(0.08,1.0), ratio=(0.75, 1.33))
resize_cropp_imgs = [resize_cropper(orig_img) for _ in range(4)]
plot(resize_cropp_imgs)
torchvision.transforms.RandomRotation(degrees, interpolation=
# RandomRotation
imgRR = T.RandomRotation(degrees=(0, 30), center=((int(img.size[0]/3), int(img.size[1]/3))), expand=True)(img)
imgRR.show()
imgRR.save('C:\\Users\\myt\\Desktop\\imgRR.png')
print(imgRR.size)
torchvision.transforms.Resize(size, interpolation=
# Resize
imgRs = T.Resize(size=150, max_size=160)(img)
imgRs.show()
imgRs.save('C:\\Users\\myt\\Desktop\\imgRs.png')
imgRs.size
结果:(160, 120)
原图像 400×300,根据 size 变为 (150×400/300, 150) = (200, 150),其中长边 200 超过max_size,所以按比例修改为 (160, 160×150/200) = (160, 120)。
使用高斯滤波器进行图像模糊,高斯滤波器的参数随机。如果是 torch.Tensor 类型则大小为 […, C, H, W]。
# GaussianBlur
imgGB = T.GaussianBlur(kernel_size=(5, 9), sigma=(0.1, 5))
imgGB_imgs = [imgGB(orig_img) for _ in range(4)]
plot(imgGB_imgs)
以给定的概率随机地插入给定图像的颜色。如果是 torch.Tensor 类型则大小为 […, 1or3, H, W]。
# RandomInvert
imgRI = T.RandomInvert(p=0.3)
imgRI_imgs = [imgRI(orig_img) for _ in range(3)]
plot(imgRI_imgs)
通过减少每个颜色通道的比特数,以给定的概率随机地对图像进行贴图。如果图像是torch Tensor,它应该是 torch.uint8 类型的大小为 […, 1or3, H, W],如果img是PIL图像,预计它的模式是 "L "或 “RGB”。
# RandomPosterize(bits,p=0.5)
imgRP = T.RandomPosterize(bits=2, p=0.6)
imgRP_imgs = [imgRP(orig_img) for _ in range(3)]
plot(imgRP_imgs)
通过反转所有高于阈值的像素值,以给定的概率随机地晒出图像。如果图像是torch Tensor,它的大小为 […, 1or3, H, W],如果img是PIL图像,预计它的模式是 "L "或 “RGB”。
# RandomSolarize
imgRS = T.RandomSolarize(threshold = 192.0)
imgRS_imgs = [imgRS(orig_img) for _ in range(2)]
plot(imgRS_imgs)
以给定的概率随机调整图像的锐度。如果图像是torch Tensor,它的大小为 […, 1or3, H, W]。
# RandomAdjustSharpness
imgRAS = T.RandomAdjustSharpness(sharpness_factor=2,p=1)(img)
imgRAS.show()
imgRAS.save('C:\\Users\\myt\\Desktop\\imgRAS.png')
以一个给定的概率随机地对给定图像的像素进行最大化对比度操作。如果图像是torch Tensor,它的大小为 […, 1or3, H, W]。
# RandomAutocontrast
imgRA = T.RandomAutocontrast(p=1)(img)
imgRA.show()
imgRA.save('C:\\Users\\myt\\Desktop\\imgRA.png')
以给定的概率随机对图像进行直方图均衡化。如果图像是torch Tensor,它的大小为 […, 1or3, H, W]。
# RandomEqualize
orig_img = Image.open('C:\\Users\\myt\\Desktop\\test3.jpg')
imgRE = T.RandomEqualize(p=1)
imgRE_imgs = [imgRE(orig_img) for _ in range(1)]
plot(imgRE_imgs)
使用均值和标准差对 torch.tensor 图像进行归一化。这个图像变换不支持 PIL
# Normalize
img = Image.open('C:\\Users\\myt\\Desktop\\test.png')
img_tensorf = T.ToTensor()(img)
img_Norm = T.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])(img_tensorf)
将 torch.tensor 的 C×H×W 图像或 ndarray 的 H×W×C 图像转换为 PIL图像。
import torchvision.io as TI
img = TI.read_image('C:\\Users\\myt\\Desktop\\test.jpg')
print(img.shape)
imgI = T.ToPILImage()(img)
imgI.show()
imgI.save('C:\\Users\\myt\\Desktop\\imgI.png')
将 PIL 图像或 ndarray 的 H×W×C 图像转换为 torch.tensor 的 C×H×W 图像。PIL 模式为 **(L, LA, P, I, F, RGB, YCbCr, RGBA, CMYK, 1) **,ndarray 是 np.unit8。
# ToTensor
img = Image.open('C:\\Users\\myt\\Desktop\\test.png')
print(img.size)
imgT = T.ToTensor()(img)
print(imgT.shape)
结果:(400, 300);torch.Size([3, 300, 400])
AutoAugment 是一种常见的数据增强技术,可以提高图像分类模型的准确性。虽然数据增强策略与其训练的数据集直接相关,但经验研究表明,ImageNet 策略在应用于其他数据集时能提供显著的改进。在 TorchVision 中,我们实现了在以下数据集上学习的3个策略。ImageNet、CIFAR10 和 SVHN。新的变换可以独立使用,也可以与现有的 transform 混合使用。
其中主要有三个成员 AutoAugmentPolicy.CIFAR10、AutoAugmentPolicy.IMAGENET、AutoAugmentPolicy.SVHN 与 AutoAugment 联用。
# AutoAugmentPolicy
policies = [T.AutoAugmentPolicy.CIFAR10, T.AutoAugmentPolicy.IMAGENET, T.AutoAugmentPolicy.SVHN]
augmenters = [T.AutoAugment(policy) for policy in policies]
imgs = [
[augmenter(orig_img) for _ in range(4)]
for augmenter in augmenters
]
row_title = [str(policy).split('.')[-1] for policy in policies]
plot(imgs, row_title=row_title)
RandAugment 是一种简单的高性能数据增强技术,可以提高图像分类模型的准确性。
# RandAugment
augmenter = T.RandAugment()
imgs = [augmenter(orig_img) for _ in range(4)]
plot(imgs)
TrivialAugmentWide 是一种独立于数据集的数据增强技术,可以提高图像分类模型的准确性。
# TrivalAugmentWide
augmenter = T.TrivialAugmentWide()
imgs = [augmenter(orig_img) for _ in range(4)]
plot(imgs)
torchvision.transforms.functrional 模块提供的函数形式的图像变化,可以让用户自定图像变换类。
# Functional Transform
import torchvision.transforms.functional as TF
import random
class MyRotationTransform:
"""Rotate by one of the given angles."""
def __init__(self, angles):
self.angles = angles
def __call__(self, x):
angle = random.choice(self.angles)
return TF.rotate(x, angle)
rotation_transform = MyRotationTransform(angles=[-30, -15, 0, 15, 30])
transforms = T.Compose(
[MyRotationTransform((30,60)),
T.GaussianBlur(kernel_size=(5, 9), sigma=(0.1, 5)),
T.CenterCrop(size=(256, 128))
])
imgMT = transforms(img)
imgMT.show()
imgMT.save('C:\\Users\\myt\\Desktop\\imgMT.png')