0

LSTMセルとTensorflowを使用してテキスト生成ニューラルネットワークを作成しようとしています。私は時間主形式[time_steps、batch_size、input_size]で文章をネットワーク上で訓練しています。シーケンスの次の単語を予測するために、各時間ステップを欲しいと思います。シーケンスはタイムステップまで空の値で埋められ、別のプレースホルダにはバッチ内の各シーケンスの長さが含まれます。各タイムステップで可変長出力のコストを計算します。

バックプロパゲーションの概念については多くの情報がありますが、可変長シーケンスコスト計算のテンソルフローの実際の実装については何も見つかりません。シーケンスの終わりにはパッドが置かれているので、パッド付きの部品のコストを計算したくないと仮定しています。ですから、最初の出力からシーケンスの最後までの出力をクリップする方法が必要です。

outputs = [] 
    states = [] 
    cost = 0 
    for i in range(time_steps+1): 
     output, state = cell(X[i], state) 
     z1 = tf.matmul(output, dec_W1) + dec_b1 
     a1 = tf.nn.sigmoid(z1) 
     z2 = tf.matmul(a1, dec_W2) + dec_b2 
     a2 = tf.nn.softmax(z2) 
     outputs.append(a2) 
     states.append(state) 
     #== calculate cost 
     cost = cost + tf.nn.softmax_cross_entropy_with_logits(logits=z2, labels=y[i]) 
    optimizer = tf.train.AdamOptimizer(0.001).minimize(cost) 

このコードでは可変長シーケンスなしで動作します:

は、ここで私が現在持っているコードです。しかし、もし私が最後に追加された値をパディングすると、それはあまり意味をなさないパディングされたセクションのコストも計算されます。

シーケンスの長さ上限の前に出力のコストのみを計算するにはどうすればよいですか?

答えて

0

Worked it out!

多くの例を掘り下げた後(ほとんどがKerasなどの高レベルのフレームワークで痛みました)、マスクを作成する必要があることがわかりました。振り返ってみるとシンプルだ。

ここで1のマスクと0を作成し、要素ごと(コスト値であろう)マトリックス

x = tf.placeholder(tf.float32) 
seq = tf.placeholder(tf.int32) 

def mask_by_length(input_matrix, length): 
    ''' 
     Input matrix is a 2d tensor [batch_size, time_steps] 
     length is a 1d tensor 
     length refers to the length of input matrix axis 1 
    ''' 
    length_transposed = tf.expand_dims(length, 1) 

    # Create range in order to compare length to 
    range = tf.range(tf.shape(input_matrix)[1]) 
    range_row = tf.expand_dims(range, 0) 

    # Use the logical operations to create a mask 
    mask = tf.less(range_row, length_transposed) 

    # cast boolean to int to finalize mask 
    mask_result = tf.cast(mask, dtype=tf.float32) 

    # Element-wise multiplication to cancel out values in the mask 
    result = tf.multiply(mask_result, input_matrix) 

    return result 

mask_values = mask_by_length(x, seq) 

入力ヴァルス(時間メジャー)time_stepsに対してそれを乗算するコードです、 BATCH_SIZE]

[0.71、0.22、1.42、-0.28、0.99] [0.41、2.24、0.09、0.74、0.65]

配列ヴァルス[BATCH_SIZE]

[2,3]

出力(時間メジャー)time_steps、BATCH_SIZE]

[0.71、0.22、0、0、0、] [0.41、2.24、0.09、0、0、 ]]

関連する問題