【Python】数据预处理——torchvision.transforms
文章目录
- 【Python】数据预处理——torchvision.transforms
-
- 1. 介绍
- 2. 举例说明
-
- 2.1 导入所需包
- 2.2 class torchvision.transforms.Compose(transforms)
- 2.3 class torchvision.transforms.ToTensor
- 2.4 class torchvision.transforms.ToPILImage
- 2.5 class torchvision.transforms.Normalize(mean, std)
- 2.6 class torchvision.transforms.CenterCrop(size)
- 2.7 class torchvision.transforms.RandomCrop(size, padding=0)
- 2.8 class torchvision.transforms.RandomHorizontalFlip()
- 2.9 class torchvision.transforms.RandomResizedCrop(size, interpolation=2)
- 2.9 class torchvision.transforms.Pad(padding, fill=0)
- 3. 参考
1. 介绍
首先,在torchvision transform库中,大致有以下几类方法:
- 1)定义一系列预处理的操作:
- class torchvision.transforms.Compose(transforms)
- 2)各种数据类型的转换:
- class torchvision.transforms.ToTensor
- class torchvision.transforms.ToPILImage
- 3)对Tensor进行标准化:
- class torchvision.transforms.Normalize(mean, std)
- 4)对PIL.Image进行变换:
- class torchvision.transforms.CenterCrop(size)
- class torchvision.transforms.RandomCrop(size, padding=0)
- class torchvision.transforms.RandomHorizontalFlip()
- class torchvision.transforms.RandomResizedCrop(size, interpolation=2)
- class torchvision.transforms.Pad(padding, fill=0)
2. 举例说明
2.1 导入所需包
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
2.2 class torchvision.transforms.Compose(transforms)
这个类将多个变换方式结合在一起。
- 参数:各个变换的实例对象
transform = transforms.Compose([
transforms.RandomCrop(32, padding=4), #先四周填充0,在吧图像随机裁剪成32*32
transforms.RandomHorizontalFlip(), #图像一半的概率翻转,一半的概率不翻转
transforms.RandomRotation((-45,45)), #随机旋转
transforms.ToTensor(),
transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225)), #R,G,B每层的归一化用到的均值和方差
])
这里在执行的时候会按照顺序执行:
- 先执行transforms.RandomCrop(32, padding=4);
- 最后执行transforms.Normalize((0.4914, 0.4822, 0.4465), (0.229, 0.224, 0.225))。
所以这里一定要注意类型的问题,这些方法有的使用的是Tensor类型,有些是PIL.Image的类型。具体的可以看后面的使用。
2.3 class torchvision.transforms.ToTensor
这个类把一个取值范围是 [0,255] 的 PIL.Image 或者shape为(H,W,C)的numpy.ndarray,转换成形状为[C,H,W],取值范围是 [0,1.0] 的torch.FloadTensor。
'''输入代码'''
data = np.random.randint(0, 255, size=300)
img = data.reshape(10,10,3)
print(img.shape)
img_tensor = transforms.ToTensor()(img) # 转换成tensor
print(img_tensor.shape)
'''输出结果'''
(10, 10, 3)
torch.Size([3, 10, 10])
2.4 class torchvision.transforms.ToPILImage
将shape为(C,H,W)的Tensor或shape为(H,W,C)的numpy.ndarray 转换成PIL.Image,值不变(注意与Totensor的区别)。还有要注意是这个方法好像只支持uint8的数据类型。
'''输入代码'''
data = np.random.randint(0, 255, size=300, dtype='uint8')
img = data.reshape(10,10,3)
print(img.shape)
img_PIL = transforms.ToPILImage()(img)
print(img_PIL.size)
print(img_PIL.mode)
'''输出结果'''
(10, 10, 3)
(10, 10)
RGB
2.5 class torchvision.transforms.Normalize(mean, std)
给定均值:(R,G,B) 方差:(R,G,B),将会把Tensor正则化。即:Normalized_image=(image-mean)/std。
- 这个就不解释了,输入mean和std,直接执行公式Normalized_image=(image-mean)/std。
- 但是要注意的是这个处理的数据要求是Tensor类型的。
因此在使用class torchvision.transforms.Compose(transforms)的时候要注意将这个类放在
class torchvision.transforms.ToTensor 的后面。
2.6 class torchvision.transforms.CenterCrop(size)
这个类将给定的PIL.Image进行中心切割,得到给定的size。
- size可以是tuple (target_height, target_width)。
- size也可以是一个Integer,在这种情况下,切出来的图片的形状是正方形。
'''输入代码'''
transform = transforms.Compose([transforms.CenterCrop(500), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
'''输出'''
(606, 910, 3)
torch.Size([3, 500, 500])
2.7 class torchvision.transforms.RandomCrop(size, padding=0)
这个类切割中心点的位置随机选取。size可以是tuple也可以是Integer。
- 这个和上面的那个方法比较类似,但是这个切的比较随机了,切好的图片的中心点是从原图中随机选择的,当然选择的中心点肯定是可以保证切出来的图片满足size的要求的。
'''输入代码’'''
transform = transforms.Compose([transforms.RandomCrop(500, padding=100), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
'''输出结果'''
(606, 910, 3)
torch.Size([3, 500, 500])
多切几次,获得的图像是不同的,但是大小相同。
2.8 class torchvision.transforms.RandomHorizontalFlip()
这个类是:随机水平翻转给定的PIL.Image,概率为0.5。即:一半的概率翻转,一半的概率不翻转。
'''输入代码,
这个可以多运行几次,你会发现不一样的
'''
transform = transforms.Compose([transforms.RandomHorizontalFlip(), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
'''输出'''
(606, 910, 3)
torch.Size([3, 606, 910])
2.9 class torchvision.transforms.RandomResizedCrop(size, interpolation=2)
这个函数是可以说是crop和resize的合体。
- 先将给定的PIL.Image随机切,
- 然后再resize成给定的size大小。这个函数已经改成了RandomResizedCrop,以前的RandomSizedCrop已经被弃用了。
这里是使用插值的方式将随机切的图片填充成你需要的大小,但是size只能是一个整数,也就是说只能切出来一个正方形的。
'''输入代码'''
transform = transforms.Compose([transforms.RandomResizedCrop(500, interpolation=1), transforms.ToTensor()])
image = Image.open('./data/image.jpg')
print(np.array(image).shape)
img1 = transform(image)
print(img1.shape)
plt.imshow(np.transpose(img1, (1, 2, 0)))
plt.show()
'''输出结果'''
(606, 910, 3)
torch.Size([3, 500, 500])
2.9 class torchvision.transforms.Pad(padding, fill=0)
transforms.Pad class torchvision.transforms.Pad(padding, fill=0, padding_mode=‘constant’)
- 功能:对图像进行填充
- 参数:
- padding-(sequence or int, optional),此参数是设置填充多少个pixel。
- 当为int时,图像上下左右均填充int个,例如padding=4,则上下左右均填充4个pixel,若为3232,则会变成4040;
- 当为sequence时,若有2个数,则第一个数表示左右扩充多少,第二个数表示上下的。当有4个数时,则为左,上,右,下。
- fill-(int or tuple) 填充的值是什么(仅当填充模式为constant时有用)。
- int时,各通道均填充该值,
- 当长度为3的tuple时,表示RGB通道需要填充的值。
- padding_mode- 填充模式,这里提供了4种填充模式,
- constant,常量。
- edge,按照图片边缘的像素值来填充。
- reflect
- symmetric
- padding-(sequence or int, optional),此参数是设置填充多少个pixel。
3. 参考
【1】https://blog.csdn.net/kejizuiqianfang/article/details/88947790