transforms.yp是一个工具箱
就是将一个特定格式的图片经过这个工具的到想要的变换
Tensor数据类型
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms
writer = SummaryWriter("logs")
img = Image.open("images/微信图片_20250711193055.jpg")
print(img)
#ToTensor
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
writer.add_image("ToTensor", img_tensor)
#Normalize
trans_norm = transforms.Normalize([0.5, 0.5, 0.5], [0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
writer.add_image("Normalize", img_norm)
#Resize
print(img.size)
trans_resize = transforms.Resize((512, 512))
img_resize = trans_resize(img)
print(img_resize)
img_resize = trans_totensor(img_resize)
writer.add_image("Resize", img_resize,1)
#Compose - resize - 2
trans_resize_2 = transforms.Resize((512, 512))
trans_compose = transforms.Compose([trans_resize_2, trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image("Compose", img_resize_2,2)
#RandomCrop
trans_random = transforms.RandomCrop(512,1024)
trans_compose_2 = transforms.Compose([trans_random,trans_totensor])
for i in range(10):
img_crop = trans_compose_2(img)
writer.add_image("RandomCropHW", img_crop,i)
writer.close()
transforms
是 torchvision
的一个模块,专门用来做 图片的预处理和数据增强。
核心用法:
from torchvision import transforms
transform = transforms.ToTensor()
image = Image.open('xxx.jpg') # PIL Image
tensor_image = transform(image) # 转成 Tensor
常用的组合写法:
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
])
image = Image.open('xxx.jpg')
tensor_image = transform(image)
transforms.Compose()
可以把多个预处理步骤按顺序连接起来,比如缩放、裁剪、转 Tensor 等。
输入:PIL Image(或 numpy ndarray)
输出:FloatTensor,shape 为 [C, H, W],像素值范围变成 [0.0, 1.0]
转换细节:
RGB 图片:shape (H, W, 3)
➡️ (3, H, W)
像素值:0-255 的 uint8 ➡️ 浮点数 0-1 之间
例子:
from PIL import Image
from torchvision import transforms
img = Image.open('xxx.jpg')
tensor = transforms.ToTensor()(img)
print(tensor.shape) # torch.Size([3, H, W])
print(tensor.max(), tensor.min()) # tensor.max() 应该接近 1.0,min() 接近 0.0
Tensor 就是 PyTorch 的核心数据结构,类似于 NumPy 的 ndarray,但它具备 GPU 加速、自动求导 的能力。
功能 | 普通数组(如 numpy) | Tensor |
---|---|---|
CPU 运算 | ✅ 支持 | ✅ 支持 |
GPU 运算 | ❌ 不支持 | ✅ 支持 |
自动求导(梯度计算) | ❌ 不支持 | ✅ 支持 |
深度学习框架兼容性 | ❌ 基础数学计算 | ✅ 完全兼容 PyTorch |
主要原因:
高效: PyTorch 的训练推理只能用 Tensor,尤其是 GPU 运算
梯度计算: Tensor 支持 requires_grad=True
,训练模型时自动求导
统一数据接口: 图片转成 Tensor 后,数据可以无缝送入 DataLoader
、模型训练
简单例子:
import torch a = torch.tensor([[1.0, 2.0], [3.0, 4.0]], requires_grad=True)
b = a * 2
c = b.mean()
c.backward()
print(a.grad) # 自动求导,得到梯度
问题 | 精炼回答 |
---|---|
transforms怎么用 | 用 Compose 串联多个预处理方法,用 ToTensor 把图片转成 FloatTensor,范围 0-1,格式 [C, H, W] |
为什么要 Tensor | Tensor 支持 GPU 运算、自动求导、直接送入模型训练,是 PyTorch 的“标配数据类型” |
transforms.Compose
是什么?Compose
的作用:将一系列图片预处理操作“打包”成一个整体,一次性执行多个转换。
使用场景:数据预处理步骤往往不止一条,比如:
resize 调整图片大小
center crop 居中裁剪
ToTensor 转 Tensor
Normalize 标准化
用 Compose
可以这样串起来:
from torchvision import transforms
transform = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5], std=[0.5])
])
执行逻辑:Compose
会 按顺序 对图片执行这些操作。
比如:
from PIL import Image
img = Image.open("xxx.jpg")
img = transform(img) # 按顺序执行 Resize ➡️ ToTensor ➡️ Normalize
简单理解:Compose 就是一个“流程线”,把多个变换打包成一个函数。
transforms.Normalize
是什么?将图片的每个通道(通常是 RGB 三个通道)按均值和标准差进行归一化,让数据符合标准正态分布(均值0,标准差1),便于模型更快收敛、训练更稳定。
transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
mean
和 std
分别对应 每个通道的均值和标准差
例如 RGB 三通道,就填 [mean_R, mean_G, mean_B]
和 [std_R, std_G, std_B]
假设输入图片的像素值已经通过 ToTensor()
转为 [0,1] 的 Tensor,Normalize()
会:
每个像素先减去 mean
再除以 std
最终得到既可以有负数也可以大于1的 标准化 Tensor
常见 ImageNet 预训练模型标准化参数:
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
这些 mean/std 来自于 ImageNet 数据集整体统计值。
目的 | 解释 |
---|---|
加速模型收敛 | 数据归一化后能避免某些特征“值特别大”,训练更平滑 |
特征居中 | 均值变成0,避免偏移现象 |
兼容预训练模型 | 训练和推理保持一致(不归一化直接喂模型会效果很差!) |
from torchvision import transforms
from PIL import Image
transform = transforms.Compose([
transforms.Resize((224,224)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.485,0.456,0.406], std=[0.229,0.224,0.225])
])
img = Image.open('cat.jpg')
tensor = transform(img)
print(tensor.shape) # torch.Size([3, 224, 224])
print(f"最大值:{tensor.max()}, 最小值:{tensor.min()}")
模块 | 功能 | 举例说明 |
---|---|---|
ToTensor() |
转为 Tensor,归一化到 [0,1] | RGB 图片 ➡️ Tensor |
Normalize() |
标准化到均值0方差1 | 减均值除方差 |
transforms.Resize
是什么?Resize
用于 调整图片大小,不论你的原图是啥尺寸,它都可以帮你按指定方式变成固定尺寸,方便送入神经网络训练或推理。
统一输入大小:神经网络通常要求输入固定尺寸(比如 ResNet 要 224×224)
降低运算量:原图太大训练成本高
数据增强的一部分:Resize 搭配其他 transform 使用效果更佳
from torchvision import transforms
transform = transforms.Resize((224, 224))
效果:
无论输入什么尺寸,强制缩放到 224x224,保持 [H, W]
transform = transforms.Resize(224)
效果:
按短边缩放为 224,长边按比例缩放,保持长宽比不变
例子:
输入图片 300×500 ➡️ 输出 224×374
输入图片 1000×800 ➡️ 输出 224×179
Resize(size, interpolation=InterpolationMode.BILINEAR, max_size=None, antialias=None)
size
: (H, W) 或 单个 int
interpolation
: 插值算法(默认 BILINEAR)
max_size
: 当 size 是单个整数时,可以控制最大边长
antialias
: 是否使用抗锯齿(PyTorch 2.0 起推荐)
模式 | 说明 |
---|---|
InterpolationMode.BILINEAR |
双线性插值(默认,平滑效果好) |
InterpolationMode.NEAREST |
最近邻(速度快但不平滑) |
InterpolationMode.BICUBIC |
三次样条插值(更平滑但慢) |
例子:
from torchvision.transforms import InterpolationMode
transform = transforms.Resize((128, 128), interpolation=InterpolationMode.BICUBIC)
from torchvision import transforms
from PIL import Image
img = Image.open('dog.jpg')
transform = transforms.Compose([
transforms.Resize((128, 128)),
transforms.ToTensor()
])
tensor_img = transform(img)
print(tensor_img.shape) # torch.Size([3, 128, 128])
功能 | 说明 |
---|---|
Resize((H, W)) |
直接缩放到 H×W, 强行拉伸 |
Resize(H) |
短边变成 H, 长边等比例缩放 |
interpolation |
控制缩放质量 |
常配合 | 通常和 ToTensor() 、Normalize() 一起使用 |
四、RandomCrop
transforms.RandomCrop
是什么?随机裁剪图片的一块区域
在训练时引入随机性,提升模型对图片位置、特征分布的鲁棒性(抗干扰能力)
和 Resize
不同,RandomCrop
不是缩放,而是“剪一块下来”
from torchvision import transforms
transform = transforms.RandomCrop(size=(224, 224))
效果:
输入图片会随机裁剪出一个 224×224 的小区域,丢弃剩下的部分。
如果图片尺寸小于裁剪区域,会报错。
通常搭配 Resize
用于先缩放再裁剪:
transform = transforms.Compose([
transforms.Resize(256), # 确保图片至少256的短边
transforms.RandomCrop(224), # 裁剪224×224的区域
transforms.ToTensor()
])
典型 ImageNet 标配套路:先Resize到256 ➡️ 再随机裁剪224
RandomCrop(size, padding=0, pad_if_needed=False, fill=0, padding_mode='constant')
参数 | 含义 |
---|---|
size |
裁剪的输出尺寸 |
padding |
随机裁剪前先加上四周 padding |
pad_if_needed |
如果原图小于 size ,是否自动 pad |
fill |
填充值(仅 padding_mode=constant 时生效) |
padding_mode |
constant (默认零填充)、edge (边界值填充)、reflect (镜像填充) |
transform = transforms.RandomCrop(224, padding=16, padding_mode='reflect')
效果:
图片四周先镜像扩展 16 像素,再随机裁剪 224×224
场景 | 理由 |
---|---|
防止过拟合 | 模型不能只记住图片的某个固定区域 |
增加数据多样性 | 每次训练模型看到的“图片”都不同 |
空间不变性 | 让模型学到特征不局限于图片中心 |
from torchvision import transforms
from PIL import Image
transform = transforms.Compose([
transforms.Resize(256),
transforms.RandomCrop(224),
transforms.ToTensor()
])
img = Image.open('cat.jpg')
tensor = transform(img)
print(tensor.shape) # torch.Size([3, 224, 224])
模块 | 功能 | 作用 |
---|---|---|
Resize |
缩放图片 | 固定尺寸输入 |
RandomCrop |
随机裁剪 | 增加随机性,提升泛化能力 |
ToTensor |
转 Tensor | PyTorch 标配 |