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

为何训练与测试时同一图像的神经网络表现差异巨大?

新冠快检图像分类模型训练与推理准确率不一致问题排查

我用TensorFlow搭建了一个神经网络,将新冠病毒快速检测图像分为三类:阴性、阳性、空白。训练过程中TensorBoard显示验证准确率约90%,但训练完成后用同一训练图像测试时,分类准确率却仅约60%;更换不同图像训练后,该问题依然存在。


训练相关细节

图像预处理流程

训练时图像先转为灰度图再调整尺寸,批量大小设为16:

image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.resize(image, (height, width))

数据增强设置

因数据集仅约450张图像,使用keras.preprocessing.image.ImageDataGenerator做数据增强,参数如下:
width_shift_range=0.1、brightness_range=[0.9, 1.1]、height_shift_range=0.1、zoom_range=0.2、horizontal_flip=True、rotation_range=10、shear_range=0.2、fill_mode="nearest"、samplewise_center=True、samplewise_std_normalization=True

TFLite模型转换代码

为适配移动平台,将训练好的模型转为TFLite格式:

model = tf.keras.models.load_model(model_path)

converter = tf.lite.TFLiteConverter.from_keras_model(model)
# converter.optimizations = [tf.lite.Optimize.DEFAULT] # 未启用优化
tflite_model = converter.convert()

# 保存模型
with open('rapid_test_strip_cleaned_model.tflite', 'wb') as f:
  f.write(tflite_model)

已尝试的解决方法

  • 将图像裁剪至检测盒的试纸条区域,重新训练并测试
  • 检查测试脚本中的标签映射是否正确
  • 验证测试时图像是否正确转为灰度图并调整尺寸
  • 在转换TFLite前,直接用tensorflow.keras.models测试原模型

模型结构

img_width, img_height = (256, 256)

model = Sequential()
inputShape = (img_width, img_height, 1)
model.add(Conv2D(32, (3, 3), activation="relu", input_shape=inputShape))
# 抑制过拟合
model.add(Dropout(0.25))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Conv2D(64, (3, 3), activation="relu"))
# 抑制过拟合
model.add(Dropout(0.25))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))

model.add(Conv2D(128, (3, 3), activation="relu"))
# 抑制过拟合
model.add(Dropout(0.25))
model.add(MaxPooling2D(pool_size=(2, 2), strides=(2, 2)))
  
model.add(Flatten())
model.add(Dense(512, activation="relu"))
# 抑制过拟合
model.add(Dropout(0.5))
model.add(Dense(3, activation="softmax"))

opt = Adam(learning_rate=INIT_LR, decay=INIT_LR / EPOCHS)

model.compile(loss="categorical_crossentropy", optimizer=opt,
            metrics=["accuracy"])

训练的TensorBoard图表显示验证准确率约90%,其中直线来自另一次训练运行。


测试/推理脚本

interpreter = tf.lite.Interpreter(model_path=model_path)

# 加载TFLite模型并分配张量
interpreter.allocate_tensors()

# 获取输入输出张量信息
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()

height = input_details[0]['shape'][1]
width = input_details[0]['shape'][2]

labels = ["positive", "negative", "initial"]

# 加载图像并预处理
image = cv2.imread(image_path)
image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
image = cv2.resize(image, (height, width))
input_arr = img_to_array(image)

input_arr = np.array([input_arr])
# 归一化
input_arr = input_arr / 255.0

interpreter.set_tensor(input_details[0]['index'], input_arr)
interpreter.invoke()

# 获取输出结果
output_data = interpreter.get_tensor(output_details[0]['index'])
results = np.squeeze(output_data)
top_k = results.argsort()[-5:][::-1]

print(labels[top_k[0]])

问题可能的根源

  1. 预处理流程不一致:训练时用了samplewise_center=True和samplewise_std_normalization=True,即对每张图像单独做均值中心化、标准差归一化,但推理脚本仅做了input_arr / 255.0,未同步这两步操作,导致输入数据分布与训练时偏差极大,模型输出错误。
  2. 标签映射不匹配:训练时的标签顺序与推理脚本中labels列表的顺序可能不一致,比如训练时标签顺序是[阴性,阳性,空白],但推理时顺序颠倒,导致分类结果对应错误。
  3. 数据集划分偏差:验证集可能与训练集存在数据重叠,或验证集图像分布过于简单,导致验证准确率虚高,实际模型泛化能力不足。
  4. Dropout层状态异常:虽然Keras模型在推理时会自动关闭Dropout,但转换TFLite时若未正确处理,可能导致推理时仍启用Dropout,影响输出稳定性(不过你已测试原Keras模型,此可能性较低)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 17:18:08