LSTM自动编码器
deep-learning
keras
machine-learning
python
6
0

我正在尝试构建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以及如何使解码器从向量生成序列。

我正在使用带有tensorflow后端的keras

编辑:如果有人想尝试,这是我的过程,以生成带有移动序列(包括填充)的随机序列:

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.
)
参考资料:
Stack Overflow
收藏
评论
共 2 个回答
高赞 时间 活跃

您可以在此处找到一个简单的序列来对自动编码器进行排序: https ://blog.keras.io/building-autoencoders-in-keras.html

收藏
评论

模型可以是您想要的任何方式。如果我理解正确,那么您只是想知道如何使用LSTM创建模型?

使用LSTM

好吧,首先,您必须定义编码矢量的外观。假设您希望它是20个元素的数组,即1维向量。因此,形状(无,20)。它的大小取决于您,没有明确的规则可以了解理想的规则。

并且您的输入必须是三维的,例如(1200,10,5)。在keras摘要和错误消息中,它将显示为(None,10,5),因为“ None”表示批次大小,每次训练/预测时批次大小可能会有所不同。

有很多方法可以做到这一点,但是,假设您只需要一个LSTM层:

from keras.layers import *
from keras.models import Model

inpE = Input((10,5)) #here, you don't define the batch size   
outE = LSTM(units = 20, return_sequences=False, ...optional parameters...)(inpE)

对于一个非常简单的编码器来说,这足以生成一个包含20个元素的数组(但是如果需要,您可以堆叠更多的层)。让我们创建模型:

encoder = Model(inpE,outE)   

现在,对于解码器,它变得晦涩难懂。您不再有实际的序列,而是静态的有意义的向量。您可能仍要使用LTSM,它们将假定向量是一个序列。

但是在这里,由于输入的形状为(None,20),因此必须首先将其重塑为3维数组,然后再附加LSTM层。

重塑的方式完全取决于您。 1个元素的20个步骤? 1个步骤(共20个元素)? 2个元素的10个步骤?谁知道?

inpD = Input((20,))   
outD = Reshape((10,2))(inpD) #supposing 10 steps of 2 elements    

重要的是要注意,如果您不再有10个步骤,您将无法仅启用“ return_sequences”并获得所需的输出。您将需要工作一点。从根本上讲,不必使用“ return_sequences”,甚至不必使用LSTM,但是您可以这样做。

由于在重塑中,我有10个时间步长(有意地),因此可以使用“ return_sequences”,因为结果将有10个时间步长(作为初始输入)

outD1 = LSTM(5,return_sequences=True,...optional parameters...)(outD)    
#5 cells because we want a (None,10,5) vector.   

您可以采用许多其他方式进行工作,例如仅创建50个单元的LSTM而无需返回序列,然后重塑结果:

alternativeOut = LSTM(50,return_sequences=False,...)(outD)    
alternativeOut = Reshape((10,5))(alternativeOut)

我们的模型是:

decoder = Model(inpD,outD1)  
alternativeDecoder = Model(inpD,alternativeOut)   

之后,将模型与代码结合在一起并训练自动编码器。这三个模型都具有相同的权重,因此您可以使编码器仅使用其predict方法即可带来结果。

encoderPredictions = encoder.predict(data)

我经常看到的用于生成序列的LSTM类似于预测下一个元素。

您只需要序列中的几个元素,然后尝试查找下一个元素。然后您又向前迈出了另一段,依此类推。这可能有助于生成序列。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号