LSTM Autoencoder на таймсериях

В настоящее время я пытаюсь реализовать автокодер 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 приводит к тем же плохим прогнозам, проблема в моей модели, в концепции или где-то еще?

Мы очень ценим каждый комментарий, спасибо.


person HitLuca    schedule 06.02.2018    source источник
comment
Эй, тебе удалось это решить? Я пытаюсь реализовать что-то подобное в TensorFlow и сталкиваюсь с более или менее той же проблемой.   -  person MrfksIV    schedule 03.07.2018
comment
@MrfksIV Да, проблема в том, что мой набор данных слишком нишевый, чтобы его можно было легко автоматически кодировать с помощью LSTM. Сейчас я пишу магистерскую диссертацию на тему генерации транзакций и подробно проанализировал эту проблему. Если вы, в частности, не работаете с этим набором данных, я предлагаю вам попробовать некоторые синтетические временные данные, такие как синусоидальные волны, пилообразные волны и т. Д., Поскольку модель должна правильно работать с этим. Если он по-прежнему не работает, возможно, в вашем коде есть ошибки. Сообщите мне, если это поможет!   -  person HitLuca    schedule 04.07.2018


Ответы (1)


Проблема заключалась в том, что мой набор данных слишком нишевый, чтобы его можно было легко автоматически кодировать с помощью LSTM. Сейчас я пишу магистерскую диссертацию на тему генерации транзакций и подробно проанализировал эту проблему. Если вы, в частности, не работаете с этим набором данных, я предлагаю попробовать с некоторыми синтетическими данными, связанными со временем, такими как синусоидальные волны, пилообразные волны и т. Д., Поскольку модель должна правильно работать с этим. Если он по-прежнему не работает, возможно, в вашем коде есть ошибки.

person HitLuca    schedule 12.09.2018