TensorFlow LTC价格预测模型多轮训练后输出呈直线问题排查
莱特币价格预测模型训练异常排查
我用TensorFlow搭建模型预测LTC未来100步价格,已加载1000条训练数据,模型的搭建、保存、加载流程都正常,但训练7-10轮后,模型输出变成一条直线。附上模型代码、首轮训练输出图和多轮训练后的输出图,求排查原因。
模型代码
df = df[['y', 'h', 'o', 'l']] # ,'t' df2 = df.values print(len(df)) training = int(np.ceil(len(df) * .95)) print(training) # quit() # prepere data for tensorflow # MinMaxScaler expecting like 1 feature scaler = MinMaxScaler(feature_range=(0, 1)) scaled_data = scaler.fit_transform(df) print(f"scaled_data {len(scaled_data)}") # How many past days of data we want to use to predict the next day price prediction_days = 500 train_data = scaled_data[0:int(training), :] print(f"train_data {len(train_data)}") # Preparing the Training data X_train = [] y_train = [] X_test = [] y_test = [] for x in range(prediction_days, len(train_data)): X_train.append(scaled_data[x - prediction_days:x, 0]) y_train.append(scaled_data[x, 0]) X_test.append(scaled_data[x - prediction_days:x, 0]) y_test.append(scaled_data[x, 0]) X_train, y_train = np.array(X_train), np.array(y_train) X_test, y_test = np.array(X_test), np.array(y_test) # Reshaping so that it will work in Neural net X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1)) X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1)) print(X_train.shape) print(y_train.shape) print("Files") print(os.path.isfile('model.h5')) if os.path.isfile('model.h5') is False: model = Sequential() model.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1))) model.add(Dropout(0.2)) model.add(LSTM(units=50, return_sequences=True)) model.add(Dropout(0.2)) model.add(LSTM(units=50)) model.add(Dropout(0.2)) model.add(Dense(units=100)) # define the optimization algorithm # best learning rate for opt = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0) model.compile(optimizer=opt, loss='mean_squared_error') model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test)) #, callbacks=[keras.callbacks.LearningRateScheduler(lambda epoch: 1e-8 * 10 ** (epoch / 30))] # evaluate the model model.save('model.h5') #del model model = load_model('model.h5') # loss, accuracy = my_model.evaluate(X_test, y_test) # print(f"accuracy: {accuracy * 100:.2f}%") model_json = model.to_json() with open("model.json", "w") as json_file: json_file.write(model_json) model.save_weights('model_weight.h5') model.load_weights('model_weight.h5') else: # load json and create model json_file = open('model.json', 'r') loaded_model_json = json_file.read() json_file.close() model = model_from_json(loaded_model_json) # load weights into new model model.load_weights("model.h5") print("Loaded model from disk") opt = Adam(lr=0.01, beta_1=0.9, beta_2=0.999, epsilon=1e-08, decay=0.0) model.compile(optimizer=opt, loss='mean_squared_error') # train the model, iterating on the data in batches model.fit(X_train, y_train, epochs=5, validation_data=(X_test, y_test)) # callbacks=[keras.callbacks.LearningRateScheduler(lambda epoch: 1e-8 * 10 ** (epoch / 30))] # evaluate the model model_json = model.to_json() with open("model.json", "w") as json_file: json_file.write(model_json) model.save_weights('model_weight.h5') model.load_weights('model_weight.h5') test_data = 60 # actual_prices = df.values total_dataset = df.values print(f"Counter") model_inputs = total_dataset[len(total_dataset) - test_data - prediction_days:] model_inputs = model_inputs.reshape(-1, 1) model_inputs = scaler.fit_transform( model_inputs) # ValueError: X has 1 features, but MinMaxScaler is expecting 4 features as input. real_data = [model_inputs[len(model_inputs) - prediction_days: len(model_inputs) + 1, 0]] # len of real_data = 101 real_data = np.array(real_data) real_data = np.reshape(real_data, (real_data.shape[0], real_data.shape[1], 1)) # reshape real_data to (100, 100, 1) prediction = model.predict(real_data) # evaluation metrics prediction = scaler.inverse_transform(prediction) prediction = prediction.reshape(-1, 1) # plot # plt.plot(df, color='green') plt.plot(prediction, color='green') plt.legend() plt.show()
训练输出对比
- 首轮训练输出:

- 7-10轮训练输出:

问题排查与解决建议
- 学习率过高:当前设置的Adam学习率为0.01,对于LSTM这类序列模型来说偏大,容易导致训练后期梯度爆炸,模型直接收敛到固定值。建议将学习率调整为0.001或更低,或者添加学习率衰减策略(比如每轮按比例降低)。
- 训练/测试集完全重叠:代码里X_train和X_test用的是同一批数据,等于用训练数据做验证,完全无法检测过拟合。正确做法是把训练集之后的独立数据作为测试集,比如
test_data = scaled_data[training:, :],再单独构建X_test和y_test。 - 特征与归一化不匹配:你对包含4个特征的df做了归一化,但后续只取第一个特征(y)作为模型输入,不仅浪费了h、o、l的信息,还导致预测阶段出现维度不匹配的错误。如果只使用y特征,应该仅对df['y']做归一化;如果要用上所有特征,模型输入维度要对应修改(把reshape的最后一维改成4)。
- 预测阶段归一化错误:预测时重新调用
scaler.fit_transform(model_inputs)会覆盖训练时的归一化参数,导致逆变换结果失真。应该直接用训练好的scaler做transform,即model_inputs = scaler.transform(model_inputs)。 - 输出层设计不合理:任务是预测未来100步价格,但当前输出层是Dense(100),如果是逐次单步预测,输出层应该设为Dense(1),然后循环预测100次;如果是直接多步预测,需要调整输入输出的维度对应关系,否则模型无法学习到序列变化规律,最终输出直线。
内容的提问来源于stack exchange,提问作者Lubomir
相关产品推荐
相关产品推荐

