Размеры, не совпадающие в модели keras LSTM

#python-3.x #theano #keras #keras-layer

#python-3.x #theano #keras #keras-слой

Вопрос:

Я хочу использовать нейронную сеть LSTM с keras для прогнозирования групп временных рядов, и у меня возникают проблемы с тем, чтобы модель соответствовала тому, что я хочу. Размеры моих данных:

входной тензор: (data length, number of series to train, time steps to look back)

тензор вывода: (data length, number of series to forecast, time steps to look ahead)

Примечание: я хочу сохранить размеры точно такими, без транспозиции.

Фиктивный код данных, который воспроизводит проблему, является:

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

epoch_number = 100
batch_size = 20
input_dim = 4
output_dim = 3
look_back = 24
look_ahead = 24
n = 100

trainX = np.random.rand(n, input_dim, look_back)
trainY = np.random.rand(n, output_dim, look_ahead)
print('test X:', trainX.shape)
print('test Y:', trainY.shape)

model = Sequential()

# Add the first LSTM layer (The intermediate layers need to pass the sequences to the next layer)
model.add(LSTM(10, batch_input_shape=(None, input_dim, look_back), return_sequences=True))

# add the first LSTM layer (the dimensions are only needed in the first layer)
model.add(LSTM(10, return_sequences=True))

# the TimeDistributed object allows a 3D output
model.add(TimeDistributed(Dense(look_ahead)))

model.compile(loss='mean_squared_error', optimizer='adam', metrics=['accuracy'])
model.fit(trainX, trainY, nb_epoch=epoch_number, batch_size=batch_size, verbose=1)
  

Это приводит к:

Исключение: ошибка при проверке цели модели: ожидаемый timedistributed_1 должен иметь форму (None, 4, 24), но получен массив с формой (100, 3, 24)

Проблема, похоже, заключается в определении TimeDistributed слоя.

Как мне определить TimeDistributed слой, чтобы он компилировался и обучался?

Ответ №1:

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

У вас trainY есть форма (n, output_dim, look_ahead) , поэтому (100, 3, 24) , но сеть выдает форму вывода (batch_size, input_dim, look_ahead) . Проблема в этом случае заключается в том, что output_dim != input_dim . Если ваше измерение времени изменяется, вам может понадобиться дополнение или сетевой узел, который удаляет указанный временной шаг.

Ответ №2:

Я думаю, проблема в том, что вы ожидаете output_dim (!= input_dim ) на выходе TimeDistributed , хотя это невозможно. Это измерение — это то, что он рассматривает как измерение времени: оно сохраняется.

Входные данные должны быть не менее 3D, а измерение индекса one будет считаться временным измерением.

Цель TimeDistributed состоит в том, чтобы применять один и тот же слой к каждому временному шагу. Вы можете получить только то же количество временных шагов, с которого начали.

Если вам действительно нужно уменьшить это измерение с 4 до 3, я думаю, вам нужно будет либо добавить еще один слой в конце, либо использовать что-то отличное от TimeDistributed .

PS: один из советов по поиску этой проблемы заключался в том, что output_dim он никогда не использовался при создании модели, он появляется только в данных проверки. Хотя это всего лишь запах кода (в этом наблюдении может быть что-то не так), это стоит проверить.

Комментарии:

1. Я выполняю транспонирование, потому что для одного временного ряда это транспонирование делает прогноз намного более точным. После этого урока у меня появилась идея: machinelearningmastery.com/… Но я думаю, что есть еще кое-что, что нужно сделать для отношений «многие ко многим»