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

Keras LSTM回归模型对不同视频始终输出相同值的问题

模型测试始终输出相同值的排查方案

问题重现

基于行走视频提取的特征训练LSTM回归模型,目标预测人物快乐程度(输出范围0-1),但测试不同视频时模型始终输出固定值,训练与测试代码如下:

训练代码

list_features,masks=fe.prepare_all_videos()
X_train=np.array(list_features)
scaler = MinMaxScaler(feature_range=(-1,1))
X_train = scaler.fit_transform(X_train.reshape(X_train.shape[0], -1)).reshape(X_train.shape)
X_train = scaler.fit_transform(X_train.reshape(X_train.shape[1], -1)).reshape(X_train.shape)
X_train = scaler.fit_transform(X_train.reshape(X_train.shape[2], -1)).reshape(X_train.shape)
y_train=f.getListEtichettaFromVideos('happy')
y_train=np.array(y_train)
y_train = (y_train-min(y_train)) / (max(y_train)-min(y_train))
model = keras.Sequential([
    layers.LSTM(32,input_shape=(24,2048)),
    layers.Dense(16),
    layers.Dense(1,activation='sigmoid')
])

# Compile neural network
model.compile(optimizer='adam', loss='mse')
history=model.fit(X_train,y_train,epochs=20,batch_size=16,validation_data=(X_train,y_train))

测试代码

modello=keras.models.load_model('Modello.keras')
video=cv2.VideoCapture(path+'VID_TEST_CUT_75.avi')
frames=f.getAllFramesFromVideo(video)
frames=frames[:24]

feature,mask=fe.prepare_single_video(frames)
features=np.array(feature)
scaler = MinMaxScaler(feature_range=(-1,1))
features = scaler.fit_transform(features.reshape(features.shape[0], -1)).reshape(features.shape)
features = scaler.fit_transform(features.reshape(features.shape[1], -1)).reshape(features.shape)
features = scaler.fit_transform(features.reshape(features.shape[2], -1)).reshape(features.shape)
print(modello.predict(features))

核心问题排查与修复

1. 数据标准化逻辑完全错误

这是导致输出固定值的最直接原因:

  • 训练时连续三次调用fit_transform,每次都会重新计算数据的均值、极值,彻底打乱特征分布,模型无法学到有效规律
  • 测试时重新初始化Scaler并调用fit_transform,用测试数据的分布做标准化,和训练阶段的标准化逻辑完全脱节,导致模型输入分布错乱

修复方案:

  • 训练时仅基于训练集做一次标准化,保存Scaler用于测试阶段
  • 测试时只能用训练好的Scaler执行transform,绝对不能重新fit

修改后的训练代码片段:

scaler = MinMaxScaler(feature_range=(-1,1))
# 对样本维度做一次标准化(假设X_train形状为(样本数, 帧数, 特征数))
X_train_flatten = X_train.reshape(X_train.shape[0], -1)
scaler.fit(X_train_flatten)
X_train = scaler.transform(X_train_flatten).reshape(X_train.shape)

# 保存scaler,后续测试用
import joblib
joblib.dump(scaler, 'scaler.pkl')

修改后的测试代码片段:

# 加载训练好的scaler
scaler = joblib.load('scaler.pkl')
features=np.array(feature)
# 仅执行transform,禁止fit
features_flatten = features.reshape(features.shape[0], -1)
features = scaler.transform(features_flatten).reshape(features.shape)

2. 验证集设置无效

训练时validation_data=(X_train,y_train)直接用训练集做验证,无法判断模型泛化能力:

  • 若训练集标签分布单一(比如大部分标签集中在某个值),模型会直接学习输出该均值,导致测试时输出固定值
  • 无法监控过拟合/欠拟合情况,训练过程完全失控

修复方案:

  • 用train_test_split将训练集划分为训练、验证子集,用独立验证集监控loss变化
  • 查看训练曲线:若训练/验证loss都居高不下,说明模型未学到有效特征;若训练loss极低但验证loss极高,说明过拟合

3. 模型结构与损失函数不匹配

  • LSTM后的Dense层无激活函数,默认线性激活易导致梯度消失,建议添加relu激活增强非线性表达
  • 输出层用sigmoid(输出0-1)搭配mse损失,若标签是连续值可保留,但如果标签是离散二分类,建议改用binary_crossentropy

修改后的模型结构:

model = keras.Sequential([
    layers.LSTM(32,input_shape=(24,2048)),
    layers.Dense(16, activation='relu'),  # 添加relu激活
    layers.Dense(1,activation='sigmoid')
])
# 根据标签类型选择损失函数
model.compile(optimizer='adam', loss='mse')

4. 输入维度一致性检查

测试时需确保输入形状与训练时一致(训练输入为(样本数,24,2048)),单样本测试时需手动增加维度:

# 若features形状为(24,2048),需转为(1,24,2048)匹配模型输入
features = np.expand_dims(features, axis=0)
print(modello.predict(features))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 08:25:40