必须复现训练时的预处理逻辑:确认输入尺寸(如224×224)和归一化方式(如rescale=1./255或专用preprocess_input),确保load_img后正确缩放、加batch维,并匹配模型输出层激活类型解码。

加载图像前先确认模型输入尺寸和归一化方式
直接用 tf.keras.preprocessing.image.load_img 读图再转数组,大概率导致预测结果异常——因为模型训练时用的预处理逻辑(比如 rescale=1./255、preprocessing_function)必须复现。跳过这步,model.predict() 会拿到未归一化的 uint8 数据,和训练分布严重不一致。
实操建议:
- 查模型文档或训练代码,确认输入尺寸(如
(224, 224))和归一化方式(是除以 255?减均值?还是用tf.keras.applications.xception.preprocess_input?) - 优先复用训练时的预处理函数,例如:若用
EfficientNetV2B0,必须调用tf.keras.applications.efficientnet_v2.preprocess_input - 图像路径用
tf.io.read_file+tf.image.decode_jpeg更可控,避免 PIL 自动转 RGB 的隐式行为
构造单样本 batch 时别漏掉 batch 维度
model.predict() 要求输入是 batched tensor,即形状为 (batch_size, height, width, channels)。直接传入 shape 为 (224, 224, 3) 的张量会报错:ValueError: Input 0 of layer "model" is incompatible with the layer。
正确做法:
立即学习“Python免费学习笔记(深入)”;
- 用
tf.expand_dims(image_tensor, axis=0)在最前面加一个维度 - 或用
np.expand_dims(image_array, axis=0)(如果用 NumPy 流程) - 避免用
np.array([image_array])—— 容易因 dtype 不一致引发静默错误 - 验证维度:打印
input_tensor.shape,确保是(1, 224, 224, 3)类似结构
预测后解码 logits 需匹配模型输出层类型
模型最后一层决定输出含义:softmax 输出概率,linear 或无激活输出 logits。用错解码方式会导致结果完全不可信,比如对 logits 直接取 np.argmax 可能碰巧对,但概率值会全错。
检查与处理方法:
- 运行
model.layers[-1].activation,看是否为<function softmax at ...></function>;若为<function linear at ...></function>,需手动加tf.nn.softmax - 若模型带
include_top=True(如官方预训练权重),通常已含 softmax;若include_top=False,则输出是特征向量,必须自己接分类头 - 标签映射:用
tf.keras.applications.<model>.decode_predictions</model>仅适用于 ImageNet 模型;自定义类别要用训练时的class_indices字典反查
GPU 内存不足时用 tf.device 强制 CPU 推理
小样本预测本不该爆显存,但如果模型较大(如 ViT-L/16)且 GPU 已被其他进程占满,model.predict() 可能卡住或报 ResourceExhaustedError。此时强行用 CPU 是最快落地解法。
操作要点:
- 在预测前加
with tf.device('/CPU:0'):上下文管理器 - 确保模型已在 CPU 设备上构建(即创建模型时未指定 GPU 设备),否则会触发隐式数据搬运开销
- 若用 SavedModel 格式加载,加载时加
options=tf.saved_model.LoadOptions(experimental_io_device='/job:localhost')可绕过部分设备绑定问题
真正麻烦的不是怎么跑通,而是训练时没保存好预处理逻辑和 class_indices——等要预测时才发现连“猫”和“狗”的索引都对不上。


















