首页 文章

TensorFlow:记住下一批次的LSTM状态(有状态LSTM)

提问于
浏览
23

给定训练有素的LSTM模型,我想对单个时间步进行推理,即下面的例子中的 seq_length = 1 . 在每个时间步之后,需要记住内部LSTM(存储器和隐藏)状态以用于下一个'batch' . 在推理的最开始,给定输入计算内部LSTM状态 init_c, init_h . 然后将它们存储在传递给LSTM的 LSTMStateTuple 对象中 . 在训练期间,每个时间步都更新此状态 . 但是对于推理,我希望 state 被保存在批次之间,即初始状态只需要在开始时计算,然后在每个'batch'(n = 1)之后保存LSTM状态 .

我发现了这个与StackOverflow相关的问题:Tensorflow, best way to save state in RNNs? . 但是这仅在 state_is_tuple=False 时有效,但TensorFlow很快就会弃用此行为(请参阅rnn_cell.py) . Keras似乎有一个很好的包装器可以使 stateful LSTM成为可能,但我不知道在TensorFlow中实现这一目标的最佳方法 . TensorFlow GitHub上的这个问题也与我的问题有关:https://github.com/tensorflow/tensorflow/issues/2838

有关构建有状态LSTM模型的任何好建议吗?

inputs  = tf.placeholder(tf.float32, shape=[None, seq_length, 84, 84], name="inputs")
targets = tf.placeholder(tf.float32, shape=[None, seq_length], name="targets")

num_lstm_layers = 2

with tf.variable_scope("LSTM") as scope:

    lstm_cell  = tf.nn.rnn_cell.LSTMCell(512, initializer=initializer, state_is_tuple=True)
    self.lstm  = tf.nn.rnn_cell.MultiRNNCell([lstm_cell] * num_lstm_layers, state_is_tuple=True)

    init_c = # compute initial LSTM memory state using contents in placeholder 'inputs'
    init_h = # compute initial LSTM hidden state using contents in placeholder 'inputs'
    self.state = [tf.nn.rnn_cell.LSTMStateTuple(init_c, init_h)] * num_lstm_layers

    outputs = []

    for step in range(seq_length):

        if step != 0:
            scope.reuse_variables()

        # CNN features, as input for LSTM
        x_t = # ... 

        # LSTM step through time
        output, self.state = self.lstm(x_t, self.state)
        outputs.append(output)

2 回答

  • 20

    我发现在占位符中保存所有图层的整个状态是最简单的 .

    init_state = np.zeros((num_layers, 2, batch_size, state_size))
    
    ...
    
    state_placeholder = tf.placeholder(tf.float32, [num_layers, 2, batch_size, state_size])
    

    然后解压缩并创建一个LSTMStateTuples元组,然后再使用本机tensorflow RNN Api .

    l = tf.unpack(state_placeholder, axis=0)
    rnn_tuple_state = tuple(
    [tf.nn.rnn_cell.LSTMStateTuple(l[idx][0], l[idx][1])
     for idx in range(num_layers)]
    )
    

    RNN通过API:

    cell = tf.nn.rnn_cell.LSTMCell(state_size, state_is_tuple=True)
    cell = tf.nn.rnn_cell.MultiRNNCell([cell]*num_layers, state_is_tuple=True)
    outputs, state = tf.nn.dynamic_rnn(cell, x_input_batch, initial_state=rnn_tuple_state)
    

    然后将 state - 变量作为占位符提供给下一批 .

  • 6

    Tensorflow,在RNN中保存状态的最佳方法?实际上是我原来的问题 . 下面的代码是我如何使用状态元组 .

    with tf.variable_scope('decoder') as scope:
        rnn_cell = tf.nn.rnn_cell.MultiRNNCell \
        ([
            tf.nn.rnn_cell.LSTMCell(512, num_proj = 256, state_is_tuple = True),
            tf.nn.rnn_cell.LSTMCell(512, num_proj = WORD_VEC_SIZE, state_is_tuple = True)
        ], state_is_tuple = True)
    
        state = [[tf.zeros((BATCH_SIZE, sz)) for sz in sz_outer] for sz_outer in rnn_cell.state_size]
    
        for t in range(TIME_STEPS):
            if t:
                last = y_[t - 1] if TRAINING else y[t - 1]
            else:
                last = tf.zeros((BATCH_SIZE, WORD_VEC_SIZE))
    
            y[t] = tf.concat(1, (y[t], last))
            y[t], state = rnn_cell(y[t], state)
    
            scope.reuse_variables()
    

    而不是使用 tf.nn.rnn_cell.LSTMStateTuple 我只是创建一个工作正常的列表列表 . 在这个例子中,我没有保存状态 . 但是,您可以很容易地从变量中取出状态,只使用assign来保存值 .

相关问题