tensorflow中tf.dynamic_rnn使用技巧

转载:http://blog.csdn.net/lyg5623/article/details/73924506

用rnn处理变长文本时,使用dynamic_rnn可以跳过padding部分的计算,减少计算量。假设有两个文本,一个长度为10,另一个长度为5,那么需要对第二文本使用0-padding方法填充,得到的shape为(2, 10, dim),其中dim是词向量维度。使用dynamic_rnn的代码如下:

outputs, last_states = tf.nn.dynamic_rnn(  cell=cell,  dtype=tf.float32, sequence_length=x_lengths,  inputs=x)

其中cell是RNN节点,比如tf.contrib.rnn.BasicLSTMCel,x是0-padding以后的数据,x_lengths是每个文本的长度。计算第二个文本的时候,只计算前面5个值,后面的就直接跳过了,对应的output直接设为0,cell的状态保持第5步的值。

dynamic_rnn返回两个变量,第一个是每个step的输出值,第二个是最终的状态。那么问题来了,对于第二个文本,我想取的肯定是第5个output,最后一个output是无效的0对我来说没有意义。目前我知道的有3种做法。

第一种是从别人代码里面看到,链接在此。作者自己写了个index的operation,代码比较绕。

        第二种是构建一个mask,长度对应的那位为1,其余的为0,比如第二个文本对应的mask为[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],然后将这个mask与outputs按时间维度进行sum,这样得到的刚好是第5个输出的值。

       第三种做法最简单,这得从rnn的定义说起,rnn的输出其实就是状态中的h,因此last_states 中的h状态就是我们需要的output。也就是我们把last_states.h当作rnn的最终输出就行了。

猜你喜欢

转载自blog.csdn.net/qq_34638161/article/details/79078390