数据预处理:图像缩放与归一化、数据增强策略

大家好,我是你们的老朋友。今天咱们聊聊数据预处理这块硬骨头。说实话,很多同学觉得模型训练就是调参、改网络结构,其实数据预处理才是真正的「地基」。地基没打好,后面再怎么折腾也白搭。

我刚开始做障碍物检测那会儿,就吃过这个亏。当时急着跑模型,随便把图片resize了一下就扔进去训练。结果呢?模型在验证集上表现还行,一到真实场景就各种漏检。后来才发现,是预处理环节出了问题。

图像缩放与归一化

先说图像缩放。你想想看,咱们的检测模型输入尺寸通常是固定的,比如640×640或者416×416。但摄像头拍出来的图片尺寸五花八门,怎么办?必须统一尺寸。

这里有个坑——直接暴力拉伸。我曾经试过把一张1920×1080的宽屏图片直接拉成正方形,结果画面里的行人全变成了「瘦高个」,车辆变成了「矮胖子」。模型根本学不到正确的形状特征。

避坑指南:不要直接resize!建议采用letterbox方式,保持原始宽高比,不足部分用灰色填充。这样物体的形状不会变形。

归一化就更关键了。说白了,就是把像素值从0-255映射到0-1或者-1到1之间。为什么要这么做?因为神经网络对输入数据的尺度非常敏感。如果输入值太大,梯度更新会不稳定,模型训练容易发散。

# 我常用的归一化方式
def normalize_image(image):
    # 方式一:除以255
    image = image / 255.0
    
    # 方式二:均值标准差归一化(推荐)
    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]
    image = (image - mean) / std
    
    return image

我个人习惯用第二种方式。为什么?因为ImageNet上预训练的模型都是用这种方式归一化的。如果你要用迁移学习,最好保持一致。

数据增强:让模型见多识广

数据增强,说白了就是「无中生有」。你手头只有1000张图片,通过翻转、旋转、裁剪,能变出5000张甚至更多。模型见过的场景越多,泛化能力就越强。

我记得有一次做夜间障碍物检测,白天采集的数据完全不够用。后来通过颜色抖动模拟夜间光照,模型在夜间的表现提升了将近15%。

翻转与旋转

水平翻转是最常用的。为什么?因为障碍物不管从左边来还是右边来,本质上是同一个物体。但要注意——垂直翻转要慎用。你想想看,路上的车不会倒着开吧?

  • 水平翻转:概率50%,几乎所有场景都适用
  • 垂直翻转:仅适用于无人机航拍等特殊场景
  • 随机旋转:±10°以内,角度太大容易丢失关键信息
小技巧:旋转后记得调整标注框。我见过有人旋转了图片但没旋转标注框,结果模型学到的全是错误的位置信息。

裁剪与颜色抖动

随机裁剪模拟的是「部分遮挡」的情况。比如一棵树挡住了半边车身,模型还能认出来吗?通过裁剪训练,模型就能学会从局部特征推断整体。

颜色抖动包括亮度、对比度、饱和度的随机调整。这个在光照变化大的场景特别有用。我曾经在隧道入口做检测,光线从亮到暗变化剧烈。用了颜色抖动后,模型在隧道口的误检率降低了30%。

# 颜色抖动参数设置(我常用的范围)
brightness_delta = 0.2  # 亮度变化范围
contrast_delta = 0.2    # 对比度变化范围
saturation_delta = 0.2  # 饱和度变化范围

Mosaic与MixUp策略

这两个是YOLOv4之后火起来的高级技巧。说实话,我第一次看到Mosaic的时候觉得「这不就是拼图吗?」后来才发现,这里面门道很深。

Mosaic数据增强

Mosaic把4张图片拼成1张。这样做的好处是什么?

  1. 小目标检测能力提升:4张图拼在一起,相当于每张图被缩小了,模型被迫去学习小目标的特征
  2. 上下文信息丰富:一张图里同时出现车辆、行人、路标,模型能学到物体之间的空间关系
  3. Batch Normalization效果更好:因为每张合成图包含4张原始图的信息,BN层的统计量更稳定
核心要点:Mosaic不是简单的拼图。要注意4张图的标注框不能重叠,否则模型会混淆。我一般会计算每个标注框的面积,如果重叠面积超过30%,就重新采样。

MixUp策略

MixUp更「暴力」——直接把两张图按比例混合。比如70%的汽车 + 30%的行人,生成一张「半透明」的合成图。标注也按同样的比例混合。

这听起来有点反直觉。模糊的图片能用来训练?

嗯,这里要注意。MixUp的本质是正则化。它强迫模型在类别之间学习平滑的决策边界。我在实际项目中测试过,用了MixUp之后,模型对遮挡和模糊目标的检测能力明显提升。

# MixUp的简单实现
def mixup(x1, y1, x2, y2, alpha=0.2):
    lam = np.random.beta(alpha, alpha)
    x = lam * x1 + (1 - lam) * x2
    y = lam * y1 + (1 - lam) * y2
    return x, y

知识体系总览

说了这么多,咱们用一张图来总结一下数据预处理的整体流程:

数据预处理知识体系 原始图像数据 第一步:图像缩放与归一化 第二步:数据增强 几何变换 翻转、旋转、裁剪 颜色变换 亮度、对比度、饱和度 高级策略 Mosaic、MixUp 预处理后的训练数据

从这张图可以看得很清楚:原始数据先经过缩放归一化,然后进入数据增强环节。增强又分三个方向——几何变换、颜色变换、高级策略。最终汇聚成高质量的训练数据。

我的建议:不要一股脑把所有增强都用上。先跑个基线,然后逐个添加增强策略,观察模型表现。有时候「少即是多」,过度增强反而会引入噪声。

好了,数据预处理这部分就聊到这儿。记住一句话:好的数据预处理,能让你的模型事半功倍。下一章咱们聊聊标注数据的格式转换和清洗,那也是个大坑。

可可精品资料库