web-dev-qa-db-ja.com

TensorFlow:次のバッチのLSTM状態を記憶する(ステートフルLSTM)

訓練されたLSTMモデルが与えられた場合、単一のタイムステップ、つまりseq_length = 1以下の例では。各タイムステップの後、次の「バッチ」のために内部LSTM(メモリおよび非表示)状態を記憶する必要があります。推論の最初に、内部LSTMにはinit_c, init_hは、入力が与えられると計算されます。これらは、LSTMに渡されるLSTMStateTupleオブジェクトに保存されます。トレーニング中、この状態はタイムステップごとに更新されます。ただし、推論のためにstateをバッチ間で保存する必要があります。つまり、最初の状態のみを計算する必要があり、その後は各「バッチ」(n = 1の後にLSTM状態を保存する必要があります)。

この関連するStackOverflowの質問を見つけました: Tensorflow、状態をRNNに保存する最良の方法? 。ただし、これはstate_is_Tuple=Falseが、この動作はTensorFlowによって非推奨になります( rnn_cell.py を参照)。 Kerasには、statefulLSTMを可能にするニースラッパーがあるようですが、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)
23
verified.human

すべてのレイヤーの状態全体をプレースホルダーに保存するのが最も簡単であることがわかりました。

init_state = np.zeros((num_layers, 2, batch_size, state_size))

...

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

次に、それを解凍し、ネイティブテンソルフローRNN Apiを使用する前にLSTMStateTuplesのタプルを作成します。

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-変数は、プレースホルダーとして次のバッチに送られます。

21
user1506145

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を使用するのではなく、正常に機能するリストのリストを作成するだけです。この例では、状態を保存していません。ただし、変数から状態を簡単に作成し、値を保存するために割り当てを使用することもできます。

6
chasep255