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)
问题:我不知道如何着手,尤其是如何整合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.
)
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用于生成序列就像预测下一个元素一样.
您只需要序列中的一些元素并尝试查找下一个元素.而你又向前迈出了一步,依此类推.这可能有助于生成序列.
归档时间: |
|
查看次数: |
18054 次 |
最近记录: |