时序数据的表征学习方法(四)——LSTM自编码器

  • 2020 年 12 月 17 日
  • AI

//machinelearningmastery.com/lstm-autoencoders/machinelearningmastery.com

原文来自:

LSTM自动编码器是使用编码器-解码器LSTM体系结构的序列数据自动编码器的实现。

拟合后,模型的编码器部分可用于编码或压缩序列数据,而序列数据又可用于数据可视化或用作监督学习模型的特征向量输入。

序列预测问题极具挑战性,不仅因为输入序列的长度可能会变化(这具有挑战性,因为机器学习算法(尤其是神经网络)被设计为与固定长度的输入配合使用。)

序列数据的另一个挑战是,观测的时间顺序可能使提取适合用作监督学习模型输入的特征具有挑战性,而这些特征通常需要在信号处理领域或信号处理领域具有深厚的专业知识

LSTM自动编码器是使用编码器-解码器LSTM体系结构的序列数据自动编码器的实现。

对于给定的序列数据集,编码器/解码器LSTM配置为读取输入序列,对其进行编码,对其进行解码并重新创建。基于模型重新创建输入序列的能力来评估模型的性能。

一旦模型达到重建序列所需的性能水平,就可以删除模型的解码器部分,只剩下编码器模型。然后可以使用该模型将输入序列编码为固定长度的向量。

然后,所得的向量可以用于各种应用程序中,不仅可以作为序列的压缩表示形式,还可以输入到另一个监督学习模型中。

LSTM自动编码器的早期应用

LSTM自动编码器的早期应用之一是在2015年发表的论文

//arxiv.org/abs/1502.04681arxiv.org

在本文中,Nitish Srivastava等人。将LSTM自动编码器描述为Encoder-Decoder LSTM的扩展或应用。

模型的输入是向量序列(图像补丁或特征)。编码器LSTM按此顺序读取。读取最后一个输入后,解码器LSTM接管并输出目标序列的预测。

他们使用带有视频输入数据的模型来重构视频帧序列以及预测视频帧,这两者都被描述为无监督学习任务。作者不仅仅是直接使用模型,还探索了一些有趣的体系结构选择,这些信息可能有助于为模型的未来应用提供信息。他们设计模型的方式是以相反的顺序重新创建视频帧的目标序列,声称这使模型解决的优化问题更易于处理。

目标序列与输入序列相同,但顺序相反。反转目标序列可以使优化更加容易,因为模型可以通过查看低范围相关性来实现。

他们还探索了两种方法来训练解码器模型,特别是在由解码器生成的先前输出中调节的版本,以及另一种没有任何这种调节的方法。

码器可以有两种-有条件的或无条件的。条件解码器接收最后生成的输出帧作为输入[…]。无条件的解码器不会接收该输入。

还探索了一种更为复杂的自动编码器模型,其中一个解码器使用了两种解码器模型:一种用于预测序列中的下一帧,一种用于重建序列中的帧,称为复合模型。

…可以将输入重构和预测未来结合起来以创建一个复合[…]。在这里,要求编码器LSTM提出一种状态,从该状态我们可以预测接下来的几帧并重构输入。

发现在没有解码器条件的情况下的复合模型在他们的实验中表现最佳。

下面就是使用demo代码来看看怎么设计一个lstm自编码器

from numpy import array
from keras.models import Sequential
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import RepeatVector
from keras.layers import TimeDistributed
from keras.utils import plot_model
# define input sequence
sequence = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
# reshape input into [samples, timesteps, features]
n_in = len(sequence)
sequence = sequence.reshape((1, n_in, 1))
# define model
model = Sequential()
model.add(LSTM(100, activation='relu', input_shape=(n_in,1)))
model.add(RepeatVector(n_in))
model.add(LSTM(100, activation='relu', return_sequences=True))
model.add(TimeDistributed(Dense(1)))
model.compile(optimizer='adam', loss='mse')
# fit model
model.fit(sequence, sequence, epochs=300, verbose=0)
plot_model(model, show_shapes=True, to_file='reconstruct_lstm_autoencoder.png')
# demonstrate recreation
yhat = model.predict(sequence, verbose=0)
print(yhat[0,:,0])

可以看到,这里的设计基本是使用的是simple seq2seq的实现方式,只不过标签换成了输入自己

这个思路挺简单的,另外一个思路比较有意思,复合LSTM自编码器


# lstm autoencoder reconstruct and predict sequence
from numpy import array
from keras.models import Model
from keras.layers import Input
from keras.layers import LSTM
from keras.layers import Dense
from keras.layers import RepeatVector
from keras.layers import TimeDistributed
from keras.utils import plot_model
# define input sequence
seq_in = array([0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9])
# reshape input into [samples, timesteps, features]
n_in = len(seq_in)
seq_in = seq_in.reshape((1, n_in, 1))
# prepare output sequence
seq_out = seq_in[:, 1:, :]
n_out = n_in - 1
# define encoder
visible = Input(shape=(n_in,1))
encoder = LSTM(100, activation='relu')(visible)
# define reconstruct decoder
decoder1 = RepeatVector(n_in)(encoder)
decoder1 = LSTM(100, activation='relu', return_sequences=True)(decoder1)
decoder1 = TimeDistributed(Dense(1))(decoder1)
# define predict decoder
decoder2 = RepeatVector(n_out)(encoder)
decoder2 = LSTM(100, activation='relu', return_sequences=True)(decoder2)
decoder2 = TimeDistributed(Dense(1))(decoder2)
# tie it together
model = Model(inputs=visible, outputs=[decoder1, decoder2])
model.compile(optimizer='adam', loss='mse')
plot_model(model, show_shapes=True, to_file='composite_lstm_autoencoder.png')
# fit model
model.fit(seq_in, [seq_in,seq_out], epochs=300, verbose=0)
# demonstrate prediction
yhat = model.predict(seq_in, verbose=0)
print(yhat)

这里创建了一个多输出的神经网络,完成了一个多输出回归的任务,然后使用decoder1来重构,decoder2来预测,据说能够提高精度。。我是没试过,不过基于lstm的自编码器的概念倒是比较有意思,将时序数据进行了真正的无监督的embedding。

//www.kaggle.com/dimitreoliveira/time-series-forecasting-with-lstm-autoencoderswww.kaggle.com

另外贴一个kaggle比赛的实现,这里对比了常规的lstm和lstm的自编码器。休息休息。。。累死了妈的