AlexNet+LSTM模型视频预测时更换输入始终输出相同结果问题求助
CNN+LSTM视频预测固定输出0的解决方案
你的预测结果始终为0的核心问题首先出在推理代码逻辑存在严重错误,和模型训练的问题是两码事,先把代码的问题修复后再排查训练环节的问题即可。
现有代码的核心错误
- 最致命的错误:你在把读取到的单帧图像resize赋值给
frame_set后,紧接着用frame_set=np.arange(10*width*height*3).reshape(10,width, height, 3)直接用无意义的等差数值序列覆盖了有效帧数据,等于每次喂给模型的根本不是视频内容,模型当然输出固定结果。 - 不符合模型输入要求:你的模型输入要求是连续10帧的时序视频序列,现有逻辑每次只读1帧,没有缓存连续10帧的逻辑,完全不匹配CNN+LSTM的输入规范。
- 冗余无效操作:
frame_set.reshape(10, width, height, 3).shape没有任何赋值动作,属于完全无用的代码。 - 逻辑错误:
vid.set(3, 480)和vid.set(4, 240)写在帧读取之后不会生效,且后续你已经把帧resize到224*224,这两行设置完全多余。 - 缺失预处理步骤:没有和训练环节对齐的像素归一化操作,且你直接把分类概率数组传给
cv2.imshow展示,属于调用逻辑错误。
修复后的参考推理代码
import cv2 import numpy as np from tensorflow.keras import models from collections import deque import time model_path = 'Model/AlexNet_LSTM_10Frame_Cropped.h5' model = models.load_model(model_path) vid = cv2.VideoCapture("Data Fix/Data16_133.mp4") # 初始化长度为10的帧缓存队列,对应模型的时序输入要求 frame_buffer = deque(maxlen=10) # 归一化参数必须和训练环节完全一致,如果你训练时只是像素除以255,直接修改为frame_resized/255.0即可 norm_mean = [0.485, 0.456, 0.406] norm_std = [0.229, 0.224, 0.225] total_frame = 0 # 替换为你自己的5个类别名称 class_names = ["类别0", "类别1", "类别2", "类别3", "类别4"] while(vid.isOpened()): ret, frame = vid.read() start = time.time() if ret == True: total_frame += 1 draw = frame.copy() # 单帧预处理和训练环节保持一致 frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB) frame_resized = cv2.resize(frame_rgb, (224, 224), interpolation = cv2.INTER_AREA) frame_normalized = (frame_resized / 255.0 - norm_mean) / norm_std # 加入缓存队列 frame_buffer.append(frame_normalized) # 队列存满10帧后再执行预测 if len(frame_buffer) == 10: # 转换为模型要求的输入格式 (batch, 时序长度, 宽, 高, 通道数) model_input = np.expand_dims(np.array(frame_buffer), axis=0) result = model.predict_on_batch(model_input)[0] # 取概率最高的类别 pred_class = np.argmax(result) pred_score = result[pred_class] # 把预测结果绘制到画面上 cv2.putText(draw, f"类别:{class_names[pred_class]} 置信度:{pred_score:.2f}", (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) print(f"预测类别:{pred_class},各类别概率:{result}") cv2.imshow('Result', draw) if cv2.waitKey(1) & 0xFF == ord('q'): break else: break vid.release() cv2.destroyAllWindows()
修复代码后仍输出固定0的训练环节排查方向
- 检查数据集标注是否正确,是否存在严重类别不平衡:如果类别0的样本占比超过90%,模型会直接学习到预测所有样本为0就能拿到最高准确率。
- 确认训练时的预处理逻辑和推理完全对齐:包括色彩空间转换、归一化方式、resize插值方法等所有涉及输入数据处理的步骤。
- 检查模型结构是否正确:5分类输出层需要使用softmax激活,损失函数要和标注格式匹配,对应为categorical_crossentropy(独热标注)或sparse_categorical_crossentropy(序号标注)。
- 检查模型训练是否收敛:如果训练过程中验证集准确率始终在20%(5分类的随机概率)附近波动,说明自定义AlexNet没有学到有效特征,可以调整学习率、batch size等参数,或加入迁移学习提升特征提取能力。
内容的提问来源于stack exchange,提问作者JuniorPython
相关产品推荐
相关产品推荐

