tensor flow dynamic_rnn 与rnn有啥区别?

最近看了一下rnn.py中的源码。由于水平有限,没有完全看懂,看到rnn函数和dynamic_rnn函数的时候,总感觉这两函数没啥区别,只是一个输入是…
关注者
221
被浏览
52,008
登录后你可以
不限量看优质回答私信答主深度交流精彩内容一键收藏

在每一个train step,传入model的是一个batch的数据(这一个batch的数据forward得到predictions,计算loss,backpropagation更新参数),这一个batch内的数据一定是padding成相同长度的。

那么,如果可以只在一个batch内部进行padding,例如一个batch中数据长度均在6-10这个范围内,就可以让这个batch中所有数据pad到固定长度10,而整个dataset上的数据最大长度很可能是100,这样就不需要让这些数据也pad到100那么长,白白浪费空间。

所以dynamic_rnn实现的功能就是可以让不同迭代传入的batch可以是长度不同数据,但同一次迭代一个batch内部的所有数据长度仍然是固定的。例如,第一时刻传入的数据shape=[batch_size, 10],第二时刻传入的数据shape=[batch_size, 12],第三时刻传入的数据shape=[batch_size, 8]等等。

但是rnn不能这样,它要求每一时刻传入的batch数据的[batch_size, max_seq],在每次迭代过程中都保持不变。

这样不就必须要求全部数据都要pad到统一的max_seq长度了吗?是的,但也有个折中办法。

——将数据集的sequence length做个初步统计,看会落在哪几个区间段内。然后根据区间段将数据进行归类,也就是所谓的放在不同buckets中。

最后用rnn为每一个buckets都创建一个sub graph。训练的时候,根据当前batch data所归属的bucket id,找到它对应的sub graph,进行参数更新(虽然是不同的sub graph,但参数是共享的。至少tensorflow中是这么实现的~\(≧▽≦)/~)

具体可参看:github.com/tensorflow/t


另外,两者的输入形式确实不同,但你提到的“将填充的部分输出为0”,给rnn传入sequence_length这个参数后,也是可以的。