19-图像数据处理:PaddleVision Transform 实战

概述:图像模型训练前为什么必须做 Transform

图像数据不能直接随便送进模型。即使模型结构完全正确,如果图像预处理错了,训练也会异常。

常见图像预处理包括:

  • 调整图片尺寸,例如 Resize
  • 把图片转成 Tensor,例如 ToTensor
  • 按通道归一化,例如 Normalize
  • 随机裁剪、翻转、颜色扰动等数据增强。
  • 保证输入 shape 满足 CNN 要求。

在 Paddle 中,图像处理常用 paddle.vision.transforms。它可以把多个预处理步骤组合起来,和 paddle.vision.datasets 或自定义 Dataset 配合使用。

读完本文,你应该能写出训练和验证两套图像 Transform,并理解图像 Tensor 的 shape、归一化和数据增强策略。

图像 Tensor 的常见 shape

CNN 中常见图像输入格式是:

text 复制代码
[batch_size, channels, height, width]

也就是 NCHW。

例如:

text 复制代码
[32, 3, 224, 224]

含义:

  • 32 张图片。
  • 每张图片 3 个通道。
  • 高度 224。
  • 宽度 224。

单张图片通常是:

text 复制代码
[3, 224, 224]

DataLoader 组合成 batch 后才会变成:

text 复制代码
[N, 3, 224, 224]

transforms.Compose:串联多个图像预处理

常见写法:

python 复制代码
from paddle.vision import transforms

train_transform = transforms.Compose([
    transforms.Resize(size=(224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

Compose 会按顺序执行每个 transform:

text 复制代码
原始图片
    |
Resize
    |
ToTensor
    |
Normalize
    |
模型输入 Tensor

顺序很重要。通常先做几何变换,再转 Tensor,再归一化。

Resize:统一图像尺寸

模型要求输入尺寸一致,所以常用 Resize

python 复制代码
transform = transforms.Compose([
    transforms.Resize(size=(224, 224)),
    transforms.ToTensor(),
])

如果数据集中图片尺寸不同,DataLoader 默认无法直接堆叠成 batch。Resize 可以解决尺寸不一致问题。

注意:

  • 直接拉伸可能改变宽高比。
  • 分类任务中通常影响可接受。
  • 检测、分割任务要更谨慎,因为标签也要同步变换。

ToTensor:把图像转成 Paddle Tensor

ToTensor 通常会把图像转成 Paddle Tensor,并把通道维整理成模型常用格式。

示例:

python 复制代码
from paddle.vision import datasets, transforms

transform = transforms.Compose([
    transforms.ToTensor(),
])

dataset = datasets.MNIST(mode="train", transform=transform)
image, label = dataset[0]

print(image.shape)
print(image.dtype)
print(label)

MNIST 是灰度图,常见 shape 是:

text 复制代码
[1, 28, 28]

彩色图通常是:

text 复制代码
[3, H, W]

Normalize:按通道归一化

归一化常用于让输入分布更稳定:

python 复制代码
transform = transforms.Compose([
    transforms.Resize(size=(224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(
        mean=[0.485, 0.456, 0.406],
        std=[0.229, 0.224, 0.225],
    ),
])

归一化公式:

xnorm=x−meanstd x_{norm} = \frac{x - mean}{std} xnorm=stdx−mean

对于 RGB 图片,meanstd 通常各有 3 个值,分别对应 3 个通道。

如果是 MNIST 灰度图,可以写:

python 复制代码
transforms.Normalize(mean=[0.5], std=[0.5])

关键点:通道数要匹配。RGB 用 3 个值,灰度图用 1 个值。

训练 Transform 与验证 Transform

训练集可以使用随机增强:

python 复制代码
train_transform = transforms.Compose([
    transforms.RandomHorizontalFlip(prob=0.5),
    transforms.Resize(size=(224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

验证集应该稳定:

python 复制代码
val_transform = transforms.Compose([
    transforms.Resize(size=(224, 224)),
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),
])

原则:

  • 训练集可以有随机增强。
  • 验证集和测试集不要使用随机增强。
  • 训练和验证应使用一致的基础尺寸和归一化规则。

常见数据增强方法

Transform 作用 常见用途
RandomHorizontalFlip 随机水平翻转 分类、检测、分割常见
RandomCrop 随机裁剪 增强位置鲁棒性
ColorJitter 调整亮度、对比度等 增强光照鲁棒性
Resize 改变尺寸 统一输入大小
Normalize 通道归一化 稳定训练

不是所有增强都适合所有任务。例如数字识别中水平翻转可能改变语义,医学图像也要谨慎。

使用 MNIST 验证 Transform

MNIST 可以快速验证图像数据管道。

python 复制代码
import paddle
from paddle.vision import datasets, transforms

transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.5], std=[0.5]),
])

train_dataset = datasets.MNIST(mode="train", transform=transform)
train_loader = paddle.io.DataLoader(train_dataset, batch_size=32, shuffle=True)

images, labels = next(iter(train_loader))
print("images:", images.shape, images.dtype)
print("labels:", labels.shape, labels.dtype)

期望形状:

text 复制代码
images: [32, 1, 28, 28]
labels: [32]

如果 shape 不符合预期,先检查 transform 顺序。

自定义图像 Dataset 的基本写法

真实项目常见目录结构:

text 复制代码
dataset/
    cats/
        001.jpg
        002.jpg
    dogs/
        001.jpg
        002.jpg

自定义数据集示例:

python 复制代码
from pathlib import Path
from PIL import Image
import paddle


class ImageFolderDataset(paddle.io.Dataset):
    def __init__(self, root_dir, transform=None):
        super().__init__()
        self.root_dir = Path(root_dir)
        self.transform = transform
        self.class_names = sorted([p.name for p in self.root_dir.iterdir() if p.is_dir()])
        self.class_to_id = {name: idx for idx, name in enumerate(self.class_names)}
        self.samples = []

        for class_name in self.class_names:
            class_dir = self.root_dir / class_name
            for path in class_dir.glob("*.jpg"):
                self.samples.append((path, self.class_to_id[class_name]))

    def __len__(self):
        return len(self.samples)

    def __getitem__(self, index):
        path, label = self.samples[index]
        image = Image.open(path).convert("RGB")
        if self.transform is not None:
            image = self.transform(image)
        label = paddle.to_tensor(label, dtype="int64")
        return image, label

使用:

python 复制代码
dataset = ImageFolderDataset("dataset", transform=train_transform)
loader = paddle.io.DataLoader(dataset, batch_size=32, shuffle=True)

可视化检查:预处理后图像是否合理

图像预处理最怕"看起来代码没错,实际图片已经乱了"。建议抽样检查:

python 复制代码
images, labels = next(iter(loader))
print(images.shape)
print(images.min().numpy(), images.max().numpy())
print(labels[:8])

如果接入 VisualDL,也可以记录图像样本。检查重点:

  • 图片是否被错误拉伸。
  • 通道是否颠倒。
  • 归一化后范围是否异常。
  • label 是否和目录类别对应。

训练前先看数据,比训练崩了再排查更省时间。

常见错误:图像 Transform 排查清单

错误一:Normalize 的通道数不匹配

RGB 图片:

python 复制代码
Normalize(mean=[...三个值...], std=[...三个值...])

灰度图:

python 复制代码
Normalize(mean=[0.5], std=[0.5])

错误二:验证集用了随机增强

验证集不要使用 RandomCropRandomHorizontalFlip 这类随机增强,否则指标会不稳定。

错误三:忘记 ToTensor

模型需要 Tensor 输入。如果 Dataset 返回 PIL Image,模型前向会失败。

错误四:输入 shape 不符合 CNN

CNN 通常期待:

text 复制代码
[N, C, H, W]

如果是 [N, H, W, C],需要调整通道顺序。

错误五:类别名到 ID 的映射不稳定

建议排序:

python 复制代码
self.class_names = sorted(...)

否则不同运行环境下类别 ID 可能不一致。

建议练习:把图像预处理跑通

  1. 用 MNIST 打印单张图像 shape。
  2. 用 DataLoader 打印 batch 图像 shape。
  3. 对 MNIST 使用 Normalize(mean=[0.5], std=[0.5])
  4. 给训练集添加 RandomHorizontalFlip,观察是否适合任务。
  5. 写一个 ImageFolderDataset 读取本地图片。
  6. 打印 class_to_id,确认类别映射。

总结

这一篇讲了 PaddleVision 图像处理基础:

  • 图像模型常用 NCHW 格式。
  • Compose 串联多个 transform。
  • Resize 统一尺寸。
  • ToTensor 将图像转成 Tensor。
  • Normalize 做通道归一化。
  • 训练集可以随机增强,验证集应稳定。
  • 自定义图像数据集要保证类别映射稳定。

如果只能记住一句话,那就是:

图像 Transform 的目标,是把不规则图片稳定转换成模型期望的 [N, C, H, W] Tensor。

相关推荐
IT_陈寒1 小时前
Vue的响应式让我原地破防,原来问题出在这
前端·人工智能·后端
带娃的IT创业者1 小时前
Kimi-K3 开源背后:2.8 万亿参数的“暴力美学”与智能体的新拐点
人工智能·开源·大模型·智能体·开源模型·kimi-k3·moonshot ai
m0_380743871 小时前
实战看出 LLM API 的隐性消耗
人工智能
安逸Ai2 小时前
Claude Code、Cursor、Copilot 这类工具通常如何理解项目上下文?
人工智能
烟雨江南7852 小时前
2026汽车制造与新能源整车柔性产线Agentic-Workflow白皮书:跨APS_MES_ERP多智能体动态排产与装配容错实战
大数据·网络·人工智能·自动化·ai客服·企业agent
星栈2 小时前
AI 时代,人和 AI 的关系,我的一点思考
人工智能
鲜于言悠9053 小时前
Claude Code重大更新:多会话可互相通信,告别手动复制上下文
人工智能
甲维斯3 小时前
给Claude Code配上DeepSeek,调用kimicu控制电脑
人工智能·agent
geminigoth3 小时前
Spring AI Alibaba 入门开发一(备份)
java·人工智能·spring