Я пытаюсь согласовать свое понимание LSTM и указал здесь в этом посте Кристофером Олахом, реализованным в Керасе. Я слежу за блогом, написанным Джейсоном Браунли для учебника Keras. То, что я в основном смущен о том,
- Преобразование ряда данных в
[samples, time steps, features]
и, - LSTM с состоянием
Давайте сосредоточимся на двух вышеупомянутых вопросах со ссылкой на код, вставленный ниже:
# reshape into X=t and Y=t+1
look_back = 3
trainX, trainY = create_dataset(train, look_back)
testX, testY = create_dataset(test, look_back)
# reshape input to be [samples, time steps, features]
trainX = numpy.reshape(trainX, (trainX.shape[0], look_back, 1))
testX = numpy.reshape(testX, (testX.shape[0], look_back, 1))
########################
# The IMPORTANT BIT
##########################
# create and fit the LSTM network
batch_size = 1
model = Sequential()
model.add(LSTM(4, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')
for i in range(100):
model.fit(trainX, trainY, nb_epoch=1, batch_size=batch_size, verbose=2, shuffle=False)
model.reset_states()
Примечание: create_dataset принимает последовательность длины N и возвращает N-look_back
массив, каждый элемент которого является look_back
последовательностью длины.
Что такое временные шаги и особенности?
Как можно видеть, TrainX является трехмерным массивом, где Time_steps и Feature являются последними двумя измерениями соответственно (3 и 1 в данном конкретном коде). Что касается изображения ниже, означает ли это, что мы рассматриваем many to one
случай, когда количество розовых коробок равно 3? Или это буквально означает, что длина цепи равна 3 (то есть только 3 зеленых поля).
Становится ли аргумент функций актуальным, когда мы рассматриваем многомерный ряд? например, моделирование двух финансовых акций одновременно?
Statest LSTM
Означают ли LSTM с состоянием, что мы сохраняем значения памяти ячейки между запусками пакетов? Если это так, то batch_size
это единица, и память перезагружается между тренировочными запусками, так какой смысл говорить, что это было с состоянием. Я предполагаю, что это связано с тем, что данные тренировок не перемешиваются, но я не уверен, как это сделать.
Есть предположения? Ссылка на изображение: http://karpathy.github.io/2015/05/21/rnn-effectiveness/
Изменить 1:
Немного смущен комментарием @ van о том, что красные и зеленые квадраты равны. Так что просто для подтверждения, соответствуют ли следующие вызовы API развернутым диаграммам? Особенно отмечая вторую диаграмму ( batch_size
была выбрана произвольно.):
Изменить 2:
Для людей, которые прошли курс углубленного изучения Udacity и все еще не понимают аргумент time_step, посмотрите следующее обсуждение: https://discussions.udacity.com/t/rnn-lstm-use-implementation/163169
Обновить:
Оказывается, model.add(TimeDistributed(Dense(vocab_len)))
это то, что я искал. Вот пример: https://github.com/sachinruk/ShakespeareBot
Update2:
Я кратко изложил большую часть моего понимания LSTM здесь: https://www.youtube.com/watch?v=ywinX5wgdEU
источник
Ответы:
Прежде всего, вы выбираете отличные уроки ( 1 , 2 ) для начала.
Что означает временной шаг :
Time-steps==3
в X.shape (описание формы данных) есть три розовых прямоугольника. Так как в Keras каждый шаг требует ввода, поэтому количество зеленых прямоугольников должно обычно равняться количеству красных прямоугольников. Если только вы не взломаете структуру.многие ко многим против многих к одному : в керасе есть
return_sequences
параметр при инициализацииLSTM
илиGRU
илиSimpleRNN
. Когдаreturn_sequences
естьFalse
(по умолчанию), то это много к одному, как показано на рисунке. Возвращаемая форма -(batch_size, hidden_unit_length)
это последнее состояние. Когдаreturn_sequences
естьTrue
, то это много ко многим . Его возвращаемая форма(batch_size, time_step, hidden_unit_length)
Соответствует ли аргумент feature: Аргумент Feature означает «насколько велик ваш красный прямоугольник» или каково входное измерение на каждом шаге Если вы хотите прогнозировать, скажем, 8 видов рыночной информации, то вы можете сгенерировать свои данные с помощью
feature==8
.С состоянием : вы можете посмотреть исходный код . При инициализации состояния, если
stateful==True
, то состояние из последней тренировки будет использоваться в качестве начального состояния, в противном случае оно будет генерировать новое состояние. Я еще неstateful
включился. Тем не менее, я не согласен с тем, чтоbatch_size
может быть только 1, когдаstateful==True
.В настоящее время вы генерируете свои данные из собранных данных. Представьте, что ваша фондовая информация поступает в виде потока, вместо того, чтобы ждать целый день, чтобы собрать все последовательные данные, вы хотели бы генерировать входные данные в режиме онлайн во время обучения / прогнозирования по сети. Если у вас есть 400 акций в одной сети, вы можете установить
batch_size==400
.источник
stateful: Boolean (default False). If True, the last state for each sample at index i in a batch will be used as initial state for the sample of index i in the following batch.
lookback = 1
?stateful=True
: Размер партии может быть любым, но вы должны придерживаться его. Если вы строите свою модель с партией размером 5, то всеfit()
,predict()
и связанная с ними метода потребует партии 5. Обратите внимание , однако , что это состояние не будет сохранено сmodel.save()
, что может показаться нежелательным. Однако вы можете вручную добавить состояние в файл hdf5, если вам это нужно. Но по сути это позволяет изменить размер партии, просто сохранив и перезагрузив модель.В качестве дополнения к принятому ответу, этот ответ показывает поведение keras и способы достижения каждой картины.
Поведение генерала Кераса
Стандартная внутренняя обработка keras всегда много-много, как показано на следующем рисунке (где я использовал
features=2
давление и температуру, просто в качестве примера):На этом изображении я увеличил количество шагов до 5, чтобы избежать путаницы с другими измерениями.
Для этого примера:
Наш входной массив должен быть в форме
(N,5,2)
:Входы для раздвижных окон
Часто слои LSTM должны обрабатывать целые последовательности. Разделительные окна могут быть не лучшей идеей. Слой имеет внутренние состояния о том, как последовательность развивается по мере продвижения вперед. Windows исключает возможность изучения длинных последовательностей, ограничивая все последовательности размером окна.
В окнах каждое окно является частью длинной оригинальной последовательности, но для Keras они будут рассматриваться как независимая последовательность:
Обратите внимание, что в этом случае у вас изначально есть только одна последовательность, но вы делите ее на несколько последовательностей для создания окон.
Понятие «что такое последовательность» абстрактно. Важными частями являются:
Достижение каждого случая с «отдельными слоями»
Достижение стандарта много ко многим:
Вы можете достичь многого с помощью простого слоя LSTM, используя
return_sequences=True
:Достижение многих к одному:
Используя точно такой же слой, keras будет выполнять ту же самую внутреннюю предварительную обработку, но когда вы используете
return_sequences=False
(или просто игнорируете этот аргумент), keras автоматически отбрасывает шаги, предшествующие последнему:Достижение один ко многим
Теперь это поддерживается не только слоями keras LSTM. Вам нужно будет создать свою собственную стратегию, чтобы умножить шаги. Есть два хороших подхода:
stateful=True
чтобы периодически получать выходные данные одного шага и использовать их как входные данные следующего шага (необходимоoutput_features == input_features
)Один ко многим с повторным вектором
Чтобы соответствовать стандартному поведению keras, нам нужны входные данные поэтапно, поэтому мы просто повторяем входные данные для нужной длины:
Понимание состояния = True
Теперь прибывает одно из возможных применений
stateful=True
(кроме того, чтобы избежать загрузки данных, которые не могут поместиться сразу в память вашего компьютера)Stateful позволяет вводить «части» последовательностей поэтапно. Разница в том, что:
stateful=False
втором пакете содержатся совершенно новые последовательности, независимые от первого пакета.stateful=True
, вторая партия продолжает первую партию, расширяя те же последовательности.Это похоже на разделение последовательностей в окнах с этими двумя основными отличиями:
stateful=True
увидит эти окна соединенными в одну длинную последовательностьВ
stateful=True
, каждая новая партия будет интерпретироваться как продолжение предыдущей партии (пока вы не позвонитеmodel.reset_states()
).Пример входных данных, партия 1 содержит шаги 1 и 2, партия 2 содержит шаги с 3 по 5:
Обратите внимание на выравнивание резервуаров в партии 1 и партии 2! Вот почему нам нужно
shuffle=False
(если, конечно, мы не используем только одну последовательность).Вы можете иметь любое количество партий, на неопределенный срок. (Для переменной длины в каждом пакете используйте
input_shape=(None,features)
.Один ко многим с сохранением состояния = True
В нашем случае мы будем использовать только 1 шаг на пакет, потому что мы хотим получить один выходной шаг и сделать его входным.
Обратите внимание, что поведение на картинке не "вызвано"
stateful=True
. Мы приведем это в порядок ниже. В этом примере то,stateful=True
что «позволяет» нам остановить последовательность, манипулировать тем, что мы хотим, и продолжить с того места, где мы остановились.Честно говоря, повторный подход, вероятно, является лучшим выбором для этого случая. Но так как мы смотрим
stateful=True
, это хороший пример. Лучший способ использовать это - следующий случай «многие ко многим».Слой:
Теперь нам понадобится ручной цикл для прогнозов:
Многие ко многим с Stateful = True
Теперь, здесь, мы получаем очень хорошее приложение: учитывая входную последовательность, попытайтесь предсказать ее будущие неизвестные шаги.
Мы используем тот же метод, что и в примере «один ко многим», с той разницей, что:
Слой (такой же, как выше):
Повышение квалификации:
Мы собираемся обучить нашу модель прогнозированию следующего шага последовательностей:
Предсказание:
Первый этап нашего прогнозирования включает в себя «настройку состояний». Вот почему мы собираемся снова предсказать всю последовательность, даже если мы уже знаем эту часть:
Теперь перейдем к циклу, как в случае один ко многим. Но не сбрасывайте состояния здесь! , Мы хотим, чтобы модель знала, в каком шаге последовательности она находится (и она знает, что это на первом новом шаге из-за прогноза, который мы только что сделали)
Этот подход был использован в этих ответах и файле:
Достижение сложных конфигураций
Во всех приведенных выше примерах я показал поведение «одного слоя».
Конечно, вы можете размещать много слоев друг над другом, не обязательно все по одной схеме, и создавать свои собственные модели.
Один интересный пример, который появился, - это «автоматический кодер», который имеет кодер «многие к одному», за которым следует декодер «один ко многим»:
Кодер:
декодер:
Использование метода «повторить»;
автоассоциатор:
Поезд с
fit(X,X)
Дополнительные объяснения
Если вам нужны подробности о том, как рассчитываются шаги в LSTM, или подробности о
stateful=True
вышеупомянутых случаях, вы можете прочитать больше в этом ответе: Сомнения относительно `Понимания LSTM Keras`источник
my_cell = LSTM(num_output_features_per_timestep, return_state=True)
за этим следует циклa, _, c = my_cell(output_of_previous_time_step, initial_states=[a, c])
Если у вас есть return_sequence в вашем последнем слое RNN, вы не можете использовать простой плотный слой, вместо этого используйте TimeDistributed.
Вот пример кода, который может помочь другим.
words = keras.layers.Input (batch_shape = (None, self.maxSequenceLength), name = "input")
источник