我正在尝试构建一个 LSTM 自动编码器,目标是从一个序列中获取一个固定大小的向量,它尽可能好地表示该序列。这个自动编码器由两部分组成:
LSTM
编码器:获取一个序列并返回一个输出向量(return_sequences = False
)LSTM
解码器:获取一个输出向量并返回一个序列(return_sequences = True
)
所以,最后,编码器是 多对一的 LSTM,解码器是 一对多 的 LSTM。
图片来源: Andrej Karpathy
在高层次上,编码看起来像这样(类似于 此处 描述的):
encoder = Model(...)
decoder = Model(...)
autoencoder = Model(encoder.inputs, decoder(encoder(encoder.inputs)))
autoencoder.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
autoencoder.fit(data, data,
batch_size=100,
epochs=1500)
data
数组的形状(训练示例数、序列长度、输入维度)是 (1200, 10, 5)
并且看起来像这样:
array([[[1, 0, 0, 0, 0],
[0, 1, 0, 0, 0],
[0, 0, 1, 0, 0],
...,
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0],
[0, 0, 0, 0, 0]],
... ]
问题: 我不确定如何进行,尤其是如何将 LSTM
集成到 Model
以及如何让解码器从向量生成序列。
我正在使用 keras
和 tensorflow
后端。
编辑: 如果有人想尝试,这是我生成带有移动序列(包括填充)的随机序列的程序:
import random
import math
def getNotSoRandomList(x):
rlen = 8
rlist = [0 for x in range(rlen)]
if x <= 7:
rlist[x] = 1
return rlist
sequence = [[getNotSoRandomList(x) for x in range(round(random.uniform(0, 10)))] for y in range(5000)]
### Padding afterwards
from keras.preprocessing import sequence as seq
data = seq.pad_sequences(
sequences = sequence,
padding='post',
maxlen=None,
truncating='post',
value=0.
)
原文由 ScientiaEtVeritas 发布,翻译遵循 CC BY-SA 4.0 许可协议
模型可以是您想要的任何方式。如果我没理解错的话,你只是想知道如何使用 LSTM 创建模型?
使用 LSTM
好吧,首先,您必须定义编码后的矢量的外观。假设您希望它是一个包含 20 个元素的数组,一个一维向量。所以,形状(无,20)。它的大小由您决定,没有明确的规则可以知道理想的大小。
而且你的输入必须是三维的,比如你的(1200,10,5)。在 keras 摘要和错误消息中,它将显示为 (None,10,5),因为“None”代表批量大小,每次训练/预测时都会有所不同。
有很多方法可以做到这一点,但是,假设您只需要一个 LSTM 层:
这对于一个非常非常简单的编码器来说已经足够了,它会产生一个包含 20 个元素的数组(但如果你愿意,你可以堆叠更多层)。让我们创建模型:
现在,对于解码器,它变得晦涩难懂。你不再有一个实际的序列,而是一个静态的有意义的向量。您可能仍想使用 LTSM,它们会假设向量是一个序列。
但在这里,由于输入的形状为 (None,20),您必须首先将其重新整形为某个 3 维数组,以便接下来附加 LSTM 层。
重塑它的方式完全取决于您。 1个元素20步? 20 个元素的 1 步? 2 个元素的 10 个步骤?谁知道?
重要的是要注意,如果您不再有 10 个步骤,您将无法仅启用“return_sequences”并获得您想要的输出。你将不得不工作一点。实际上,没有必要使用“return_sequences”,甚至没有必要使用 LSTM,但您可以这样做。
因为在我的重塑中我有 10 个时间步长(有意),所以可以使用“return_sequences”,因为结果将有 10 个时间步长(作为初始输入)
您可以通过许多其他方式工作,例如简单地创建一个 50 个单元的 LSTM 而不返回序列,然后重塑结果:
我们的模型是:
之后,您将模型与您的代码结合起来并训练自动编码器。所有三个模型都将具有相同的权重,因此您只需使用其
predict
方法即可使编码器带来结果。我经常看到的用于生成序列的 LSTM 类似于预测下一个元素。
您只取序列中的几个元素并尝试找到下一个元素。然后您将另一部分向前迈出一步,依此类推。这可能有助于生成序列。