Модель и формы
Поскольку это последовательности в последовательностях, вам необходимо использовать ваши данные в другом формате.
Хотя вы можете просто go например (machines, days, 360)
и просто рассматривать 360 как функции (которые могут работать до некоторой точки), для надежной модели (тогда, возможно, есть проблема со скоростью), вы бы нужно рассматривать обе вещи как последовательности.
Тогда я бы go с данными типа (machines, days, 360, 1)
и двумя уровнями рекуррентности.
Тогда наши модели input_shape
будут (None, 360, 1)
Случай модели 1 - Только дневная рекуррентность
Форма данных: (machines, days, 360)
Применить некоторую нормализацию к данные.
Здесь приведен пример, но модели могут быть гибкими, поскольку вы можете добавить больше слоев, попробовать свертки и т. Д. c:
inputs = Input((None, 360)) #(m, d, 360)
outs = LSTM(some_units, return_sequences=False,
stateful=depends_on_training_approach)(inputs) #(m, some_units)
outs = Dense(360, activation=depends_on_your_normalization)(outs) #(m, 360)
outs = Reshape((1,360)) #(m, 1, 360)
#this reshape is not necessary if using the "shifted" approach - see time windows below
#it would then be (m, d, 360)
model = Model(inputs, outs)
В зависимости от сложности внутридневных последовательностей , они могли бы получить хорошие прогнозы с этим, но если они развиваются сложным образом, то следующая модель будет немного лучше.
Всегда помните, что вы можете создавать больше слоев и исследовать вещи, чтобы увеличить возможности эта модель, это только небольшой пример
Пример модели 2 - Двухуровневая рекуррентность
Форма данных: (machines, days, 360, 1)
Применить некоторую нормализацию к данным.
Существует много способов экспериментировать, как это сделать, но вот простой.
inputs = Input((None, 360, 1)) #(m, d, 360, 1)
#branch 1
inner_average = TimeDistributed(
Bidirectional(
LSTM(units1, return_sequences=True, stateful=False),
merge_mode='ave'
)
)(inputs) #(m, d, 360, units1)
inner_average = Lambda(lambda x: K.mean(x, axis=1))(inner_average) #(m, 360, units1)
#branch 2
inner_seq = TimeDistributed(
LSTM(some_units, return_sequences=False, stateful=False)
)(inputs) #may be Bidirectional too
#shape (m, d, some_units)
outer_seq = LSTM(other_units, return_sequences = False,
stateful=depends_on_training_approach)(inner_seq) #(m, other_units)
outer_seq = Dense(few_units * 360, activation = 'tanh')(outer_seq) #(m, few_units * 360)
#activation = same as inner_average
outer_seq = Reshape((360,few_units))(outer_seq) #(m, 360, few_units)
#join branches
outputs = Concatenate()([inner_average, outer_seq]) #(m, 360, units1+few_units)
outputs = LSTM(units, return_sequences=True, stateful= False)(outputs) #(m, 360,units)
outputs = Dense(1, activation=depends_on_your_normalization)(outputs) #(m, 360, 1)
outputs = Reshape((1,360))(outputs) #(m, 1, 360) for training purposes
model = Model(inputs, outputs)
Это одна попытка, я сделал среднее число дней, но я мог бы вместо inner_average
сделать что-то вроде:
#branch 1
daily_minutes = Permute((2,1,3))(inputs) #(m, 360, d, 1)
daily_minutes = TimeDistributed(
LSTM(units1, return_sequences=False,
stateful=depends_on_training_approach)
)(daily_minutes) #(m, 360, units1)
Многие другие способы изучение данных возможно, это очень креативное поле. Например, вы могли бы использовать подход daily_minutes
сразу после inner_average
, исключая K.mean
лямбда-слой .... у вас есть идея.
Время windows подход
Ваш подход звучит хорошо. Дайте один шаг, чтобы предсказать следующий, дайте два шага, чтобы предсказать 1151 * третий, дайте три шага, чтобы предсказать четвертый.
Приведенные выше модели подходят для этого подхода.
Имейте в виду, что очень короткие входы могут быть бесполезны и могут ухудшить вашу модель. (Постарайтесь представить, сколько шагов будет достаточно для того, чтобы начать прогнозирование следующих шагов)
Предварительно обработайте данные и разделите их на группы:
- группа с длиной = 4 ( например)
- группа с длиной = 5
- ...
- группа с длиной = 28
Вам потребуется ручное обучение l oop где в каждой эпохе вы кормите каждую из этих групп (вы не можете кормить разные длины все вместе).
Другой подход заключается в том, чтобы все этапы заставляли модель предсказывать смещенную последовательность, например:
inputs = original_inputs[:, :-1]
# исключая последний тренировочный день outputs = original_inputs[:, 1:]
# исключить первый тренировочный день
Для того, чтобы сделать приведенные выше модели подходящими для этого подхода, вам нужно return_sequences=True
в каждом LSTM, который использует измерение дня в качестве шагов (не inner_seq
). (Метод inner_average
потерпит неудачу, и вам придется прибегнуть к подходу daily_minutes
с return_sequences=True
и другим Permute((2,1,3))
сразу после.
Shapes будет:
- branch1:
(m, d, 360, units1)
- branch2:
(m, d, 360, few_units)
- для этого нужно отрегулировать Reshape
- Изменение формы с использованием 1 временного шага будет ненужным, измерение
days
заменит 1. - Вам может понадобиться использовать
Lambda
слои для изменения формы с учетом размера партии и переменного количества дней (если нужны подробности, пожалуйста, сообщите мне)
Обучение и прогнозирование
(Извините, что сейчас нет времени на детализацию)
Затем вы можете следовать упомянутым подходам здесь и здесь также более полный с несколькими ссылками . (Будьте внимательны с выходными формами, хотя, по вашему вопросу, мы всегда сохраняем размер шага по времени, даже если он может быть 1)
Важное Очки:
- Если вы выберете
stateful=False
: - это означает легкую тренировку с
fit
(если вы не использовали подход «разной длины»); - это также означает, что вам нужно будет построить новую модель с
stateful=True
, скопировать веса обученной модели; - затем вы делаете пошаговое ручное прогнозирование
- Если вы выбираете
stateful=True
с самого начала: - , это обязательно означает ручное обучение l oop (например,
train_on_batch
); - это обязательно означает, что вам понадобится
model.reset_states()
всякий раз, когда вы собираетесь представить пакет, последовательности которого не являются продолжениями последнего пакета (каждый пакет, если ваши серии содержат целые последовательности). - не нужно создавать новую модель для ручного прогнозирования, но ручной прогноз остается прежним