1

我正在尝试按照以下论文中的描述实现 BiLSTM-Max: Supervised Learning of Universal Sentence Representations from Natural Language Inference Data

我正在使用 Tensorflow 来实现。我从一个原始的 LSTM 代码开始,但已经成功地进行了修改,以便它可以在动态长度输入和双向(即 Dynamic Bi-LSTM)下运行。

# Bi-LSTM, returns output of shape [n_step, batch_size, n_input]
outputs = tf.contrib.rnn.static_bidirectional_rnn(lstm_fw_cell, lstm_bw_cell, x,dtype=tf.float32)
# Change output back to [batch_size, n_step, n_input]
outputs = tf.transpose(tf.stack(outputs), [1, 0, 2])
# Retrieve the last output corresponding the length of input sequence
batch_size_ = tf.shape(outputs)[0]
index = tf.range(0, batch_size_) * seq_max_len + (seqlen - 1)
outputs = tf.gather(tf.reshape(outputs, [-1, 2*n_hidden]), index)

接下来将其修改为 Bi-LSTM-Max,我替换了获取最后一个输出并在 n_steps 中找到最大值,如下所示:

# Bi-LSTM, returns output of shape [n_step, batch_size, n_input]
outputs = tf.contrib.rnn.static_bidirectional_rnn(lstm_fw_cell, lstm_bw_cell, x,dtype=tf.float32)
# Change output back to [batch_size, n_step, n_input]
outputs = tf.transpose(tf.stack(outputs), [1, 0, 2])
# Retrieve the max output across n_steps
outputs = tf.reduce_max(outputs, reduction_indices=[1])

当我在 n_steps 维度上取最大值时,我假设那些索引>seqlen 是 0,所以我可以在整个维度上取最大值,而不是从 0 到 seqlen 取最大值。经过仔细检查,我意识到由于随机初始化,未分配索引的值可能不为零,或者它可能只是内存中最后分配的值。

这个操作在 python 数组中是微不足道的,但是,对于张量操作,我找不到简单的方法。有人对此有想法吗?

4

1 回答 1

0

可能最简单的做法是在找到最大值之前手动将无效输出设置为零或-∞。tf.sequence_mask使用and可以很容易地做到这一点tf.where

seq_mask = tf.sequence_mask(seqlen, seq_max_len)
# You can also use e.g. -np.inf * tf.ones_like(outputs)
outputs_masked = tf.where(seq_mask, outputs, tf.zeros_like(outputs))
outputs = tf.reduce_max(outputs, axis=1)  # axis is preferred to reduction_indices
于 2017-07-13T11:13:39.523 回答