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。

相关推荐
蓝速科技2 分钟前
会议室门牌签到功能选型与落地指南丨蓝速科技
大数据·运维·数据库·人工智能·科技
人工智能AI技术8 分钟前
Agent Harness工程组件漫谈:拆解带文件读取能力的子Agent项目分析助手
人工智能
这张生成的图像能检测吗12 分钟前
(论文速读)IPFP:把图像特征反投影到 3D,用单分支完成多模态训练
人工智能·计算机视觉·点云·多模态融合·3d技术·三维感知·2d相机
jekc86813 分钟前
TabbyAPI+ExLlama
人工智能
YOLO数据集集合17 分钟前
无人机航拍地面目标检测数据集 | 无人机航拍 地面目标检测 坦克识别 人员检测 俯视视角 目标检测9092期
人工智能·目标检测·计算机视觉·目标跟踪·无人机航拍·军事图像·坦克识别
AI多Agent协作实战派17 分钟前
【AI探索历程18】把“半年配置“装进一个zip
人工智能
qq_1998868723 分钟前
第7板块·第1节:通用算子分类与设计模式
c++·人工智能·gpu算力·cuda
硅谷秋水3 小时前
RoboLab:用于分析机器人任务通才策略的高-保真仿真基准
机器学习·计算机视觉·语言模型·机器人
AI多Agent协作实战派6 小时前
【AI探索历程17】从“给自己用“到想“让别人用“
人工智能
吴佳浩7 小时前
Memory Provider 实战:Hermes、Mem0、Honcho、Hindsight 为什么都这样设计?
人工智能·agent·ai编程