时间序列上的 LSTM 自动编码器
LSTM Autoencoder on timeseries
我目前正在尝试实现一个 LSTM 自动编码器,以便将交易时间序列(Berka 数据集)压缩为更小的编码向量。
我正在处理的数据看起来像 this
(这是一个账户在整个时间内的累计余额)。
我决定使用 Keras,并尝试按照 this 教程创建一个简单的自动编码器。该模型不起作用。
我的代码是这样的:
import keras
from keras import Input, Model
from keras.layers import Lambda, LSTM, RepeatVector
from matplotlib import pyplot as plt
from scipy import io
from sklearn.preprocessing import MinMaxScaler
import numpy as np
class ResultPlotter(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
plt.subplots(2, 2, figsize=(10, 3))
indexes = np.random.randint(datapoints, size=4)
for i in range(4):
plt.subplot(2, 2, i+1)
plt.plot(sparse_balances[indexes[i]])
result = sequence_autoencoder.predict(sparse_balances[0:1])
plt.plot(result.T)
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
return
result_plotter = ResultPlotter()
sparse_balances = io.mmread("my_path_to_sparse_balances.mtx")
sparse_balances = sparse_balances.todense()
scaler = MinMaxScaler(feature_range=(0, 1))
sparse_balances = scaler.fit_transform(sparse_balances)
N = sparse_balances.shape[0]
D = sparse_balances.shape[1]
batch_num = 32
timesteps = 500
latent_dim = 32
datapoints = N
model_inputs = Input(shape=(timesteps,))
inputs = Lambda(lambda x: keras.backend.expand_dims(x, -1))(model_inputs)
encoded = LSTM(latent_dim)(inputs)
decoded = RepeatVector(timesteps)(encoded)
decoded = LSTM(1, return_sequences=True)(decoded)
decoded = Lambda(lambda x: keras.backend.squeeze(x, -1))(decoded)
sequence_autoencoder = Model(model_inputs, decoded)
encoder = Model(model_inputs, encoded)
earlyStopping = keras.callbacks.EarlyStopping(monitor='loss', patience=5, verbose=0, mode='auto')
sequence_autoencoder.compile(loss='mean_squared_error', optimizer='adam')
sequence_autoencoder.fit(sparse_balances[:datapoints], sparse_balances[:datapoints],
batch_size=batch_num, epochs=100,
callbacks=[earlyStopping, result_plotter])
我不会添加用于生成 sparse_balanced.mtx 的代码,以保持一切清晰,请随时索取它,我会 post 它。
问题是自动编码器似乎卡在了预测 single line,而不是 returning 紧跟输入趋势的输出上,但经过广泛的研究我仍然有找到解决办法。
我做了一些实验,使用密集层作为模型的潜在输出部分,它能够 return much better results.
那么问题是:考虑到通过使用 LSTM->Dense 或 Dense->Dense 自动编码器我能够获得不错的结果,并且使用 Dense->LSTM 和 LSTM->LSTM 的结果相同糟糕的预测,问题出在我的模型、概念还是其他地方?
非常感谢每条评论,谢谢。
问题是我的数据集太小众了,无法轻易地被 LSTM 自动编码。我目前正在写关于交易生成的硕士论文,我详细分析了这个问题。如果您没有特别使用这个数据集,我建议尝试使用一些与时间相关的合成数据,例如正弦波、锯齿波等,因为模型应该能够在这些数据上正常工作。如果它仍然不起作用,则可能是您的代码中存在一些错误。
我目前正在尝试实现一个 LSTM 自动编码器,以便将交易时间序列(Berka 数据集)压缩为更小的编码向量。 我正在处理的数据看起来像 this (这是一个账户在整个时间内的累计余额)。
我决定使用 Keras,并尝试按照 this 教程创建一个简单的自动编码器。该模型不起作用。
我的代码是这样的:
import keras
from keras import Input, Model
from keras.layers import Lambda, LSTM, RepeatVector
from matplotlib import pyplot as plt
from scipy import io
from sklearn.preprocessing import MinMaxScaler
import numpy as np
class ResultPlotter(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
plt.subplots(2, 2, figsize=(10, 3))
indexes = np.random.randint(datapoints, size=4)
for i in range(4):
plt.subplot(2, 2, i+1)
plt.plot(sparse_balances[indexes[i]])
result = sequence_autoencoder.predict(sparse_balances[0:1])
plt.plot(result.T)
plt.xticks([])
plt.yticks([])
plt.tight_layout()
plt.show()
return
result_plotter = ResultPlotter()
sparse_balances = io.mmread("my_path_to_sparse_balances.mtx")
sparse_balances = sparse_balances.todense()
scaler = MinMaxScaler(feature_range=(0, 1))
sparse_balances = scaler.fit_transform(sparse_balances)
N = sparse_balances.shape[0]
D = sparse_balances.shape[1]
batch_num = 32
timesteps = 500
latent_dim = 32
datapoints = N
model_inputs = Input(shape=(timesteps,))
inputs = Lambda(lambda x: keras.backend.expand_dims(x, -1))(model_inputs)
encoded = LSTM(latent_dim)(inputs)
decoded = RepeatVector(timesteps)(encoded)
decoded = LSTM(1, return_sequences=True)(decoded)
decoded = Lambda(lambda x: keras.backend.squeeze(x, -1))(decoded)
sequence_autoencoder = Model(model_inputs, decoded)
encoder = Model(model_inputs, encoded)
earlyStopping = keras.callbacks.EarlyStopping(monitor='loss', patience=5, verbose=0, mode='auto')
sequence_autoencoder.compile(loss='mean_squared_error', optimizer='adam')
sequence_autoencoder.fit(sparse_balances[:datapoints], sparse_balances[:datapoints],
batch_size=batch_num, epochs=100,
callbacks=[earlyStopping, result_plotter])
我不会添加用于生成 sparse_balanced.mtx 的代码,以保持一切清晰,请随时索取它,我会 post 它。
问题是自动编码器似乎卡在了预测 single line,而不是 returning 紧跟输入趋势的输出上,但经过广泛的研究我仍然有找到解决办法。 我做了一些实验,使用密集层作为模型的潜在输出部分,它能够 return much better results.
那么问题是:考虑到通过使用 LSTM->Dense 或 Dense->Dense 自动编码器我能够获得不错的结果,并且使用 Dense->LSTM 和 LSTM->LSTM 的结果相同糟糕的预测,问题出在我的模型、概念还是其他地方?
非常感谢每条评论,谢谢。
问题是我的数据集太小众了,无法轻易地被 LSTM 自动编码。我目前正在写关于交易生成的硕士论文,我详细分析了这个问题。如果您没有特别使用这个数据集,我建议尝试使用一些与时间相关的合成数据,例如正弦波、锯齿波等,因为模型应该能够在这些数据上正常工作。如果它仍然不起作用,则可能是您的代码中存在一些错误。