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
相关产品推荐
相关产品推荐

