LSTM自动编码器 [英] LSTM Autoencoder

查看:1150
本文介绍了LSTM自动编码器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试构建LSTM自动编码器,其目的是从序列中获得固定大小的矢量,该矢量尽可能代表序列.该自动编码器包括两个部分:

I'm trying to build a LSTM autoencoder with the goal of getting a fixed sized vector from a sequence, which represents the sequence as good as possible. This autoencoder consists of two parts:

  • LSTM编码器:采用序列并返回输出向量(return_sequences = False)
  • LSTM解码器:获取输出向量并返回序列(return_sequences = True)
  • LSTM Encoder: Takes a sequence and returns an output vector (return_sequences = False)
  • LSTM Decoder: Takes an output vector and returns a sequence (return_sequences = True)

因此,最后,编码器是一对多 LSTM,而解码器是一对多 LSTM.

So, in the end, the encoder is a many to one LSTM and the decoder is a one to many LSTM.

图片来源: Andrej Karpathy

从高层次看,编码看起来像这样(类似于此处所述):

On a high level the coding looks like this (similar as described here):

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),看起来像这样:

The shape (number of training examples, sequence length, input dimension) of the data array is (1200, 10, 5) and looks like this:

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以及如何使解码器从向量生成序列.

Problem: I am not sure how to proceed, especially how to integrate LSTM to Model and how to get the decoder to generate a sequence from a vector.

我正在将kerastensorflow后端一起使用.

I am using keras with tensorflow backend.

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

If someone wants to try out, here is my procedure to generate random sequences with moving ones (including padding):

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.
)

推荐答案

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

Models can be any way you want. If I understood it right, you just want to know how to create models with LSTM?

使用LSTM

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

Well, first, you have to define what your encoded vector looks like. Suppose you want it to be an array of 20 elements, a 1-dimension vector. So, shape (None,20). The size of it is up to you, and there is no clear rule to know the ideal one.

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

And your input must be three-dimensional, such as your (1200,10,5). In keras summaries and error messages, it will be shown as (None,10,5), as "None" represents the batch size, which can vary each time you train/predict.

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

There are many ways to do this, but, suppose you want only one LSTM layer:

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个元素的数组(但是如果需要,您可以堆叠更多的层).让我们创建模型:

This is enough for a very very simple encoder resulting in an array with 20 elements (but you can stack more layers if you want). Let's create the model:

encoder = Model(inpE,outE)   

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

Now, for the decoder, it gets obscure. You don't have an actual sequence anymore, but a static meaningful vector. You may want to use LTSMs still, they will suppose the vector is a sequence.

但是在这里,由于输入的形状为(None,20),因此必须首先将其重新成形为某些3维数组,然后才能附加LSTM层.

But here, since the input has shape (None,20), you must first reshape it to some 3-dimensional array in order to attach an LSTM layer next.

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

The way you will reshape it is entirely up to you. 20 steps of 1 element? 1 step of 20 elements? 10 steps of 2 elements? Who knows?

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

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

It's important to notice that if you don't have 10 steps anymore, you won't be able to just enable "return_sequences" and have the output you want. You'll have to work a little. Acually, it's not necessary to use "return_sequences" or even to use LSTMs, but you may do that.

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

Since in my reshape I have 10 timesteps (intentionally), it will be ok to use "return_sequences", because the result will have 10 timesteps (as the initial input)

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

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

You could work in many other ways, such as simply creating a 50 cell LSTM without returning sequences and then reshaping the result:

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

我们的模型变为:

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

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

After that, you unite the models with your code and train the autoencoder. All three models will have the same weights, so you can make the encoder bring results just by using its predict method.

encoderPredictions = encoder.predict(data)


我经常会看到有关LSTM生成序列的信息,就像预测下一个元素一样.


What I often see about LSTMs for generating sequences is something like predicting the next element.

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

You take just a few elements of the sequence and try to find the next element. And you take another segment one step forward and so on. This may be helpful in generating sequences.

这篇关于LSTM自动编码器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆