我对tensorflow seq2seq应用了排队读取器,以避免将整个数据集读入内存并提前全部处理。我没有首先将数据集存储到不同的存储桶文件中,以确保每个批处理都有一个存储桶大小,因为这样也会花费很多时间。因此,来自队列读取器的每批数据可能包含不同桶大小的序列,从而导致原始seq2seq模型无法运行(假设每批数据具有相同的桶大小,并且根据桶大小只选择一个子图来执行)
我试过了:
在最初的实现中,子图(与桶一样多)被构造为共享相同的参数。它们之间唯一的区别是在RNN过程中应该采取的计算时间。我将子图更改为条件图,当switch
为True时,将计算该桶的bucket_loss
并将其添加到loss_list
中,当switch
为False时,将不做任何事情并将tf.constant(0.0)
添加到loss_list
中。最后,我使用total_loss = tf.reduce_sum(loss_list)
收集所有的损失,并在其上构造梯度图。此外,我在每一步都将switches_list
输入模型。switches_list
的大小与桶的大小相同,如果此批中有第i个桶大小的数据,则switches_list
对应的第i个开关为True,否则为False。
遇到的问题:
- ,当反向传播过程经过
tf.cond(...)
节点,我被gradient.py
警告过一些稀疏张量转换成稠密的 - 当我试图获取
total_loss
或bucket_loss
时,我被告知:
ValueError: Operation u'cond/model_with_one_buckets/sequence_loss/truediv' has been marked as not fetchable.
- 我如何解决以上两个问题?
- 我应该如何修改图形以满足我的要求?
- 对于在一个桶中训练不同桶大小的数据有更好的想法吗批处理? 对seq2seq应用异步队列读取器有更好的想法吗框架不首先存储整个数据集?
我会(确实)完全抛弃bucket。使用dynamic_rnn。这里的想法是用填充符号填充你的批,尽可能多地为该批的所有成员到达相同的长度(通常只是各自批中最长成员的大小)。解决了你所有的四个问题,但是是的,重写起来有些麻烦。(我一点也不后悔)
我做了很多事情,这是非常特殊的我的情况和数据的方式,因此分享是没有意义的,但也许你想看看这个实现:可变序列长度在TensorFlow