2

私は現在、次の論文からアテンション メカニズムをコーディングしようとしています: "Effective Approaches to Attention-based Neural Machine Translation", Luong, Pham, Manning (2015) . (私はドット スコアでグローバルな注意を使用します)。

ただし、lstm デコードから非表示および出力状態を入力する方法がわかりません。問題は、時間 t での lstm デコーダーの入力が、t-1 からの出力と隠れ状態を使用して計算する必要がある量に依存することです。

コードの関連部分は次のとおりです。

with tf.variable_scope('data'):
    prob = tf.placeholder_with_default(1.0, shape=())
    X_or = tf.placeholder(shape = [batch_size, timesteps_1, num_input], dtype = tf.float32, name = "input")
    X = tf.unstack(X_or, timesteps_1, 1)
    y = tf.placeholder(shape = [window_size,1], dtype = tf.float32, name = "label_annotation")
    logits = tf.zeros((1,1), tf.float32)

with tf.variable_scope('lstm_cell_encoder'):
    rnn_layers = [tf.nn.rnn_cell.LSTMCell(size) for size in [hidden_size, hidden_size]]
    multi_rnn_cell = tf.nn.rnn_cell.MultiRNNCell(rnn_layers)
    lstm_outputs, lstm_state =  tf.contrib.rnn.static_rnn(cell=multi_rnn_cell,inputs=X,dtype=tf.float32)
    concat_lstm_outputs = tf.stack(tf.squeeze(lstm_outputs))
    last_encoder_state = lstm_state[-1]

with tf.variable_scope('lstm_cell_decoder'):

    initial_input = tf.unstack(tf.zeros(shape=(1,1,hidden_size2)))
    rnn_decoder_cell = tf.nn.rnn_cell.LSTMCell(hidden_size, state_is_tuple = True)
    # Compute the hidden and output of h_1

    for index in range(window_size):

        output_decoder, state_decoder = tf.nn.static_rnn(rnn_decoder_cell, initial_input, initial_state=last_encoder_state, dtype=tf.float32)

        # Compute the score for source output vector
        scores = tf.matmul(concat_lstm_outputs, tf.reshape(output_decoder[-1],(hidden_size,1)))
        attention_coef = tf.nn.softmax(scores)
        context_vector = tf.reduce_sum(tf.multiply(concat_lstm_outputs, tf.reshape(attention_coef, (window_size, 1))),0)
        context_vector = tf.reshape(context_vector, (1,hidden_size))

        # compute the tilda hidden state \tilde{h}_t=tanh(W[c_t, h_t]+b_t)
        concat_context = tf.concat([context_vector, output_decoder[-1]], axis = 1)
        W_tilde = tf.Variable(tf.random_normal(shape = [hidden_size*2, hidden_size2], stddev = 0.1), name = "weights_tilde", trainable = True)
        b_tilde = tf.Variable(tf.zeros([1, hidden_size2]), name="bias_tilde", trainable = True)
        hidden_tilde = tf.nn.tanh(tf.matmul(concat_context, W_tilde)+b_tilde) # hidden_tilde is [1*64]

        # update for next time step
        initial_input = tf.unstack(tf.reshape(hidden_tilde, (1,1,hidden_size2)))
        last_encoder_state = state_decoder

        # predict the target

        W_target = tf.Variable(tf.random_normal(shape = [hidden_size2, 1], stddev = 0.1), name = "weights_target", trainable = True)
        logit = tf.matmul(hidden_tilde, W_target)
        logits = tf.concat([logits, logit], axis = 0)

    logits = logits[1:]

ループの内側の部分は、私が確信していないものです。変数「initial_input」と「last_encoder_state」を上書きすると、テンソルフローは計算グラフを覚えていますか?

4

1 に答える 1

1

またはのいずれかtf.contrib.seq2seq.AttentionWrapperの実装で使用すると、モデルが大幅に簡素化されると思います。BahdanauAttentionLuongAttention

このようにして、アテンション ベクトルをセル レベルで配線することが可能になるため、アテンションが適用された後にセル出力が既に出力されます。seq2seq チュートリアルの例:

cell = LSTMCell(512)
attention_mechanism = tf.contrib.seq2seq.LuongAttention(512, encoder_outputs)
attn_cell = tf.contrib.seq2seq.AttentionWrapper(cell, attention_mechanism, attention_size=256)

orは慎重にラップされたセルをインスタンス化するwindow_sizeため、この方法では のループは必要ないことに注意してください。tf.nn.static_rnntf.nn.dynamic_rnn


あなたの質問に関して: Python 変数とテンソルフロー グラフ ノードを区別する必要があります:last_encoder_state別のテンソルに割り当てることができます。これにより、元のグラフ ノードは変更されません。これは柔軟ですが、結果のネットワークで誤解を招く可能性もあります。LSTM を 1 つのテンソルに接続していると思うかもしれませんが、実際には別のテンソルです。一般に、これを行うべきではありません。

于 2018-02-07T18:06:21.560 に答える