垫之后的张量流切片不起作用而没有垫它

cod*_*ach 5 python tensorflow

使用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")
Run Code Online (Sandbox Code Playgroud)

但是在切片时我得到了错误的尺寸:

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]...]
Run Code Online (Sandbox Code Playgroud)

如果我删除了pad操作,我得到正确的输出如下:

Features after sparse2dense[32 858][[1038 5 104]...]
Features after pad and drop[32 10][[1038 5 104]...]
Run Code Online (Sandbox Code Playgroud)

最糟糕的是,相同的代码在笔记本中工作正常(版本匹配)

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]
Run Code Online (Sandbox Code Playgroud)

现在的问题是我做错了什么?

Pet*_*dan 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 )
Run Code Online (Sandbox Code Playgroud)

前两行只是实现一个过滤器来丢弃超出 的任何值max_doc_len,因此基本上截断了所有行。

这里的主要思想是tf.sparse_to_dense()允许手动指定结果张量的形状,这是我们想要的,并且无论如何它都会用零填充其余部分。所以这一行完成了您的代码部分的用途。

PS 尽管如此,TensorFlow 中可能存在的错误仍然存​​在,但我无法在任何地方重现该问题。