为何用于预测等差数列的LSTM机器学习代码输出恒定值?
LSTM预测等差数列输出恒定值的问题分析与修复
核心问题总结
你尝试用LSTM预测等差数列的下一个数,但模型对测试数据输出恒定值,核心原因集中在数据处理、模型配置、训练设置三个方面,以下是具体问题和修复方案:
问题1:未执行数据归一化
代码中注释了# Normalize data但未实际执行归一化操作。LSTM对输入数据的数值范围非常敏感,等差数列的数值从0到199,跨度较大,模型在训练时容易快速收敛到训练数据的均值附近,导致输出恒定值。
修复方案:
使用MinMaxScaler将数据归一化到[0,1]区间,训练完成后再反归一化得到真实预测值。
问题2:训练轮次严重不足
仅训练4个epochs,对于LSTM学习简单的线性规律来说远远不够,模型还未完成规律学习就停止训练,只能输出近似均值的恒定值。
修复方案:
将epochs增加到20-50,根据训练损失的下降情况调整。
问题3:模型配置错误
- 冗余的LSTM层:预测等差数列这种简单时序任务,单层LSTM完全足够,两层LSTM反而增加模型复杂度,延缓收敛。
- 错误的评估指标:回归任务使用
accuracy指标完全无效,accuracy是分类任务的评估标准,回归任务应移除该指标,或使用mean_absolute_error等回归指标。
修复方案:
简化模型为单层LSTM,移除无效的accuracy指标。
修改后的完整代码
import numpy as np import pandas as pd import matplotlib.pyplot as plt import math from sklearn.preprocessing import MinMaxScaler from sklearn.metrics import mean_squared_error from keras.models import Sequential from keras.layers import LSTM, Dense dim = 5 data = pd.Series(range(0, 200)) # 划分训练测试集 training_data_len = math.ceil(len(data) * .8) train_data = data[:training_data_len] test_data = data[training_data_len:] print(train_data.shape, test_data.shape) # 数据归一化 scaler = MinMaxScaler(feature_range=(0, 1)) dataset_train_scaled = scaler.fit_transform(train_data.values.reshape(-1, 1)) dataset_test_scaled = scaler.transform(test_data.values.reshape(-1, 1)) # 构造训练序列 X_train = [] y_train = [] for i in range(dim, len(dataset_train_scaled)): X_train.append(dataset_train_scaled[i-dim:i, 0]) y_train.append(dataset_train_scaled[i, 0]) X_train, y_train = np.array(X_train), np.array(y_train) X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1)) print("X_train :", X_train.shape, "y_train :", y_train.shape) # 构造测试序列 X_test = [] y_test = [] for i in range(dim, len(dataset_test_scaled)): X_test.append(dataset_test_scaled[i-dim:i, 0]) y_test.append(dataset_test_scaled[i, 0]) X_test, y_test = np.array(X_test), np.array(y_test) X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1)) print("X_test :", X_test.shape, "y_test :", y_test.shape) # 构建简化版LSTM模型 regressorLSTM = Sequential() regressorLSTM.add(LSTM(dim, input_shape=(X_train.shape[1], 1))) regressorLSTM.add(Dense(1)) # 编译模型(移除无效的accuracy指标) regressorLSTM.compile(optimizer='adam', loss='mean_squared_error') # 增加训练轮次 regressorLSTM.fit(X_train, y_train, batch_size=1, epochs=30) regressorLSTM.summary() # 预测并反归一化得到真实值 y_LSTM_scaled = regressorLSTM.predict(X_test) y_LSTM = scaler.inverse_transform(y_LSTM_scaled) # 真实测试标签反归一化 y_test_true = scaler.inverse_transform(y_test.reshape(-1, 1)) # 绘图展示结果 plt.plot(train_data.index[dim:], train_data[dim:], label="train_data", color="b") plt.plot(test_data.index, test_data, label="test_data", color="g") plt.plot(test_data.index[dim:], y_LSTM, label="y_LSTM", color="orange") plt.legend() plt.xlabel("X") plt.ylabel("Y") plt.show() # 计算MSE评估模型效果 mse = mean_squared_error(y_test_true, y_LSTM) print(f"测试集MSE: {mse:.4f}")
修复后效果说明
修改后的代码会让LSTM快速学习到等差数列的规律,测试集的预测值会贴合真实的等差数列,不再输出恒定值。你可以根据实际训练损失调整epochs数量,当训练损失下降到接近0并稳定后即可停止训练。
内容的提问来源于stack exchange,提问作者ARIC9514
相关产品推荐
相关产品推荐

