1. 程式人生 > >從rnn到lstm,再到seq2seq(二)

從rnn到lstm,再到seq2seq(二)

app 感受 ima bsp expand images cat https github

技術分享

技術分享

從圖上可以看出來,decode的過程其實都是從encode的最後一個隱層開始的,如果encode輸入過長的話,會丟失很多信息,所以設計了attation機制。

attation機制的decode的過程和原來的最大的區別就是,它輸出的不只是基於本時刻的h,而是基於本時刻的h和C的concat矩陣。

那麽C是什麽,C就是encode的h的聯合(見最後一張圖的公式),含義非常明顯了,就是我在decode的時候,不但考慮我現在decode的隱層的情況,同時也考慮到encode的隱層的情況,那麽關鍵是encode的隱層那麽多,你該怎麽考慮了,這就是attation矩陣的計算方式。。目前的計算方式是,這個時刻decode的隱層和encode的所有隱層做個對應,最後一張圖非常明白

技術分享

技術分享

技術分享

如果你還沒有理解,看這個公式,輸入的d‘t就是我上面說的C,把這個和dt concat就是本時刻輸出的隱層

技術分享

其實實現起來不復雜,就是在decode的時候,隱層和encode的隱層對應一下,然後concat一下:

下面這個代碼是在github上找的,兩個隱層對應的方式可能跟上面說的不一樣,但是原理都差不多,看這個代碼感受一下這個流程。

s = self.encoder.zero_state(self.batch_size, tf.float32)
        encoder_hs = []
        with tf.variable_scope(
"encoder"): for t in xrange(self.max_size): if t > 0: tf.get_variable_scope().reuse_variables() x = tf.squeeze(source_xs[t], [1]) x = tf.matmul(x, self.s_proj_W) + self.s_proj_b h, s = self.encoder(x, s) encoder_hs.append(h) encoder_hs
= tf.pack(encoder_hs) s = self.decoder.zero_state(self.batch_size, tf.float32) logits = [] probs = [] with tf.variable_scope("decoder"): for t in xrange(self.max_size): if t > 0: tf.get_variable_scope().reuse_variables() if not self.is_test or t == 0: x = tf.squeeze(target_xs[t], [1]) x = tf.matmul(x, self.t_proj_W) + self.t_proj_b h_t, s = self.decoder(x, s) h_tld = self.attention(h_t, encoder_hs) oemb = tf.matmul(h_tld, self.proj_W) + self.proj_b logit = tf.matmul(oemb, self.proj_Wo) + self.proj_bo prob = tf.nn.softmax(logit) logits.append(logit) probs.append(prob) def attention(self, h_t, encoder_hs): #scores = [tf.matmul(tf.tanh(tf.matmul(tf.concat(1, [h_t, tf.squeeze(h_s, [0])]), # self.W_a) + self.b_a), self.v_a) # for h_s in tf.split(0, self.max_size, encoder_hs)] #scores = tf.squeeze(tf.pack(scores), [2]) scores = tf.reduce_sum(tf.mul(encoder_hs, h_t), 2) a_t = tf.nn.softmax(tf.transpose(scores)) a_t = tf.expand_dims(a_t, 2) c_t = tf.batch_matmul(tf.transpose(encoder_hs, perm=[1,2,0]), a_t) c_t = tf.squeeze(c_t, [2]) h_tld = tf.tanh(tf.matmul(tf.concat(1, [h_t, c_t]), self.W_c) + self.b_c) return h_tld

參考文章:

https://www.slideshare.net/KeonKim/attention-mechanisms-with-tensorflow

https://github.com/dillonalaird/Attention/blob/master/attention.py

http://www.tuicool.com/articles/nUFRban

http://www.cnblogs.com/rocketfan/p/6261467.html

http://blog.csdn.net/jerr__y/article/details/53749693

從rnn到lstm,再到seq2seq(二)