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

TensorFlow图像分类模型在Spyder与CMD中预测结果不一致问题

TensorFlow模型在Spyder与CMD中预测结果不一致的问题排查

我开发了一个可保存复用的TensorFlow图像分类模型,基于Sequential神经网络实现三类图像分类。在Spyder IDE与命令提示符(CMD)中使用同一虚拟环境运行同一脚本时,模型对同一张图片的预测结果存在显著差异:

  • Spyder预测结果:Class1 = 0.17 - Class2 = 0.05 - Class3 = 0.78
  • CMD预测结果:Class1 = 0.03 - Class2 = 0.01 - Class3 = 0.96

已确认条件:

  • 未使用dropout等引入随机性的层
  • 两者使用同一虚拟环境(TensorFlow版本一致)
  • 运行同一脚本文件

训练代码

import tensorflow as tf
import pandas as pd

training_data = tf.keras.utils.image_dataset_from_directory(data_dir, 
                                            validation_split=0.2,
                                            subset="training",
                                            batch_size=32, 
                                            image_size=(img_size,img_size),
                                            seed=50)

validation_data = tf.keras.utils.image_dataset_from_directory(data_dir, 
                                            validation_split=0.2,
                                            subset="validation",
                                            batch_size=32, 
                                            image_size=(img_size,img_size),
                                            seed=50)

# Get class names
class_names = training_data.class_names
print(class_names)

# Normalize pixel values between 0 & 1
norm_layer = tf.keras.layers.Rescaling(1/255.)

# Apply normalization to datasets
training_data_norm = training_data.map(lambda x, y: (norm_layer(x), y))
validation_data_norm = validation_data.map(lambda x, y: (norm_layer(x), y))

# Check normalization
image_batch, labels_batch = next(iter(training_data_norm))
image_batch[0]

model_4 = tf.keras.models.Sequential([
  tf.keras.layers.Conv2D(filters=10, 
          kernel_size=3,
          activation="relu", 
          input_shape=(img_size, img_size, 3)), 
  tf.keras.layers.MaxPool2D(pool_size=2, padding="valid"),
  tf.keras.layers.Conv2D(10, 3, activation="relu"),
  tf.keras.layers.MaxPool2D(), 
  tf.keras.layers.Conv2D(10, 3, activation="relu"),
  tf.keras.layers.MaxPool2D(),
  tf.keras.layers.Flatten(),
  tf.keras.layers.Dense(3, activation="softmax")
])

# Compile the model
model_4.compile(loss="sparse_categorical_crossentropy",
              optimizer=tf.keras.optimizers.Adam(),
              metrics=["accuracy"])

# Fit the model
history_4 = model_4.fit(training_data_norm,
                        epochs=epochs_tf,
                        steps_per_epoch=len(training_data_norm), 
                        validation_data=validation_data_norm, 
                        validation_steps=len(validation_data_norm))

# Plot training curves
pd.DataFrame(history_4.history).plot(figsize=(20, 10))

# Save model
model_4.save(r"C:\path\to\your\model")

预测代码

import tensorflow as tf

my_image = tf.io.read_file(path)
my_image = tf.image.decode_image(my_image)
my_image = tf.image.resize(my_image, size=[model_dpi, model_dpi])
my_image = my_image / 255  # Normalize data
prediction = model.predict(tf.expand_dims(my_image, axis=0), verbose=0)
print(prediction)

可能的原因及排查方向

1. 模型加载不一致

  • 检查两处运行时的模型加载路径:Spyder和CMD的默认工作目录可能不同,导致加载的不是同一个保存的模型。在预测代码中添加print(model.load_weights.__self__.name)或直接打印模型保存/加载的绝对路径,确认路径完全一致。
  • 确认模型未被意外覆盖:比如在Spyder中重新训练并保存了模型,但CMD加载的是旧版本;或者反之。

2. 图像预处理差异

  • 验证model_dpi与训练时的img_size是否相等:如果两者取值不同,图像resize后的尺寸与模型输入要求不符,会直接导致预测结果偏差。在代码中添加print(f"Model input shape: {model.input_shape}, Resized image shape: {my_image.shape}")确认尺寸一致。
  • 检查图像通道数:tf.image.decode_image会自动推断图像格式,但如果图片是灰度图或存在通道数异常,两处运行时的张量形状可能不同。添加print(my_image.shape)确认通道数为3(与训练时的input_shape一致)。
  • 统一数据类型:训练时Rescaling层输出的是float32,而预测时如果my_image是uint8类型,除以255后会得到float64,可能存在精度差异。修改归一化代码为:my_image = tf.cast(my_image, tf.float32) / 255。

3. 运行环境与计算模式差异

  • 强制统一执行模式:TensorFlow 2.x默认启用Eager Execution,但不同环境可能存在隐性差异。在预测代码开头添加tf.config.run_functions_eagerly(True),强制使用Eager模式运行,测试结果是否一致。
  • 统一硬件加速:如果一处用CPU、另一处用GPU,浮点计算的微小误差可能被放大。添加tf.config.set_visible_devices([], 'GPU')强制使用CPU运行,对比预测结果。

4. 脚本上下文差异

  • 确认图片路径完全一致:相对路径会受工作目录影响,建议在代码中使用图片的绝对路径,并添加print(path)确认两处指向同一张图片。
  • 对比预处理后的图像数据:在两处运行时分别打印my_image.numpy()的前几个像素值,确认预处理后的图像数据完全相同。如果数据不同,问题出在图像读取或resize步骤。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 23:43:20