03 - Transforms
概念
torchvision.transforms
是PyTorch中的一个模块,是一个工具箱,用于进行图像处理和数据增强的操作。它提供了一系列的转换函数,可以方便地对图像进行预处理、增强或者转换,以满足模型训练或推理的需求。
常见的图像变换包括但不限于:
- 裁剪(Crop)
- 缩放(Resize)
- 翻转(Flip)
- 旋转(Rotation)
- 归一化(Normalization)
- 转换为张量(ToTensor)
这些转换可以通过组合使用来构建一个数据预处理流水线,用于准备训练集或测试集中的图像数据。通过这些转换,可以提高模型的泛化能力、抗扰动能力,并且可以在训练过程中对数据进行增广,以防止过拟合。
Tensor
在PyTorch中,tensor
是一种多维数组,类似于 NumPy 的数组,但具有额外的功能,例如在 GPU 上进行加速计算。tensor
中的数据类型表示了数组中元素的数据类型。PyTorch 提供了多种数据类型的 tensor
,常见的包括:
- torch.float32 或 torch.float: 单精度浮点数。
- torch.float64 或 torch.double: 双精度浮点数。
- torch.float16 或 torch.half: 半精度浮点数。
- torch.int8, torch.int16, torch.int32, torch.int64: 带符号整数,分别占用 8 位、16 位、32 位、64 位。
- torch.uint8: 无符号 8 位整数。
- torch.bool: 布尔型。
每种数据类型都有其特定的用途和性能特征。例如,使用单精度浮点数 torch.float32
可以提高计算速度和节省内存,但可能会损失一定的精度;而使用双精度浮点数 torch.float64
可以获得更高的数值精度,但会占用更多的内存和计算资源。
**Tensor数据类型包装了反向神经网络理论基础需要的参数。**在神经网络中,tensor 数据类型通常用于存储模型的参数(例如权重w和偏置b),并且在训练过程中通过反向传播算法更新这些参数。这些参数包括了神经网络的理论基础,因为它们是网络学习的关键部分。 神经网络的理论基础包括网络的结构(如层的数量、类型和连接方式)、激活函数的选择、损失函数的定义等。然而,这些理论基础通常是通过调整网络参数来实现的,而这些参数正是通过 tensor 数据类型进行存储和操作的。
ToTensor()
transforms.ToTensor()是PyTorch中的一个数据转换函数,用于将PIL图像或NumPy数组转换为张量(tensor)。在深度学习中,图像通常表示为多维数组或张量,因此在将图像输入到神经网络之前,需要将其转换为张量格式。
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
# 用法示例 ->tensor
image_path = "data/train/ants_image/6240329_72c01e663e.jpg"
img = Image.open(image_path)
writer = SummaryWriter("logs")
# 函数的引用?创建自己的工具
tensor_trans = transforms.ToTensor()
tensor_img = tensor_trans(img)
writer.add_image("Tensor_img", tensor_img)
writer.close()
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img = Image.open("images/image1.jpg")
print(img)
trans_toTensor = transforms.ToTensor()
img_tensor = trans_toTensor(img)
writer.add_image("ToTensor", img_tensor)
writer.close()
Normalize()
transforms.Normalize()是PyTorch中的一个数据转换函数,用于对张量数据进行归一化操作。在深度学习中,数据的归一化通常是一个重要的预处理步骤,可以帮助提高模型的训练稳定性和收敛速度。
transforms.Normalize(mean, std)执行以下操作: 将每个通道的均值减去指定的均值(mean)。 将每个通道的标准差除以指定的标准差(std)。
这样可以将数据的分布调整为以0为中心,标准差为1的分布,使得模型更容易学习到有效的特征,并且可以减少数据间的尺度差异对模型训练的影响。
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img = Image.open("images/image1.jpg")
print(img)
# ToTensor
trans_toTensor = transforms.ToTensor()
img_tensor = trans_toTensor(img)
writer.add_image("ToTensor", img_tensor)
# Normalize
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize", img_norm, 1)
writer.close()
Resize()
transforms.Resize()是PyTorch中的一个数据转换函数,用于调整图像的大小。在深度学习中,图像的大小通常需要与模型的输入大小相匹配,以便于正确地输入到模型中进行训练或推理。
具体来说,transforms.Resize(size)执行以下操作:
将PIL图像的尺寸调整为指定的大小。保持图像的宽高比不变,根据所提供的 size 参数进行缩放或裁剪。
size 参数可以是一个整数,也可以是一个包含两个整数的元组,分别表示新图像的宽度和高度。如果提供的 size 是一个整数,则将图像的较小边缩放到这个大小,保持宽高比不变。
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img = Image.open("images/image1.jpg")
print(img)
# ToTensor
trans_toTensor = transforms.ToTensor()
img_tensor = trans_toTensor(img)
writer.add_image("ToTensor", img_tensor)
# Normalize
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize", img_norm, 1)
# Resize
print(img.size)
trans_resize = transforms.Resize((512,512))
# 变换后还是PIL Image
img_resize = trans_resize(img)
print(img_resize.size)
img_resize = trans_toTensor(img_resize)
writer.add_image("Resize", img_resize, 0)
writer.close()
Compose()
transforms.Compose() 是 PyTorch 中的一个数据转换函数,用于将多个数据转换操作组合成一个数据预处理流水线。在深度学习中,通常需要对输入数据进行多个预处理步骤,例如图像的缩放、裁剪、归一化等,transforms.Compose() 可以方便地将这些操作依次应用于输入数据。
具体来说,transforms.Compose(transforms) 接受一个由数据转换操作组成的列表或元组,并返回一个将这些操作依次应用于输入数据的组合转换函数。在应用组合转换函数时,将按照列表中的顺序依次应用每个转换操作。
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img = Image.open("images/image1.jpg")
print(img)
# ToTensor
trans_toTensor = transforms.ToTensor()
img_tensor = trans_toTensor(img)
writer.add_image("ToTensor", img_tensor)
# Normalize
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize", img_norm, 1)
# Resize
print(img.size)
trans_resize = transforms.Resize((512,512))
# 变换后还是PIL Image
img_resize = trans_resize(img)
print(img_resize.size)
img_resize = trans_toTensor(img_resize)
writer.add_image("Resize", img_resize, 0)
# Compose “封装流水线”
# 若只传入一个参数,则以最短边进行放缩
trans_resize_2 = transforms.Resize(512)
trans_compose = transforms.Compose([trans_resize_2, trans_toTensor])
img_resize_2 = trans_compose(img)
writer.add_image("Resize2", img_resize_2, 0)
writer.close()
可以将 transforms.Compose() 理解为封装了数据预处理流水线。在深度学习中,数据预处理通常需要执行多个步骤,例如缩放、裁剪、旋转、归一化等。这些步骤按照一定的顺序应用于输入数据,以便于将数据准备好用于模型的训练或推理。
RandomCrop()
transforms.RandomCrop() 是 PyTorch 中的一个数据转换函数,用于对图像进行随机裁剪操作。在深度学习中,随机裁剪是一种常见的数据增强技术,可以通过在训练过程中对图像进行随机裁剪来增加数据的多样性,从而提高模型的泛化能力。
具体来说,transforms.RandomCrop(size) 会在图像中随机选择一个矩形区域,并将其裁剪到指定的大小。裁剪的位置是随机选择的,但是裁剪的区域大小是由 size 参数指定的。
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img = Image.open("images/image1.jpg")
print(img)
# ToTensor
trans_toTensor = transforms.ToTensor()
img_tensor = trans_toTensor(img)
writer.add_image("ToTensor", img_tensor)
# Normalize
print(img_tensor[0][0][0])
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize", img_norm, 1)
# Resize
print(img.size)
trans_resize = transforms.Resize((512,512))
# 变换后还是PIL Image
img_resize = trans_resize(img)
print(img_resize.size)
img_resize = trans_toTensor(img_resize)
writer.add_image("Resize", img_resize, 0)
# Compose “封装流水线”
trans_resize_2 = transforms.Resize(512)
trans_compose = transforms.Compose([trans_resize_2, trans_toTensor])
img_resize_2 = trans_compose(img)
writer.add_image("Resize2", img_resize_2, 1)
# RandomCrop
trans_random = transforms.RandomCrop(512)
trans_compose_2 = transforms.Compose([trans_random, trans_toTensor])
for i in range(10):
img_random = trans_compose_2(img)
writer.add_image("RandomCrop", img_random, i)
writer.close()