初始化LSTM隐藏状态Tensorflow / Keras

时间:2017-02-23 12:34:37

标签: tensorflow neural-network deep-learning keras lstm

有人可以解释如何在tensorflow中初始化LSTM的隐藏状态?我正在尝试构建LSTM循环自动编码器,所以在我训练了该模型后,我想将无监督模型的学习隐藏状态转移到监督模型的隐藏状态。 这是否可以使用当前的API? 这是我试图重新创建的论文:

http://papers.nips.cc/paper/5949-semi-supervised-sequence-learning.pdf

4 个答案:

答案 0 :(得分:10)

是的 - 这是可能的,但真的很麻烦。我们来看一个例子。

  1. 定义模型:

    ionic serve

    首先构建和编译模型非常重要,因为在编译时初始状态会被重置。此外 - 您需要指定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模式完成。

  2. 现在我们可以设置初始状态的值:

    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]包含单元格状态。

  3. 希望有所帮助。

答案 1 :(得分:2)

如Keras API文档所述,用于循环图层(https://keras.io/layers/recurrent/):

有关指定RNN初始状态的提示

您可以通过使用关键字参数initial_state调用RNN层来象征性地指定RNN层的初始状态。 initial_state的值应为代表RNN层初始状态的张量或张量列表。

您可以通过使用关键字参数reset_states调用states来以数字方式指定RNN图层的初始状态。 states的值应为代表RNN层初始状态的numpy数组或numpy数组的列表。

由于LSTM层具有两个状态(隐藏状态和单元状态),所以initial_statestates的值是两个张量的列表。


示例

无状态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)>
>>>

答案 2 :(得分:0)

假设RNN位于第1层,并且隐藏/单元状态为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之后,我的状态值也保持不变。

答案 3 :(得分:0)

我使用了这种方法,对我来说完全可行:

lstm_cell = LSTM(cell_num,return_state = True)

output,h,c = lstm_cell(input,initial_state = [h_prev,c_prev])