Усреднение по измерению партии в Керасе - PullRequest
0 голосов
/ 19 марта 2019

У меня есть проблема, когда я хочу предсказать один временной ряд со многими временными рядами. Мой ввод (batch_size, time_steps, features), а вывод (1, time_steps, features)

Я не могу понять, как усреднить по N.

Вот глупый пример. Во-первых, фиктивные данные, где выходные данные представляют собой линейную функцию 200 временных рядов:

import numpy as np
time = 100
N = 2000

dat = np.zeros((N, time))
for i in range(time):
    dat[i,:] = np.sin(list(range(time)))*np.random.normal(size =1) + np.random.normal(size = 1)

y = dat.T @ np.random.normal(size = N)

Теперь я определю модель временного ряда (с использованием одномерных сетей):

from keras.models import Model
from keras.layers import Input, Conv1D, Dense, Lambda
from keras.optimizers import Adam
from keras import backend as K

n_filters = 2
filter_width = 3
dilation_rates = [2**i for i in range(5)] 
inp = Input(shape=(None, 1))
x = inp
for dilation_rate in dilation_rates:
    x = Conv1D(filters=n_filters,
               kernel_size=filter_width, 
               padding='causal',
               activation = "relu",
               dilation_rate=dilation_rate)(x)
x = Dense(1)(x)

model = Model(inputs = inp, outputs = x)
model.compile(optimizer = Adam(), loss='mean_squared_error')
model.predict(dat.reshape(N, time, 1)).shape

Out[43]: (2000, 100, 1)

Вывод неправильной формы! Затем я попытался использовать усредняющий слой, но получаю странную ошибку:

def av_over_batches(x):
    x = K.mean(x, axis = 0)
    return(x)

x = Lambda(av_over_batches)(x)

model = Model(inputs = inp, outputs = x)
model.compile(optimizer = Adam(), loss='mean_squared_error')
model.predict(dat.reshape(N, time, 1)).shape

Traceback (most recent call last):

  File "<ipython-input-3-d43ccd8afa69>", line 4, in <module>
    model.predict(dat.reshape(N, time, 1)).shape

  File "/home/me/.local/lib/python3.6/site-packages/keras/engine/training.py", line 1169, in predict
    steps=steps)

  File "/home/me/.local/lib/python3.6/site-packages/keras/engine/training_arrays.py", line 302, in predict_loop
    outs[i][batch_start:batch_end] = batch_out

ValueError: could not broadcast input array from shape (100,1) into shape (32,1)

Откуда 32 откуда? (Кстати, я получил тот же номер в моих реальных данных, а не только в MWE).

Но главный вопрос: как я могу построить сеть, которая усредняется по измерению входного пакета?

1 Ответ

0 голосов
/ 19 марта 2019

Я бы подошел к проблеме по-другому

Проблема: Вы хотите предсказать временной ряд из набора временных рядов.Допустим, у вас есть 3 значения временного ряда TS1, TS2, TS3 каждый из 100 временных шагов, которые вы хотите предсказать, временной ряд y1, y2, y3.

Мой подход к этой проблеме будет таким, как показано ниже

enter image description here

т. Е. Сгруппируйте временные ряды для каждого временного шага вместе и передайте их в LSTM.Если некоторые временные шаги короче, чем другие, вы можете дополнить их.Точно так же, если у некоторых наборов есть меньше временных рядов, тогда снова добавьте их.

Пример:

import numpy as np
np.random.seed(33)

time = 100
N = 5000
k = 5

magic = np.random.normal(size = k)

x = list()
y = list()
for i in range(N):
    dat = np.zeros((k, time))
    for i in range(k):
        dat[i,:] = np.sin(list(range(time)))*np.random.normal(size =1) + np.random.normal(size = 1)
    x.append(dat)
    y.append(dat.T @ magic)

Итак, я хочу предсказать временную серию из 100 шагов из набора из 3 шагов.Мы хотим, чтобы модель выучила magic.

from keras.models import Model
from keras.layers import Input, Conv1D, Dense, Lambda, LSTM
from keras.optimizers import Adam
from keras import backend as K
import matplotlib.pyplot as plt

input = Input(shape=(time, k))
lstm = LSTM(32, return_sequences=True)(input)
output = Dense(1,activation='sigmoid')(lstm)

model = Model(inputs = input, outputs = output)
model.compile(optimizer = Adam(), loss='mean_squared_error')

data_x = np.zeros((N,100,5))
data_y = np.zeros((N,100,1))

for i in range(N):
    data_x[i] = x[i].T.reshape(100,5)
    data_y[i] = y[i].reshape(100,1)

from sklearn.preprocessing import StandardScaler

ss_x = StandardScaler()
ss_y = StandardScaler()

data_x = ss_x.fit_transform(data_x.reshape(N,-1)).reshape(N,100,5)
data_y = ss_y.fit_transform(data_y.reshape(N,-1)).reshape(N,100,1)

# Lets leave the last one sample for testing rest split into train and validation
model.fit(data_x[:-1],data_y[:-1], batch_size=64, nb_epoch=100, validation_split=.25)

Потери в валу продолжали падать, но я остановил их.Давайте посмотрим, насколько хорош наш прогноз

y_hat = model.predict(data_x[-1].reshape(-1,100,5))
plt.plot(data_y[-1], label='y')
plt.plot(y_hat.reshape(100), label='y_hat')
plt.legend(loc='upper left')

enter image description here

Результаты многообещающие.Запуск его для большего количества эпох, а также настройка гиперпараметров должны еще больше приблизить нас к magic.Можно также попробовать сложенный LSTM и двунаправленный LSTM.

Мне кажется, что RNN лучше подходят для данных временного ряда, чем CNN

Формат данных: допустим, временные шаги = 3 Временной ряд 1 =[1,2,3]

Временной ряд 2 = [4,5,6]

Временной ряд 3 = [7,8,9]

Временной ряд 3 = [10,11,12]

Y =[100,200,300]

Для партии размером 1

[[1,4,7,10],[2,5,8,11],[3,6,9,12]] -> LSTM -> [100,200,300]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...