我还在研究 LSTM,并试图找到最佳和合适的训练流程和数据形状。
一个时间序列代表音乐音符,我们称之为一首歌。因此,我的数据形式如下。该序列由独热编码的音符组成,因此它们的形状为 (timesteps, features)
。通过转调(提高音符)将该序列复制十二次。一首歌的形状将变为 (12, timesteps, features)
。这十二个序列中的每一个都应该独立进行训练。此外,还有多首歌曲,长度各不相同。
我想训练一个 LSTM,使其在序列的每一步都进行预测。因此,十二个序列之一的训练数据将是 X = series[:-1, :], Y = series[1:, :]
,其他十二个版本的训练数据也是如此。
# 示例数据,为了简洁起见,数字未进行独热编码
series = [1, 3, 2, 4, 7, 7, 10]
X = [1, 3, 2, 4, 7, 7]
Y = [3, 2, 4, 7, 7, 10] # 向后移动一步
这十二个变体会自然形成一个批次,因为长度不变。但我的问题是:能否安排训练,使这些变体作为一个十二个的批次输入到网络中,但训练是以多对多的方式进行的?(每一步预测一次)
目前我有一个似乎是简单的方法,适用于单个示例。它一次一个时间步将数据输入到网络中,并在中间保留状态:
# X = (12 * timesteps, 1, features), Y = (12 * timesteps, features)
model = Sequential()
model.add(LSTM(256, input_shape=(None, X.shape[-1]), batch_size=1, stateful=True))
model.add(Dense(Y.shape[-1], activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['categorical_accuracy'])
for epoch in range(10):
model.fit(X, Y, epochs=1, batch_size=1, shuffle=False)
model.reset_states()
如何为包含十二个变体的单首歌曲实现上述训练方案?
回答:
正如你在评论中提到的,你需要将 LSTM 层包装在 TimeDistributed
内。这样,每个十二个变体将被单独处理。此外,由于每个特征向量都是独热编码的,我们在网络的最后一层添加了一个带有 softmax
激活函数的 Dense 层:
from keras import models, layers
n_features = 20
model_input = layers.Input(shape=(12, None, n_features))
x = layers.TimeDistributed(layers.LSTM(64, return_sequences=True))(model_input)
model_output = layers.Dense(n_features, activation='softmax')(x)
model = models.Model([model_input], [model_output])
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')
model.summary()
以下是模型摘要:
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 12, None, 20) 0
_________________________________________________________________
time_distributed_1 (TimeDist (None, 12, None, 64) 21760
_________________________________________________________________
dense_1 (Dense) (None, 12, None, 20) 1300
=================================================================
Total params: 23,060
Trainable params: 23,060
Non-trainable params: 0
_________________________________________________________________
请注意,这个模型对于你的问题可能过于简单。你可能希望堆叠更多的 LSTM 层,并根据你试图解决的具体问题调整参数以获得更好的准确性(最后你必须进行实验!);但它为你提供了一个在这种情况下模型可能是什么样的粗略概念。虽然这看起来可能有些不相关,但我建议你阅读 Keras 官方博客中的 Seq2Seq 教程,以获得更多这方面的想法。
作为补充说明,如果你使用的是 GPU,那么你可以使用 CuDNNLSTM 层代替 LSTM;它在 GPU 上性能更好。