(query, facts, attention_size, mask, stag='null', mode='LIST', softmax_stag=1, time_major=False, return_alphas=False)
| 217 | return auc |
| 218 | |
| 219 | def attention(query, facts, attention_size, mask, stag='null', mode='LIST', softmax_stag=1, time_major=False, return_alphas=False): |
| 220 | if isinstance(facts, tuple): |
| 221 | # In case of Bi-RNN, concatenate the forward and the backward RNN outputs. |
| 222 | facts = tf.concat(facts, 2) |
| 223 | |
| 224 | if time_major: |
| 225 | # (T,B,D) => (B,T,D) |
| 226 | facts = tf.array_ops.transpose(facts, [1, 0, 2]) |
| 227 | |
| 228 | mask = tf.equal(mask, tf.ones_like(mask)) |
| 229 | hidden_size = facts.get_shape().as_list()[-1] # D value - hidden size of the RNN layer |
| 230 | input_size = query.get_shape().as_list()[-1] |
| 231 | |
| 232 | # Trainable parameters |
| 233 | w1 = tf.Variable(tf.random_normal([hidden_size, attention_size], stddev=0.1)) |
| 234 | w2 = tf.Variable(tf.random_normal([input_size, attention_size], stddev=0.1)) |
| 235 | b = tf.Variable(tf.random_normal([attention_size], stddev=0.1)) |
| 236 | v = tf.Variable(tf.random_normal([attention_size], stddev=0.1)) |
| 237 | |
| 238 | with tf.name_scope('v'): |
| 239 | # Applying fully connected layer with non-linear activation to each of the B*T timestamps; |
| 240 | # the shape of `tmp` is (B,T,D)*(D,A)=(B,T,A), where A=attention_size |
| 241 | tmp1 = tf.tensordot(facts, w1, axes=1) |
| 242 | tmp2 = tf.tensordot(query, w2, axes=1) |
| 243 | tmp2 = tf.reshape(tmp2, [-1, 1, tf.shape(tmp2)[-1]]) |
| 244 | tmp = tf.tanh((tmp1 + tmp2) + b) |
| 245 | |
| 246 | # For each of the timestamps its vector of size A from `tmp` is reduced with `v` vector |
| 247 | v_dot_tmp = tf.tensordot(tmp, v, axes=1, name='v_dot_tmp') # (B,T) shape |
| 248 | key_masks = mask # [B, 1, T] |
| 249 | # key_masks = tf.expand_dims(mask, 1) # [B, 1, T] |
| 250 | paddings = tf.ones_like(v_dot_tmp) * (-2 ** 32 + 1) |
| 251 | v_dot_tmp = tf.where(key_masks, v_dot_tmp, paddings) # [B, 1, T] |
| 252 | alphas = tf.nn.softmax(v_dot_tmp, name='alphas') # (B,T) shape |
| 253 | |
| 254 | # Output of (Bi-)RNN is reduced with attention vector; the result has (B,D) shape |
| 255 | #output = tf.reduce_sum(facts * tf.expand_dims(alphas, -1), 1) |
| 256 | output = facts * tf.expand_dims(alphas, -1) |
| 257 | output = tf.reshape(output, tf.shape(facts)) |
| 258 | # output = output / (facts.get_shape().as_list()[-1] ** 0.5) |
| 259 | if not return_alphas: |
| 260 | return output |
| 261 | else: |
| 262 | return output, alphas |
| 263 | |
| 264 | def din_attention(query, facts, attention_size, mask, stag='null', mode='SUM', softmax_stag=1, time_major=False, return_alphas=False): |
| 265 | if isinstance(facts, tuple): |
nothing calls this directly
no test coverage detected