Состояния в LSTM
LSTM состоит из вентилей, которые вычисляют cell state
и hidden state
.
На рисунке верхняя стрелка, выходящая справа от LSTM, является состоянием ячейки (c_t
), а нижняя стрелка - скрытым состоянием (h_t
),Состояния ячеек являются результатом стробированных манипуляций, а размер состояния такой же, как у hidden_size
LSTM.Каждое развертывание (с соответствующим входом X) приводит к собственному состоянию ячейки.В случае LSTM состояние ячейки состоит из двух значений hidden_state (h_t
) из (batch_size x hidden_size) и cell_state (c_t
) из (batch_size x hidden_size).
batch_size = 2
num_steps = 5
num_input = num_output = 1
hidden_size = 8
inputs = Input(batch_shape=(batch_size,num_steps, num_input))
lstm, state_h, state_c = LSTM(hidden_size, return_state=True, return_sequences=True)(inputs)
model = Model(inputs=inputs, outputs=[state_h, state_c])
print (model.predict(np.zeros((batch_size, num_steps, num_input))))
print (model.layers[1].cell.state_size)
Примечание: В случае GRU / RNN состояние ячейки отсутствует, есть только скрытое состояние, поэтому состояние ячейки в случае составляет всего h_t
размера (batch_size, hidden_size)
Ссылка:
Реализация Keras LSTM
Документы Keras:
количество тензоров состояния равно 1 (для RNN и GRU) или 2 (для LSTM).
Иллюстрированное руководство по LSTM и GRU
Состояния подачи
В вашем примере layers[0]
обозначает 1 LSTM, а layers[1]
обозначает 2-й LSTM.Если вы хотите инициализировать состояние ячейки (c_t
) n-го пакета, начиная с состояния ячейки (n-1), т. Е. В предыдущем пакете есть два варианта:
.как вы делаете в генераторе, но используйте states[1]
, если вы хотите c_t
и states[0]
для h_t
.Аналогичным образом используйте layers[0]
для 1-го LSTM и layers[1]
для второго LSTM.Но вместо этого используйте set_value
методы.Смотрите редактирование ниже.
Use keras Stateful=True
: Если для состояния задано значение true, состояния LSTM не сбрасываются после каждой партии.Так что если у вас есть партия с 5 выборками данных (каждая с некоторой длиной последовательности), вы получите состояние ячейки для каждой из 5 выборок данных.Если для состояния с состоянием установлено значение true, эти состояния используются для инициализации следующего состояния ячейки пакета для следующего пакета.
Edit:
Метод set_value
должен использоваться дляустановить значение тензорной переменной.Код model.layers[0].states[0] = K.variable(value=hidden_states[gen_data.current_idx])
действителен, потому что он изменяет состояние [0], которое указывало на переменную размера (batch_size X hidden_size), на переменную размера (batch_size x 2).Оно не меняет значение тензорной переменной, а скорее указывает на новую тензорную переменную другой размерности.
Тестовый код:
print (model.layers[0].states[0], hex(id(model.layers[0].states[0])))
model.layers[0].states[0]= K.variable(np.random.randn(10,2))
print (model.layers[0].states[0], hex(id(model.layers[0].states[0])))
Выход
<tf.Variable 'lstm_18/Variable:0' shape=(10, 8) dtype=float32_ref> 0x7f8812e6ee10
<tf.Variable 'Variable_2:0' shape=(10, 2) dtype=float32_ref> 0x7f881269afd0
Как видите, это две разные переменные.Правильный способ сделать это -
print (model.layers[0].states[0], hex(id(model.layers[0].states[0])))
K.set_value(model.layers[0].states[0], np.random.randn(10,8))
print (model.layers[0].states[0], hex(id(model.layers[0].states[0])))
Вывод
<tf.Variable 'lstm_20/Variable:0' shape=(10, 8) dtype=float32_ref> 0x7f881138eb70
<tf.Variable 'lstm_20/Variable:0' shape=(10, 8) dtype=float32_ref> 0x7f881138eb70
Если ваш код исправлен, то
K.set_value(model.layers[0].states[0], np.random.randn(10,2))
выдаст ошибку как размер тензораи размер значения, которое вы устанавливаете, чтобы не совпадать.