使用model.predict()预测不同图像时输出结果始终相同的问题
解决手势识别模型预测结果固定的问题
你遇到的问题是模型对所有输入图像输出相同结果,这大概率是输入预处理和训练阶段不一致或者加载模型的方式有误导致的,下面是具体的排查和解决步骤:
1. 移除不必要的模型重新编译代码
加载已经训练好的.h5模型后,不需要再次调用model.compile()——这会重置优化器状态(虽然不影响训练好的权重,但完全没必要,甚至可能引发潜在问题)。直接删掉以下代码:
model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy'])
2. 对齐训练和预测时的图像归一化逻辑
训练模型时,输入图像肯定做了归一化处理(把像素值缩放到0-1之间),但你现在的代码里只把图像转成了float32,没有做归一化。在arr = np.array(img, dtype='float32')之后加上:
arr = arr / 255.0 # 将0-255的像素值缩放到0-1区间,和训练时保持一致
3. 确认图像尺寸和训练时完全匹配
检查原Kaggle训练代码中的输入图像尺寸:如果训练时模型的输入是(64,64,1)(很多手势识别模型会用这个尺寸),那你现在resize成(120,320)就完全错误了,必须严格和训练代码里的resize参数保持一致。
另外注意:PIL的resize((w, h))参数是宽度在前,高度在后,而模型输入的(120,320)是高度在前,宽度在后,如果训练时是resize((320,120)),那你现在的尺寸就搞反了,模型无法正确提取特征。
4. 复刻训练时的图像预处理细节
原手势识别代码大概率做了手部区域提取(比如阈值分割、去除背景),而你直接用全图的灰度图输入,背景干扰会让模型无法识别手势。比如原代码可能有类似这样的处理:
# 示例:训练时可能做的阈值分割(仅参考,以原代码为准) _, img_thresh = cv2.threshold(np.array(img), 127, 255, cv2.THRESH_BINARY_INV)
你需要把训练代码中所有针对输入图像的处理步骤(比如灰度反转、阈值、裁剪)完全复制到预测代码里,确保输入图像的分布和训练时一致。
修改后的示例代码
from keras.models import load_model from PIL import Image import numpy as np # 加载模型,无需重新编译 model = load_model('hand-guesture-model.h5') # 图像预处理(严格对齐训练逻辑) img = Image.open('test.jpg').convert('L') # 替换成训练代码里的resize尺寸,比如原代码是(64,64)就改成(64,64) img = img.resize((64, 64)) arr = np.array(img, dtype='float32') arr = arr / 255.0 # 归一化 arr = arr.reshape(1, 64, 64, 1) # 对应模型输入形状 prediction = model.predict(arr) print(prediction) print(np.argmax(prediction[0]))
内容的提问来源于stack exchange,提问作者Shanthan Reddy
相关产品推荐
相关产品推荐

