def gen_episode(self, memory, q_vec, fact_vecs, i): def gen_attn(fact_vec, _reuse=tf.AUTO_REUSE): with tf.variable_scope('attention', reuse=_reuse): features = [ fact_vec * q_vec, fact_vec * memory, tf.abs(fact_vec - q_vec), tf.abs(fact_vec - memory) ] feature_vec = tf.concat(features, 1) attention = tf.layers.dense(feature_vec, args.embed_dim, tf.tanh, reuse=_reuse, name='fc1') attention = tf.layers.dense(attention, 1, reuse=_reuse, name='fc2') return tf.squeeze(attention, 1) # Gates (attentions) are activated, if sentence relevant to the question or memory attns = tf.map_fn(gen_attn, tf.transpose(fact_vecs, [1, 0, 2])) attns = tf.transpose(attns) # (B, n_fact) attns = tf.nn.softmax(attns) # (B, n_fact) attns = tf.expand_dims(attns, -1) # (B, n_fact, 1) # The relevant facts are summarized in another GRU reuse = i > 0 with tf.variable_scope('attention_gru', reuse=reuse): _, episode = tf.nn.dynamic_rnn( AttentionGRUCell(args.hidden_size, reuse=reuse), tf.concat([fact_vecs, attns], 2), # (B, n_fact, D+1) self.placeholders['inputs_len'], dtype=np.float32) return episode # (B, D)
def gen_episode(features, memory, q_vec, fact_vecs, is_training): def gen_attn(fact_vec): features = [ fact_vec * q_vec, fact_vec * memory, tf.abs(fact_vec - q_vec), tf.abs(fact_vec - memory) ] feature_vec = tf.concat(features, 1) attention = tf.layers.dense(feature_vec, args.embed_dim, tf.tanh, name='attn_proj_1') attention = tf.layers.dense(attention, 1, name='attn_proj_2') return tf.squeeze(attention, 1) # Gates (attentions) are activated, if sentence relevant to the question or memory attns = tf.map_fn(gen_attn, tf.transpose(fact_vecs, [1, 0, 2])) attns = tf.transpose(attns) # (B, n_fact) attns = tf.nn.softmax(attns) # (B, n_fact) attns = tf.expand_dims(attns, -1) # (B, n_fact, 1) # The relevant facts are summarized in another GRU _, episode = tf.nn.dynamic_rnn( AttentionGRUCell(args.hidden_size, name='attn_gru'), tf.concat([fact_vecs, attns], 2), # (B, n_fact, D+1) features['inputs_len'], dtype=np.float32) return episode # (B, D)
def gen_episode(self, memory, q_vec, fact_vecs, i): # Gates (attentions) are activated if sentence relevant to the question or memory attentions = [self.gen_attention(memory, q_vec, fact_vec, bool(i) or bool(n_fact)) for n_fact, fact_vec in enumerate(tf.unstack(fact_vecs, axis=1))] # n_fact list of (B,) attentions = tf.transpose(tf.stack(attentions)) # (B, n_fact) attentions = tf.nn.softmax(attentions) # (B, n_fact) attentions = tf.expand_dims(attentions, -1) # (B, n_fact, 1) # The relevant facts are summarized in another GRU reuse = i > 0 with tf.variable_scope('attention_gru', reuse=reuse): _, episode = tf.nn.dynamic_rnn( AttentionGRUCell(args.hidden_size, reuse=reuse), tf.concat([fact_vecs, attentions], 2), # (B, n_fact, D+1) self.placeholders['inputs_len'], dtype=np.float32) return episode # (B, D)