我一直在尝试构建一个简单的LSTM网络来预测标普500未来5个值的百分比变化。然而,我的神经网络输出的几乎是一条完全平坦的线。
我知道我永远不应该在训练集上检查我的模型,但这只是一个健全性检查,看看它是否至少能工作。
sc = MinMaxScaler(feature_range=(0,1))dataset = dataset[5:-1]dataset = dataset.dropna()close = sc.fit_transform(dataset['Close'].values.reshape(-1,1))volume = sc.fit_transform(dataset['Volume'].values.reshape(-1,1))pct = sc.fit_transform(dataset['pct5'].values.reshape(-1,1))close_train = []volume_train = []y = []pc = []leng = 60for i in range(leng, len(close)): close_train.append(close[i - 60 : i, 0]) volume_train.append(volume[i - 60 : i, 0]) y.append(close[i, 0]) pc.append(pct[i, 0])close_train = np.array(close_train, dtype=np.float64)volume_train = np.array(volume_train, dtype=np.float64)y = np.array(y)pc = np.array(pc, dtype=np.float64) #This is just adjusted pct in case you got lostclose_train = np.reshape(close_train, (close_train.shape[0], close_train.shape[1], 1))volume_train = np.reshape(volume_train, (volume_train.shape[0], volume_train.shape[1], 1))def buildModel(dataLength, labelLength): price = Input(shape=(dataLength, 1), name='price') volumen = Input(shape=(dataLength, 1), name='volumen') priceLayers1 = LSTM(60, return_sequences=True)(price) volumeLayers1 = LSTM(60, return_sequences=True)(volumen) priceLayers2 = LSTM(60, return_sequences=True)(price) volumeLayers2 = LSTM(60, return_sequences=True)(volumen) priceLayers3 = LSTM(60, return_sequences=False)(price) volumeLayers3 = LSTM(60, return_sequences=False)(volumen) output = concatenate( [ price, volumen ] ) output = Dense(1, activation='linear', name='dense')(output) model = Model( [ price, volumen ], [ output ] ) opt = tf.keras.optimizers.Adam(learning_rate=0.001) model.compile(optimizer=opt, loss='mse') print(output) return modelrnn = buildModel(60, 4)hist = rnn.fit( [ close_train, volume_train ], [ pc ], epochs = 100, batch_size=50)nsamples, nx, ny = close_train.shapetest_close = close_train.reshape((nsamples,nx*ny))test_vol = volume_train.reshape((nsamples,nx*ny))pred = rnn.predict([test_close[0, :60], test_vol[0, :60]])print(pred_dim)pred1 = sc.inverse_transform(pred_dim)final = []for i in range(0, len(pred1)+60): if i <60: final.append(None) continue final.append(pred1[i-60, 0])plt.figure(figsize=(30,20))plt.plot(dataset['pct5'])plt.plot(final, c='r')plt.axvline(60, c='r')print(final)
附注:我并不期望它能准确工作,因为这几乎是不可能的,但我希望它至少能工作,这样我就可以继续下一步了 🙂
回答:
您在问题中展示的模型目前是一个输入的线性回归。
即:
output = Dense(1, activation='linear', name='dense')(concatenate[price, volume])
我怀疑这个模型能做的最好的事情就是预测一个平均值… 它可能会将权重尽可能接近0设置,并且将偏置设置为信号的平均值。
您可能想要编写的是类似于下面的内容:
def buildModel(dataLength, labelLength): price = Input(shape=(dataLength, 1), name='price') volumen = Input(shape=(dataLength, 1), name='volumen') priceLayers1 = LSTM(60, return_sequences=True)(price) volumeLayers1 = LSTM(60, return_sequences=True)(volumen) priceLayers2 = LSTM(60, return_sequences=True)(priceLayers1) volumeLayers2 = LSTM(60, return_sequences=True)(volumeLayers1) priceLayers3 = LSTM(60, return_sequences=False)(priceLayers2) volumeLayers3 = LSTM(60, return_sequences=False)(volumeLayers2) x = Concatenate()([priceLayers3, volumeLayers3]) output = Dense(1, activation='linear', name='dense')(x) model = tf.keras.Model([price, volumen], output) model.compile(optimizer='adam', loss='mse') return model