В настоящее время я пытаюсь реализовать автокодер 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, чтобы все было понятно, не стесняйтесь спрашивать об этом, и я опубликую его.
Проблема в том, что автоэнкодер, кажется, застревает на предсказании одной строки вместо того, чтобы возвращать выходы, которые точно следуют тенденции входных данных, но после обширного исследования мне все еще нужно найти решение. Я провел несколько экспериментов, используя плотный слой в качестве скрытой части модели для вывода, и он может возвращать гораздо лучшие результаты.
Тогда возникает вопрос: учитывая тот факт, что с помощью автокодировщиков LSTM-> Dense или Dense-> Dense я могу получить достойные результаты, а использование Dense-> LSTM и LSTM-> LSTM приводит к тем же плохим прогнозам, проблема в моей модели, в концепции или где-то еще?
Мы очень ценим каждый комментарий, спасибо.