我正在努力训练RNN来预测未来的股票价格。
我的目标是使用两个数据集训练模型:X_train和y_train。
X_train是一个3D数组,包括(观察次数,前蜡烛数,每个蜡烛的属性)
y_train是一个3D数组,包括(观测数量,未来观测数量,价格)。
因此,如果我有来自500支蜡烛的数据,我的X_train将是(430,60,6):对于430次观察(每次当前的蜡烛),取得之前的60次观察和6种特征(收盘价,体积等) 。)他们并尝试使用该数据(通过RNN)预测y_train(430,10,1):430观察预测接下来的10支蜡烛的收盘价(对应于1)。 在我的生活中,我无法获得正确进入模型的尺寸。 我为模型使用以下代码:
regressor = Sequential()
regressor.add(LSTM(units = 50, return_sequences = True, input_shape = (
X_train.shape[1], 6)))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units = 50, return_sequences = True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units = 50, return_sequences=True))
regressor.add(Dropout(0.2))
regressor.add(LSTM(units = 1))
regressor.compile(optimizer = 'adam', loss = 'mean_squared_error')
regressor.fit(X_train, y_train, epochs = 20, batch_size = 32)
我得到ValueError: Error when checking target: expected lstm_6 to have 2 dimensions, but got array with shape (430, 10, 1)
非常感谢。
答案 0 :(得分:4)
让我们在这里退后一步,看看做了什么以及为什么它不起作用。
首先,您的输入数据具有以下形状:
(samples, timesteps, features)
其次,您希望您的outbut数据具有以下形状:
(samples, future_timesteps, 1)
这种架构称为sequence to sequence learning(通俗地称为Seq2Seq)。
那么我们如何做Seq2Seq呢?有几种方法可能需要阅读,这仍然是一个非常活跃的研究领域。以下是一些想法。
请注意,这是使用keras functional api完成的。它更好。
从两个方向读取输入序列,然后通过最终密集层为30个单位来预测接下来的30个单位。
input_layer = Input(shape=(600,6,))
lstm = Bidirectional(
LSTM(250),
merge_mode='concat'
)(input_layer)
pred = Dense(10)(lstm)
model = Model(inputs=input_layer, outputs=pred)
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
model.fit(X_train, Y_train, epochs = 20, batch_size = 32)
其中Y_train
被重新整形为(430, 10)
而不是(430, 10, 1)
。在回复评论时,这不会以任何有意义的方式改变标签(Y_train
)。这是因为(x,y,1)和(x,y)之间的差异如下:
[[[1],[2],[3]],
[[4],[5],[6]]]
而不是
[[1,2,3],
[4,5,6]]
这样的电话如下:
Y_train = np.reshape(Y_train, Y_train.shape[:2])
对训练数据没有任何影响。
但是,这可能不是最好的架构。这是因为单个致密层将从前向和后向引入最后隐藏状态,而不是在每个时间步进入每个隐藏状态(从两个方向)。实际上,上述模型并未意识到以下模型中提供的更多信息。我建议以下作为替代方案。
input_layer = Input(shape=(600,6,))
encoder = Bidirectional(
LSTM(250),
merge_mode='concat',
return_sequences=True
)(input_layer)
decoder = LSTM(250, return_sequences=True)(encoder)
pred = TimeDistributed(Dense(1))(decoder)
model = Model(inputs=input_layer, outputs=pred)
model.compile(optimizer = 'adam', loss = 'mean_squared_error')
model.fit(X_train, Y_train, epochs = 20, batch_size = 32)
其中Y_train
的格式为(430, 60, 1)
。如果您只关心下一个10
条目,请将sample weighting
调整为适合并将10th
时间索引后的所有内容加权为0
(您甚至可以使用垃圾填充它,如果你想要的训练)。这将按如下方式完成:
Y_train = np.hstack([Y_train]*6)
然后你会创建一个样本权重掩码,如:
W = np.zeros(Y_train.shape)
W[:,np.arange(W.shape[1]) < 10,:] = 1
即,只有沿第二轴的前10个条目为1,而所有其他条目为零的掩码。将此W
作为sample_weights
model.fit
参数传递
这样,模型可以在编码器/解码器范例中具有序列概念的真实序列。
最后,并不是额外的LSTMS(堆叠)是必要的坏,但它被认为是改善这种性质的模型的最佳增量,并且确实增加了大量的复杂性以及严重增加的训练时间。获得单个模型以使用1的重复深度(无堆叠),然后您可以在我给你的第二个结构中堆叠单个lstm或堆叠编码器/解码器。
您正在做的一些其他提示:
我希望这有帮助!