初始化LSTM隐藏状态Tensorflow/Keras

初始化LSTM隐藏状态Tensorflow/Keras,tensorflow,neural-network,deep-learning,keras,lstm,Tensorflow,Neural Network,Deep Learning,Keras,Lstm,有人能解释一下如何在tensorflow中初始化LSTM的隐藏状态吗?我正在尝试构建LSTM循环自动编码器,所以在我训练了模型之后,我想将学习到的无监督模型的隐藏状态转换为有监督模型的隐藏状态。 这在当前的API中是可能的吗? 这是我试图重新创建的文件: 是-这是可能的,但确实很麻烦。让我们看一个例子 定义模型: from keras.layers import LSTM, Input from keras.models import Model input = Input(batch_sha

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


是-这是可能的,但确实很麻烦。让我们看一个例子

  • 定义模型:

    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\u形状
    ,其中指定了
    batch\u大小
    ,在这种情况下,我们的网络应该是
    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
    变量提供。
    状态[0]
    保存隐藏状态,
    状态[1]
    保存单元格状态


  • 希望有帮助。

    假设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之后,我的状态值也保持不变。

    我使用了这种方法,完全适合我:

    lstm_cell = LSTM(cell_num, return_state=True) 
    
    output, h, c = lstm_cell(input, initial_state=[h_prev, c_prev])
    

    如Keras API文件中关于重复层()所述:

    关于指定RNN初始状态的说明

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

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

    由于LSTM层有两种状态(隐藏状态和单元状态),
    initial_state
    states
    的值是两个张量的列表


    例子 无状态LSTM 输入形状:(批次、时间步、特征)=(1、10、1)
    LSTM层中的单元数=8(即隐藏和单元状态的维度)

    将tensorflow导入为tf
    将numpy作为np导入
    输入=np.random.random([1,10,1]).astype(np.float32)
    lstm=tf.keras.layers.lstm(8)
    c_0=tf.convert_to_张量(np.random.random([1,8]).astype(np.float32))
    h_0=tf.convert_to_张量(np.random.random([1,8]).astype(np.float32))
    输出=lstm(输入,初始状态=[h_0,c_0])
    
    有状态LSTM 输入形状:(批次、时间步、特征)=(1、10、1)
    LSTM层中的单元数=8(即隐藏和单元状态的维度)

    请注意,对于有状态lstm,还需要指定批处理大小

    将tensorflow导入为tf
    将numpy作为np导入
    从pprint导入pprint
    输入=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_张量(np.random.random([1,8]).astype(np.float32))
    h_0=tf.convert_to_张量(np.random.random([1,8]).astype(np.float32))
    输出=lstm(输入,初始状态=[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)>]
    
    或将其设置为特定值:

    >>> 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)>
    >>>
    
    >lstm.reset_状态(状态=[h_0,c_0])
    >>>pprint(第一大州)
    [,
    ]
    >>>
    >>>pprint(h_0)
    >>>
    >>>pprint(c_0)
    >>>
    
    如果我只想设置初始隐藏状态,代码会是model.layers[1]。states[0][0]=h\u 0执行此操作时,我收到一个错误,指出隐藏状态需要是符号状态。我正在使用函数API。如何将初始状态转换为符号状态?
    >>> 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)>
    >>>