You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

加载两个不同二分类CNN合并推理时调用model.predict()出现预测失效问题

故障定位与修正方案

触发该异常的核心原因

1. 预处理流程顺序与原独立脚本不匹配

当前代码的预处理执行顺序为:

  • 裁剪得到裸片区域
  • 对全裸片区域做cv2.normalize全局归一化
  • 从归一化后的图像复制副本,涂黑中间区域得到崩边模型的输入

原独立崩边预处理脚本的执行顺序为:

  • 裁剪得到裸片区域
  • 先涂黑中间不需要的区域
  • 再对全图做全局cv2.normalize归一化

两种流程的结果存在本质差异:

cv2.NORM_MINMAX归一化是基于全图像素的最大最小值计算映射关系,提前涂入大块0值区域会直接拉低全局像素最小值、拉宽动态范围,最终输出的像素值分布和“先归一化再涂黑”的结果完全不一致。模型输入分布与训练时的分布偏差过大,就会出现输出固定类别的异常。

修正方式:将预处理顺序严格对齐原独立脚本逻辑,两个模型的输入从同一张裁剪图出发,分别完成独立的遮罩、归一化流程:

# 裁剪得到裸片ROI
crop_image = img_input[self.y:self.y + self.height, self.x:self.x + self.width].copy()
h, w = crop_image.shape[0:2]

# 分别为两个模型生成独立的原始遮罩图
scratch_raw = crop_image.copy()  # 划痕模型输入:全裸片无遮罩
broken_edge_raw = crop_image.copy()  # 崩边模型输入:带中间遮罩
broken_edge_raw[27:h - 27, 27:w - 27] = 0

# 分别独立完成归一化,和原独立脚本逻辑完全一致
scratch_input = cv2.normalize(scratch_raw, None, 0, 255, norm_type=cv2.NORM_MINMAX)
broken_edge_input = cv2.normalize(broken_edge_raw, None, 0, 255, norm_type=cv2.NORM_MINMAX)

2. 模型输入的缩放规则缺失

代码中被注释掉了输入张量的float类型转换与值缩放逻辑:

#scratch_input_image = scratch_input_image.astype('float32') / 255
#broken_edge_input_image = broken_edge_input_image.astype('float32') / 255

如果模型训练时所有训练样本的输入是缩放到0-1区间的float32张量,直接喂入0-255范围的uint8图像,模型输出会完全偏移。之前独立脚本运行正常,是因为当时该段代码处于生效状态,合并过程中被误注释。
修正方式:逐一对齐两个模型训练时的输入规则:

  • 每个模型的输入张量单独做类型转换、值域缩放,不要套用统一处理逻辑
  • 补充通道顺序转换:如果模型训练时使用RGB顺序的图像,需要在预处理最后通过cv2.cvtColor(temp, cv2.COLOR_BGR2RGB)完成通道转换——cv2.imread默认读取的是BGR通道顺序,和多数训练流程使用的RGB顺序不匹配

3. 验证排查步骤

  • 打开原有调试代码,将生成的两个模型输入图像逐张保存为本地文件,和原独立预处理脚本的输出文件做像素值对比,只要存在单像素值差超过1,就说明预处理流程存在偏差
  • 选取原独立脚本验证过的标准测试图,在合并脚本中传入该图的固定路径,分别打印两个模型的原始预测输出值,和独立脚本的输出值做对比,数值不一致即可定位到预处理环节的问题
  • 检查Keras模型加载的版本一致性:两个模型统一使用同一版本的接口加载,避免因版本兼容问题导致模型权重加载异常

内容的提问来源于stack exchange,提问作者NECben067

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.30 15:24:07