多步 LSTM:为什么我每次预测都会得到相同的曲线/模式?

问题描述 投票:0回答:1

我是张量流和 LSTM 模型(以及一般编码)的新手,非常感谢一些帮助。我正在取得进展,但无论我尝试什么,我所做的每个预测似乎总是得到相同的模式。 Image of part of my predictions (not aligned on x axis currently)

您可以在图像中看到模型总是做出相同的猜测(向上、稍微向下、向下,然后与下一个预测的开始相链接。)

我会附上下面的代码。

第一次在这里发帖,非常感谢。如果我在网站规范方面犯了任何错误,请道歉。

import os
import numpy as np
import tensorflow as tf
from tensorflow import keras
import pandas as pd
import seaborn as sns
from pylab import rcParams
import matplotlib.pyplot as plt
from matplotlib import rc
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.layers import Bidirectional, Dropout, Activation, Dense, LSTM
from tensorflow.python.keras.layers import CuDNNLSTM
from tensorflow.keras.models import Sequential
#new below
from tensorflow.keras.callbacks import EarlyStopping

%matplotlib inline

sns.set(style='whitegrid', palette='muted', font_scale=1.5)

#rcParams['figure.figsize'] = 14, 8

#RANDOM_SEED = 42

#np.random.seed(RANDOM_SEED)

# Data comes from:
# https://finance.yahoo.com/quote/BTC-USD/history?period1=1279314000&period2=1556053200&interval=1d&filter=history&frequency=1d

csv_path = r"/home/paddycuinne/files/BTC-2021min.csv"

# csv_path = "https://raw.githubusercontent.com/curiousily/Deep-Learning-For-Hackers/master/data/3.stock-prediction/AAPL.csv"

df = pd.read_csv(csv_path, parse_dates=['date'])

df = df.sort_values('date')

df.head()

df.tail()

df.shape

ax = df.plot(x='date', y='close');
ax.set_xlabel("Month")
ax.set_ylabel("Close Price (USD)")

# Normalization

df['date'] = pd.to_datetime(df['date'])

df.set_index('date', inplace=True)

df



timestamp = '2021-12-31 00:01:00'

# Ensure the timestamp is present in the DataFrame's index
date_index = df.index.get_loc(timestamp)

data_train = df.loc[:'2021-12-31 00:01:00', :]['close']


#we are splitting the data weekly wise(7days)
SEQ_LEN = 30
steps_ahead = 3


X_train, y_train = [], []

#    start_index = SEQ_LEN
#    end_index = len(data_train) - steps_ahead

for i in range(SEQ_LEN, len(data_train) - steps_ahead):
    X_train.append(data_train[i - SEQ_LEN:i])        # Input sequence of length SEQ_LEN
    y_train.append(data_train[i:i + steps_ahead]) 
    
    
X_train, y_train = np.array(X_train), np.array(y_train)    

X_train.shape, y_train.shape

pd.DataFrame(X_train).head()


pd.DataFrame(y_train).head()

x_scaler = MinMaxScaler()
X_train = x_scaler.fit_transform(X_train)
#Normalising the dataset

y_scaler = MinMaxScaler()
y_train = y_scaler.fit_transform(y_train)

pd.DataFrame(X_train).head()



X_train = X_train.reshape((X_train.shape[0], X_train.shape[1], 1))
X_train.shape, y_train.shape

pd.DataFrame(y_train).head()



data_test = df.loc['2021-12-31 00:01:01':, 'close']
data_test.head()
data_test.shape



data_test = np.array(data_test)

X_test, y_test = [], []

for i in range(SEQ_LEN, len(data_test) - steps_ahead):
    X_test.append(data_test[i - SEQ_LEN:i])        # Input sequence of length SEQ_LEN
    y_test.append(data_test[i:i + steps_ahead]) 
    

X_test, y_test = np.array(X_test), np.array(y_test)
X_test.shape, y_test.shape

X_test = x_scaler.transform(X_test)
y_test = y_scaler.transform(y_test)
pd.DataFrame(X_test).head(), pd.DataFrame(y_test)

X_test = X_test.reshape((X_test.shape[0], X_test.shape[1], 1))
X_test.shape, y_test.shape

y_test


early_stopping = EarlyStopping(monitor='val_loss', mode='auto', verbose=1, patience=20, restore_best_weights=True)

DROPOUT = 0.1
WINDOW_SIZE = SEQ_LEN - 1
#2048
#32
model = Sequential()
model.add(Bidirectional(LSTM(100, return_sequences=True, input_shape=(X_train.shape[1],X_train.shape[2]))))
model.add(Dropout(rate=DROPOUT))
model.add(Bidirectional(LSTM(100)))
model.add(Dropout(rate=DROPOUT))
model.add(Dense(units=steps_ahead))

model.compile(loss='mean_squared_error', optimizer='adam')
history = model.fit(X_train, y_train, epochs=100, batch_size=32, verbose=1,validation_data=(X_test, y_test), callbacks=[early_stopping])

print("Shape of y_pred:", y_pred.shape)
print("Shape of y_pred_2d:", y_pred_2d.shape)
print("Shape of scaler min_:", y_scaler.min_.shape)
print("Shape of scaler scale_:", y_scaler.scale_.shape)
print(df.head())


import plotly.graph_objects as go

fig = go.Figure()

#transform y test

y_pred = model.predict(X_test)
y_pred_2d = y_pred
y_hat_inverse = y_scaler.inverse_transform(y_pred_2d)

#realign for lookback and for forecast

#plot

fig.add_trace(go.Scatter(x=df.index, y=df['close'],
                         mode='lines',
                         name='Original Data'))


#for y_test_inverse[:5]
   # xaxis = xtest[:5]

#X_test_inverse[:5]
# Calculate the indices for the test and predicted values
#start_idx_y_test = int(0.7 * len(df)) + SEQ_LEN - 1
#start_idx_predicted = start_idx_y_test + steps_ahead - 1

# Get the dates for the test and predicted values
#test_dates_y_test = df['Month'].iloc[start_idx_y_test : start_idx_y_test + len(y_test_inverse)]
#test_dates = df['Month'].iloc[start_idx_predicted : start_idx_predicted + len(y_hat_inverse)]
#new

test_dates = df.loc['2021-12-31 00:01:01':].index



y_hat_inverse_flat = y_hat_inverse.flatten()
#y_test_selected = y_test_inverse_flat[::5]
#y_hat_selected = y_hat_inverse_flat[::5]
def extract_blocks(arr):
    blocks = []
    length = len(arr)
    for i in range(0, length, 9):
        blocks.extend(arr[i:i+3])
    return blocks
#was 25, 5

y_hat_selected = extract_blocks(y_hat_inverse_flat)



#fig.add_trace(go.Scatter(x=test_dates, y=y_hat_selected2,
#                         mode='lines+markers',
#                         name='Predicted Values 2'))

#from dateutil.relativedelta import relativedelta

#shifted_dates = [date - relativedelta(months=SEQ_LEN) for date in test_dates]


fig.add_trace(go.Scatter(x=test_dates, y=y_hat_selected,
                         mode='lines+markers',
                         name='Predicted Values real'))


fig.update_layout(title='Passenger Count Over Time with Test Data',
                  xaxis_title='Month',
                  yaxis_title='Passenger Count')

#########################




#fig.add_trace(go.Scatter(x=test_dates, y=y_hat_inverse.flatten(),
#                         mode='lines+markers',
#                         name='Predicted Values'))




fig.show()

我知道比特币价格很难预测,而且我知道在我获得具有任何严重预测能力的任何东西之前,我需要添加大量其他输入(交易量等)。我只是希望在继续之前解决这个问题。我的理解是,至少在趋势上,它应该能够对持续下降或上升的轨迹做出模糊的猜测。

几乎感觉模型正在做出一组 5 个预测(就模式而言),并尝试将其拟合到数据。

我在 jupyter 笔记本、anaconda、wsl 中运行。

我用谷歌搜索,查看了堆栈溢出,并尝试了 chatgpt 等。在这个特定问题上找不到太多信息。

我觉得我可能遗漏了一些明显的东西。 :/

我希望为每 3 个未来步骤获得一个预测,对于每个图形化的预测集,该预测都是唯一的,并且是从前 30 个步骤中得出的。对于上下文,我尝试以多种方式重写测试/训练分割,我尝试通过以下方式更改模型。

-神经元数量在 1 到 1024 之间的各个级别 -我尝试过添加多个图层。 -不同的批量大小 - 不同数量的纪元,最多 1000 秒 - 双向和正常 -其他各种小变化

keras lstm tensorflow2.0 bitcoin multi-step
1个回答
0
投票

你的第二个 lstm 层应该是 return_sequences=False

model = Sequential()
model.add(Bidirectional(LSTM(100, return_sequences=True, input_shape=(X_train.shape[1],X_train.shape[2]))))
model.add(Dropout(rate=DROPOUT))
model.add(Bidirectional(LSTM(100,return_sequences=False)))
model.add(Dropout(rate=DROPOUT))
model.add(Dense(units=steps_ahead))

model.compile(loss='mean_squared_error', optimizer='adam')
history = model.fit(X_train, y_train, epochs=100, batch_size=32, verbose=1,validation_data=(X_test, y_test), callbacks=[early_stopping])


model.evaluate(X_test, y_test)

plt.plot(history.history['loss'])
plt.title('loss accuracy')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'test'], loc='upper left')
plt.show()
© www.soinside.com 2019 - 2024. All rights reserved.