4、常见AI模型输入要求:分类、检测、分割等模型的固定输入尺寸与通道格式

在摄像头AI项目的工程落地中,模型推理前的输入预处理往往决定了整个pipeline的成败。很多开发者将精力集中在模型选型和训练调参上,却忽略了输入张量(Input Tensor)的格式约束,导致在端侧部署时出现推理报错、精度骤降或内存越界。本章将系统梳理分类、检测、分割三类主流视觉模型对输入尺寸(H×W)、通道数(C)、数据类型(dtype)以及归一化方式的硬性要求,并给出工程判断与适配策略。

AI模型输入约束与摄像头预处理链路 摄像头原始帧 1920×1080 · BGR 预处理模块 Resize / Crop / Pad BGR→RGB · 归一化 uint8→float32 模型输入张量 N×C×H×W 或 N×H×W×C 固定尺寸 · 固定通道 dtype: float32 推理输出 分类: 1×N 检测: 1×M×6 分割: 1×C×H×W 分类模型 ResNet / MobileNet / ViT 固定输入: 224×224×3 中心裁剪 / 等比缩放 全连接层要求固定尺寸 ImageNet均值方差归一化 dtype: float32 检测模型 YOLO / SSD / Faster R-CNN YOLOv5: 640×640×3 letterbox 等比缩放+填充 坐标需还原到原图 归一化: /255.0 dtype: float32 分割模型 UNet / DeepLabV3 / SegNet 常见: 512×512×3 可接受任意尺寸(全卷积) 但需保证H/W为8/16倍数 输出mask需上采样回原图 dtype: float32

4.1 核心原理:为什么模型输入必须是固定张量

深度学习模型在训练阶段,输入张量的形状(shape)直接决定了网络各层权重矩阵的维度。以全连接层(Fully Connected Layer)为例,其权重矩阵为 [C_in, C_out],其中 C_in 必须与上一层输出的特征维度严格匹配。如果输入图像的尺寸发生变化,经过卷积层和池化层后,展平(flatten)得到的特征向量长度就会改变,导致全连接层无法完成矩阵乘法运算。因此,分类模型通常要求固定输入尺寸,如 224×224、299×299 等。

对于检测和分割模型,虽然全卷积网络(FCN)在理论上可以接受任意尺寸输入,但实际工程中仍然需要固定尺寸。原因有三:

  • 批处理(Batch)一致性:GPU/TPU 推理时,一个 batch 内的所有张量必须具有相同的 shape,否则无法并行计算。
  • 锚点(Anchor)与特征金字塔(FPN)设计:YOLO、SSD 等检测器在特征图的每个格点上预设锚点框,锚点的尺度和比例与输入尺寸强相关。若输入尺寸变化,锚点的匹配逻辑需要重新设计。
  • 硬件加速器约束:端侧 NPU(如瑞芯微 RKNN、海思 NNIE)通常只支持编译时指定的输入 shape,动态尺寸会导致重新编译或推理失败。

通道格式方面,绝大多数视觉模型采用 RGB 三通道输入,但摄像头传感器输出的原始格式通常是 Bayer RAW 或 BGR(OpenCV 默认)。通道顺序错误会导致颜色通道错位,模型精度大幅下降。此外,部分红外摄像头或深度摄像头可能输出单通道(灰度)或四通道(RGB-D)数据,需要针对性适配。

关键认知:模型输入尺寸不是“建议值”,而是“硬约束”。在模型导出(如 ONNX、TensorRT)时,输入节点的 shape 已被固定。若运行时传入不同 shape,轻则报错,重则内存越界导致程序崩溃。

4.2 判断方法:如何确定模型的精确输入要求

在实际项目中,我们通常从三个来源获取模型的输入规格:模型配置文件、训练代码、推理框架的模型信息打印。以下是标准判断流程:

  1. 查看模型配置文件:YOLO 系列的 *.yaml 文件中包含 input_size 字段;TensorFlow 的 saved_model.pb 可通过 saved_model_cli show 命令查看输入签名。
  2. 解析 ONNX 模型:使用 onnxruntime 或 netron 工具查看输入节点的 shape 和 dtype。
  3. 检查训练代码:训练脚本中的数据加载器(DataLoader)中的 transforms.Resize((H, W)) 即为训练时的输入尺寸。
  4. 确认归一化参数:ImageNet 预训练模型通常使用 mean=[0.485, 0.456, 0.406],std=[0.229, 0.224, 0.225];而 YOLO 系列通常只做 /255.0 缩放。

下表汇总了常见模型的输入规格,供工程参考:

模型类型 典型模型 输入尺寸 (H×W) 通道格式 归一化方式 备注
分类 ResNet50 224×224 RGB mean/std 中心裁剪
分类 EfficientNet-B0 224×224 RGB mean/std 自动缩放
检测 YOLOv5s 640×640 RGB /255.0 letterbox
检测 SSD-MobileNet 300×300 RGB /255.0 固定尺寸
分割 UNet 512×512 RGB /255.0 可任意但需8倍数
分割 DeepLabV3 513×513 RGB mean/std 空洞卷积

4.3 案例拆解:YOLOv5 检测模型的输入适配实战

我们以一个实际项目为例:某工厂质检系统需要部署 YOLOv5s 模型检测产品表面缺陷,摄像头分辨率为 1920×1080,帧率要求 30 FPS。模型训练时输入尺寸为 640×640,采用 letterbox 预处理。

初始现象:直接使用 OpenCV 的 cv2.resize(frame, (640, 640)) 将图像拉伸后送入模型,检测精度从训练时的 mAP 0.92 下降到 0.78,且小目标漏检严重。

分析过程:拉伸变形导致目标宽高比失真,YOLO 的锚点框是基于 640×640 的原始比例设计的,变形后锚点匹配失效。此外,直接拉伸会引入几何畸变,特征提取质量下降。

解决方案:改用 letterbox 预处理,保持原始宽高比,在短边两侧填充灰色(114, 114, 114)。具体步骤如下:

import cv2
import numpy as np

def letterbox(img, new_shape=(640, 640), color=(114, 114, 114)):
    shape = img.shape[:2]  # H, W
    r = min(new_shape[0] / shape[0], new_shape[1] / shape[1])
    new_unpad = (int(round(shape[1] * r)), int(round(shape[0] * r)))  # W, H
    dw = (new_shape[1] - new_unpad[0]) / 2
    dh = (new_shape[0] - new_unpad[1]) / 2
    if shape[::-1] != new_unpad:
        img = cv2.resize(img, new_unpad, interpolation=cv2.INTER_LINEAR)
    top, bottom = int(round(dh - 0.1)), int(round(dh + 0.1))
    left, right = int(round(dw - 0.1)), int(round(dw + 0.1))
    img = cv2.copyMakeBorder(img, top, bottom, left, right, cv2.BORDER_CONSTANT, value=color)
    return img, r, (dw, dh)

# 推理时
frame = cv2.imread("defect.jpg")  # BGR
img, ratio, pad = letterbox(frame, (640, 640))
img = img[:, :, ::-1].transpose(2, 0, 1)  # BGR→RGB, HWC→CHW
img = np.ascontiguousarray(img, dtype=np.float32) / 255.0
# 送入模型推理...
# 后处理时,将检测框坐标除以ratio,并减去pad偏移

结果对比:采用 letterbox 后,mAP 恢复到 0.90,小目标召回率提升 12%。代价是推理耗时增加约 3ms(主要是 resize 和 copyMakeBorder),但 30 FPS 的实时性要求仍可满足。

风险与复盘:letterbox 填充的灰色值必须与训练时一致(YOLOv5 默认 114),否则会影响 BatchNorm 层的统计特性。另外,后处理坐标还原时,必须使用 ratio 和 pad 参数,否则检测框位置偏移。

常见误区:不要将 letterbox 与 resize 混为一谈。resize 会改变目标比例,letterbox 保持比例但引入填充区域。对于检测模型,填充区域不会产生误检,因为训练时已经见过类似填充。

4.4 常见误区与总结复盘

在摄像头AI项目的输入适配环节,以下误区高频出现,需要特别注意:

  • 通道顺序错误:OpenCV 读取为 BGR,PyTorch 模型训练时使用 RGB。若不转换,模型精度可能下降 5%-15%。务必在预处理中加入 img[:, :, ::-1] 或使用 cv2.cvtColor。
  • 归一化方式不匹配:YOLO 系列使用 /255.0,而 ResNet 等分类模型使用 mean/std 归一化。混用会导致输入分布偏移,激活值饱和。
  • 忽略 dtype 转换:摄像头帧为 uint8,模型输入要求 float32。直接传入 uint8 会导致推理框架隐式转换,但可能丢失精度或报错。应显式转换并确保内存连续(np.ascontiguousarray)。
  • 分割模型尺寸未对齐:UNet 等模型要求输入尺寸为 8 或 16 的倍数,否则下采样后特征图尺寸无法整除,导致上采样输出与原图尺寸不一致。
  • 动态尺寸误用:TensorRT 支持动态 shape,但端侧 NPU 通常不支持。在部署前应确认硬件加速器是否支持动态输入,否则需固定尺寸。

总结:输入适配是摄像头AI项目的“第一公里”,也是“最后一公里”。第一公里决定了模型能否正确推理,最后一公里决定了输出结果能否映射回原图。建议在项目启动时,将模型的输入规格(尺寸、通道、dtype、归一化参数)写入配置文件,并编写单元测试验证预处理逻辑的正确性。同时,建立“训练-部署”一致性检查机制,确保训练时的预处理与部署时的预处理完全一致,这是避免精度损失的最有效手段。