初始化 LSTM 隐藏状态 Tensorflow/Keras
Initializing LSTM hidden state Tensorflow/Keras
有人可以解释一下如何在 tensorflow 中初始化 LSTM 的隐藏状态吗?我正在尝试构建 LSTM 循环自动编码器,所以在我训练了该模型之后,我想将学习的无监督模型的隐藏状态转移到监督模型的隐藏状态。
当前 API 甚至可能吗?
这是我正在尝试重新制作的纸张:
http://papers.nips.cc/paper/5949-semi-supervised-sequence-learning.pdf
是的 - 这是可能的,但确实很麻烦。让我们来看一个例子。
定义模型:
from keras.layers import LSTM, Input
from keras.models import Model
input = Input(batch_shape=(32, 10, 1))
lstm_layer = LSTM(10, stateful=True)(input)
model = Model(input, lstm_layer)
model.compile(optimizer="adam", loss="mse")
首先构建和编译模型很重要,因为在编译时会重置初始状态。此外 - 您需要指定 batch_shape
,其中指定 batch_size
,因为在这种情况下我们的网络应该是 stateful
(这是通过设置 stateful=True
模式来完成的。
现在我们可以设置初始状态的值:
import numpy
import keras.backend as K
hidden_states = K.variable(value=numpy.random.normal(size=(32, 10)))
cell_states = K.variable(value=numpy.random.normal(size=(32, 10)))
model.layers[1].states[0] = hidden_states
model.layers[1].states[1] = cell_states
请注意,您需要将状态作为 keras
变量提供。 states[0]
保存隐藏状态,states[1]
保存细胞状态。
希望对您有所帮助。
假设 RNN 在第 1 层并且 hidden/cell 状态是 numpy 数组。你可以这样做:
from keras import backend as K
K.set_value(model.layers[1].states[0], hidden_states)
K.set_value(model.layers[1].states[1], cell_states)
也可以使用
设置状态
model.layers[1].states[0] = hidden_states
model.layers[1].states[1] = cell_states
但是当我这样做时,即使在步进 RNN 之后,我的状态值也保持不变。
我使用了这种方法,完全适合我:
lstm_cell = LSTM(cell_num, return_state=True)
output, h, c = lstm_cell(input, initial_state=[h_prev, c_prev])
如 Keras API 循环层文档 (https://keras.io/layers/recurrent/) 中所述:
Note on specifying the initial state of RNNs
You can specify the initial state of RNN layers symbolically by calling them with the keyword argument initial_state
. The value of initial_state
should be a tensor or list of tensors representing the initial state of the RNN layer.
You can specify the initial state of RNN layers numerically by calling reset_states
with the keyword argument states
. The value of states
should be a numpy array or list of numpy arrays representing the initial state of the RNN layer.
由于 LSTM 层有两个状态(隐藏状态和单元状态),initial_state
和 states
的值是两个张量的列表。
例子
无状态 LSTM
输入形状:(批次、时间步长、特征)=(1、10、1)
LSTM 层中的单元数 = 8(即隐藏和单元状态的维数)
import tensorflow as tf
import numpy as np
inputs = np.random.random([1, 10, 1]).astype(np.float32)
lstm = tf.keras.layers.LSTM(8)
c_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
h_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
outputs = lstm(inputs, initial_state=[h_0, c_0])
有状态 LSTM
输入形状:(批次、时间步长、特征)=(1、10、1)
LSTM 层中的单元数 = 8(即隐藏和单元状态的维数)
请注意,对于有状态 lstm,您还需要指定 batch_size
。
import tensorflow as tf
import numpy as np
from pprint import pprint
inputs = np.random.random([1, 10, 1]).astype(np.float32)
lstm = tf.keras.layers.LSTM(8, stateful=True, batch_size=(1, 10, 1))
c_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
h_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
outputs = lstm(inputs, initial_state=[h_0, c_0])
使用有状态 LSTM,状态不会在每个序列的末尾重置,我们可以注意到层的输出对应于最后一个时间步的隐藏状态(即 lstm.states[0]
):
>>> pprint(outputs)
<tf.Tensor: id=821, shape=(1, 8), dtype=float32, numpy=
array([[ 0.07119043, 0.07012419, -0.06118739, -0.11008392, 0.00573938,
-0.05663438, 0.11196419, 0.02663924]], dtype=float32)>
>>>
>>> pprint(lstm.states)
[<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[ 0.07119043, 0.07012419, -0.06118739, -0.11008392, 0.00573938,
-0.05663438, 0.11196419, 0.02663924]], dtype=float32)>,
<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[ 0.14726108, 0.13584498, -0.12986949, -0.22309153, 0.0125412 ,
-0.11446435, 0.22290672, 0.05397629]], dtype=float32)>]
调用 reset_states()
可以重置状态:
>>> lstm.reset_states()
>>> pprint(lstm.states)
[<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=array([[0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>,
<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=array([[0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>]
>>>
或将它们设置为特定值:
>>> lstm.reset_states(states=[h_0, c_0])
>>> pprint(lstm.states)
[<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[0.59103394, 0.68249655, 0.04518601, 0.7800545 , 0.3799634 ,
0.27347744, 0.54415804, 0.9889024 ]], dtype=float32)>,
<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[0.43390197, 0.28252542, 0.27139077, 0.19655049, 0.7568088 ,
0.05909375, 0.68569875, 0.19087408]], dtype=float32)>]
>>>
>>> pprint(h_0)
<tf.Tensor: id=422, shape=(1, 8), dtype=float32, numpy=
array([[0.59103394, 0.68249655, 0.04518601, 0.7800545 , 0.3799634 ,
0.27347744, 0.54415804, 0.9889024 ]], dtype=float32)>
>>>
>>> pprint(c_0)
<tf.Tensor: id=421, shape=(1, 8), dtype=float32, numpy=
array([[0.43390197, 0.28252542, 0.27139077, 0.19655049, 0.7568088 ,
0.05909375, 0.68569875, 0.19087408]], dtype=float32)>
>>>
有人可以解释一下如何在 tensorflow 中初始化 LSTM 的隐藏状态吗?我正在尝试构建 LSTM 循环自动编码器,所以在我训练了该模型之后,我想将学习的无监督模型的隐藏状态转移到监督模型的隐藏状态。 当前 API 甚至可能吗? 这是我正在尝试重新制作的纸张:
http://papers.nips.cc/paper/5949-semi-supervised-sequence-learning.pdf
是的 - 这是可能的,但确实很麻烦。让我们来看一个例子。
定义模型:
from keras.layers import LSTM, Input from keras.models import Model input = Input(batch_shape=(32, 10, 1)) lstm_layer = LSTM(10, stateful=True)(input) model = Model(input, lstm_layer) model.compile(optimizer="adam", loss="mse")
首先构建和编译模型很重要,因为在编译时会重置初始状态。此外 - 您需要指定
batch_shape
,其中指定batch_size
,因为在这种情况下我们的网络应该是stateful
(这是通过设置stateful=True
模式来完成的。现在我们可以设置初始状态的值:
import numpy import keras.backend as K hidden_states = K.variable(value=numpy.random.normal(size=(32, 10))) cell_states = K.variable(value=numpy.random.normal(size=(32, 10))) model.layers[1].states[0] = hidden_states model.layers[1].states[1] = cell_states
请注意,您需要将状态作为
keras
变量提供。states[0]
保存隐藏状态,states[1]
保存细胞状态。
希望对您有所帮助。
假设 RNN 在第 1 层并且 hidden/cell 状态是 numpy 数组。你可以这样做:
from keras import backend as K
K.set_value(model.layers[1].states[0], hidden_states)
K.set_value(model.layers[1].states[1], cell_states)
也可以使用
设置状态model.layers[1].states[0] = hidden_states
model.layers[1].states[1] = cell_states
但是当我这样做时,即使在步进 RNN 之后,我的状态值也保持不变。
我使用了这种方法,完全适合我:
lstm_cell = LSTM(cell_num, return_state=True)
output, h, c = lstm_cell(input, initial_state=[h_prev, c_prev])
如 Keras API 循环层文档 (https://keras.io/layers/recurrent/) 中所述:
Note on specifying the initial state of RNNs
You can specify the initial state of RNN layers symbolically by calling them with the keyword argument
initial_state
. The value ofinitial_state
should be a tensor or list of tensors representing the initial state of the RNN layer.You can specify the initial state of RNN layers numerically by calling
reset_states
with the keyword argumentstates
. The value ofstates
should be a numpy array or list of numpy arrays representing the initial state of the RNN layer.
由于 LSTM 层有两个状态(隐藏状态和单元状态),initial_state
和 states
的值是两个张量的列表。
例子
无状态 LSTM
输入形状:(批次、时间步长、特征)=(1、10、1)
LSTM 层中的单元数 = 8(即隐藏和单元状态的维数)
import tensorflow as tf
import numpy as np
inputs = np.random.random([1, 10, 1]).astype(np.float32)
lstm = tf.keras.layers.LSTM(8)
c_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
h_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
outputs = lstm(inputs, initial_state=[h_0, c_0])
有状态 LSTM
输入形状:(批次、时间步长、特征)=(1、10、1)
LSTM 层中的单元数 = 8(即隐藏和单元状态的维数)
请注意,对于有状态 lstm,您还需要指定 batch_size
。
import tensorflow as tf
import numpy as np
from pprint import pprint
inputs = np.random.random([1, 10, 1]).astype(np.float32)
lstm = tf.keras.layers.LSTM(8, stateful=True, batch_size=(1, 10, 1))
c_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
h_0 = tf.convert_to_tensor(np.random.random([1, 8]).astype(np.float32))
outputs = lstm(inputs, initial_state=[h_0, c_0])
使用有状态 LSTM,状态不会在每个序列的末尾重置,我们可以注意到层的输出对应于最后一个时间步的隐藏状态(即 lstm.states[0]
):
>>> pprint(outputs)
<tf.Tensor: id=821, shape=(1, 8), dtype=float32, numpy=
array([[ 0.07119043, 0.07012419, -0.06118739, -0.11008392, 0.00573938,
-0.05663438, 0.11196419, 0.02663924]], dtype=float32)>
>>>
>>> pprint(lstm.states)
[<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[ 0.07119043, 0.07012419, -0.06118739, -0.11008392, 0.00573938,
-0.05663438, 0.11196419, 0.02663924]], dtype=float32)>,
<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[ 0.14726108, 0.13584498, -0.12986949, -0.22309153, 0.0125412 ,
-0.11446435, 0.22290672, 0.05397629]], dtype=float32)>]
调用 reset_states()
可以重置状态:
>>> lstm.reset_states()
>>> pprint(lstm.states)
[<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=array([[0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>,
<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=array([[0., 0., 0., 0., 0., 0., 0., 0.]], dtype=float32)>]
>>>
或将它们设置为特定值:
>>> lstm.reset_states(states=[h_0, c_0])
>>> pprint(lstm.states)
[<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[0.59103394, 0.68249655, 0.04518601, 0.7800545 , 0.3799634 ,
0.27347744, 0.54415804, 0.9889024 ]], dtype=float32)>,
<tf.Variable 'lstm_1/Variable:0' shape=(1, 8) dtype=float32, numpy=
array([[0.43390197, 0.28252542, 0.27139077, 0.19655049, 0.7568088 ,
0.05909375, 0.68569875, 0.19087408]], dtype=float32)>]
>>>
>>> pprint(h_0)
<tf.Tensor: id=422, shape=(1, 8), dtype=float32, numpy=
array([[0.59103394, 0.68249655, 0.04518601, 0.7800545 , 0.3799634 ,
0.27347744, 0.54415804, 0.9889024 ]], dtype=float32)>
>>>
>>> pprint(c_0)
<tf.Tensor: id=421, shape=(1, 8), dtype=float32, numpy=
array([[0.43390197, 0.28252542, 0.27139077, 0.19655049, 0.7568088 ,
0.05909375, 0.68569875, 0.19087408]], dtype=float32)>
>>>