Реконструкция временных рядов автокраски Keras LSTM - программирование
Подтвердить что ты не робот

Реконструкция временных рядов автокраски Keras LSTM

Я пытаюсь восстановить данные временных рядов с помощью LSTM Autoencoder (Keras). Теперь я хочу обучить автоэнкодеру на небольшом количестве образцов (5 образцов, каждый образец имеет 500 шагов по времени и имеет 1 измерение). Я хочу убедиться, что модель может восстановить эти 5 образцов, и после этого я буду использовать все данные (6000 образцов).

window_size = 500
features = 1
data = data.reshape(5, window_size, features)

model = Sequential()

model.add(LSTM(256, input_shape=(window_size, features), 
return_sequences=True))
model.add(LSTM(128, input_shape=(window_size, features), 
return_sequences=False))
model.add(RepeatVector(window_size))

model.add(LSTM(128, input_shape=(window_size, features), 
return_sequences=True))
model.add(LSTM(256, input_shape=(window_size, features), 
return_sequences=True))
model.add(TimeDistributed(Dense(1)))

model.compile(optimizer='adam', loss='mse')
model.fit(data, data, epochs=100, verbose=1)

Модель

Обучение:

Epoch 1/100
5/5 [==============================] - 2s 384ms/step - loss: 0.1603
...
Epoch 100/100
5/5 [==============================] - 2s 388ms/step - loss: 0.0018

После тренировки я попытался восстановить один из 5 образцов:

yhat = model.predict(np.expand_dims(data[1,:,:], axis=0), verbose=0)

Восстановление: синий
Вход: оранжевый

Reconstion (blue) vs Input (orange)

Почему реконструкция так плоха, когда потери невелики? Как я могу сделать модель лучше? Благодарю.

4b9b3361

Ответ 1

Мне кажется, временные ряды должны быть предоставлены LSTM в следующем формате:

 (samples, features , window_size)

Итак, если вы измените формат, например, я обменялся переменными и посмотрел на результаты:

enter image description here

Код для воспроизведения результата (я не менял название переменных, поэтому не путайтесь :)):

import numpy as np
import keras
from keras import Sequential
from keras.layers import Dense, RepeatVector,        TimeDistributed
from keras.layers import LSTM

N = 10000
data = np.random.uniform(-0.1, 0.1, size=(N, 500))
data = data.cumsum(axis=1)
print(data.shape)
window_size = 1
features = 500
data = data.reshape(N, window_size, features)

model = Sequential()

model.add(LSTM(32, input_shape=
(window_size,features), 
return_sequences=True))
model.add(LSTM(16, input_shape=(window_size,   
features), 
return_sequences=False))
model.add(RepeatVector(window_size))

model.add(LSTM(16, input_shape=(window_size, 
features), 
return_sequences=True))
model.add(LSTM(32, input_shape=(window_size,   
features), 
return_sequences=True))
model.add(TimeDistributed(Dense(500)))

model.compile(optimizer='adam', loss='mse')
model.fit(data, data, epochs=100, verbose=1)


yhat = model.predict(np.expand_dims(data[1,:,:],   axis=0), verbose=0)
plot(np.arange(500), yhat[0,0,:])
plot(np.arange(500), data[1,0,:])

Благодарность sobe86: я использовал предложенные им данные.

Ответ 2

Я попытался запустить ваш код на следующих данных

data = np.random.uniform(-0.1, 0.1, size=(5, 500))
data = data.cumsum(axis=1)

таким образом, данные - это просто кумулятивная сумма некоторого случайного однородного шума. Я бежал за 1000 эпох, и мои результаты не так плохи, как у вас, LSTM, кажется, прилагает некоторые усилия, чтобы следовать линии, хотя, кажется, просто колеблется вокруг скользящего среднего (как можно было ожидать).

blah

Обратите внимание, что эта модель работает с данными ОБУЧЕНИЯ (что, по-видимому, подразумевает, что вы делали это в своем вопросе) - если мы попытаемся оценить производительность данных, на которых модель не была обучена, мы можем получить плохие результаты.

blah

Это неудивительно, так как при таком небольшом обучающем наборе следует полностью ожидать, что модель будет соответствовать, а не обобщаться на новые данные.

Ответ 3

Вы исправили эту проблему? У меня та же проблема, и я не знаю, как это сделать.

Ответ 4

Может быть проблема с масштабом, попробуйте восстановить: data_scaled = minmax_scale (data, feature_range = (-1, 1))