LSTM自动编码器

Sci*_*tas 31 python machine-learning deep-learning keras tensorflow

我正在尝试构建一个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)
Run Code Online (Sandbox Code Playgroud)

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]],
        ... ]
Run Code Online (Sandbox Code Playgroud)

问题:我不知道如何着手,尤其是如何整合LSTMModel以及如何解码器生成的矢量的序列.

我使用kerastensorflow后端.

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

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.
)
Run Code Online (Sandbox Code Playgroud)

Dan*_*ler 24

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

使用LSTM

那么,首先,你必须定义你的编码矢量的样子.假设您希望它是一个包含20个元素的数组,即一维向量.形状(无,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)
Run Code Online (Sandbox Code Playgroud)

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

encoder = Model(inpE,outE)   
Run Code Online (Sandbox Code Playgroud)

现在,对于解码器来说,它变得模糊不清.你不再有一个实际的序列,而是一个静态有意义的向量.您可能仍想使用LTSM,他们会假设矢量是一个序列.

但是在这里,由于输入具有形状(无,20),因此必须先将其重新整形为某个三维数组,以便接下来附加LSTM图层.

你重塑它的方式完全取决于你.20个步骤的1个元素?1步20元素?2个元素的10个步骤?谁知道?

inpD = Input((20,))   
outD = Reshape((10,2))(inpD) #supposing 10 steps of 2 elements    
Run Code Online (Sandbox Code Playgroud)

重要的是要注意,如果你不再有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.   
Run Code Online (Sandbox Code Playgroud)

您可以通过许多其他方式工作,例如只需创建一个50单元LSTM而无需返回序列,然后重新整形结果:

alternativeOut = LSTM(50,return_sequences=False,...)(outD)    
alternativeOut = Reshape((10,5))(alternativeOut)
Run Code Online (Sandbox Code Playgroud)

我们的模型是:

decoder = Model(inpD,outD1)  
alternativeDecoder = Model(inpD,alternativeOut)   
Run Code Online (Sandbox Code Playgroud)

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

encoderPredictions = encoder.predict(data)
Run Code Online (Sandbox Code Playgroud)

我经常看到的LSTM用于生成序列就像预测下一个元素一样.

您只需要序列中的一些元素并尝试查找下一个元素.而你又向前迈出了一步,依此类推.这可能有助于生成序列.


use*_*745 6

你可以在这里找到一个简单的序列来自动编码:https://blog.keras.io/building-autoencoders-in-keras.html


归档时间:

查看次数:

18054 次

最近记录:

7 年,6 月 前