使用tensorflow 1.8
我有一个RNN,我试图填充,然后将功能切片为可变长度的规范化句子
# param.batch_size = 32 params.max_doc_len = 10
# features is of shape [32, 800+]
features = tf.sparse_tensor_to_dense(features, default_value=0)
features = tf.Print(features, [tf.shape(features), features], "Features after sparse2dense")
features = tf.pad(features, tf.constant([[0, 0], [0, params.max_doc_len]]), "CONSTANT")
features = tf.Print(features, [tf.shape(features), features], "Features after pad")
# same output with
# features = features[:, :params.max_doc_len]
features = tf.strided_slice(features, [0,0], [params.batch_size, params.max_doc_len], [1,1])
features = tf.Print(features, [tf.shape(features), features], "Features after pad and drop")
然而,在切片时,我得到了错误的尺寸:
Features after sparse2dense[32 858][[1038 5 104]...]
Features after pad[32 868][[1038 5 104]...]
Features after pad and drop[10 10][[1038 5 104]...]
如果我移除了pad操作,我得到正确的输出如下:
Features after sparse2dense[32 858][[1038 5 104]...]
Features after pad and drop[32 10][[1038 5 104]...]
最糟糕的是,相同的代码在笔记本中工作正常(版本匹配)
t = tf.constant([[1, 2, 3], [4,3,2],[1, 2, 3], [4,3,2],[1, 2, 3],[9, 9, 9]])
MAX_DOC_LEN = 5
paddings = tf.constant([[0, 0], [0, MAX_DOC_LEN]])
padded = tf.pad(t, paddings, "CONSTANT")
cropped = padded[:, :MAX_DOC_LEN]
with tf.Session() as sess:
print(tf.shape(t).eval()) # [6 3]
print(tf.shape(padded).eval()) # [6 8]
print(tf.shape(cropped).eval()) # [6 5]
现在的问题是我做错了什么?
答案 0 :(得分:2)
如果我理解正确,你试图用零填充每一行,以便长度固定。事实证明,有一个非常简单的解决方案,就在代码的第一行(注意我已将tf.sparse_tensor_to_dense()
替换为tf.sparse_to_dense()
- 这些是不同的!):
filter = tf.less( features.indices[ :, 1 ], params.max_doc_len )
features = tf.sparse_retain( features, filter )
features = tf.sparse_to_dense( sparse_indices = features.indices,
output_shape = ( params.batch_size, params.max_doc_len ),
sparse_values = features.values,
default_value = 0 )
前两行只是实现了一个过滤器,可以抛弃任何超出max_doc_len
的值,所以基本上会截断所有行。
这里的主要思想是tf.sparse_to_dense()
允许手动指定我们想要的结果张量的形状,并且无论如何它用零填充其余部分。所以这一行代码就是你的代码部分。
P.S。尽管如此,TensorFlow中可能存在的错误仍然存在,但我无法在任何地方重现该问题。