具有动态形状的 tf.unstack [英] tf.unstack with dynamic shape
问题描述
我正在尝试对张量进行解压,因为我需要一个序列作为 RNN 的输入.我正在使用可变序列长度,这使我无法正确使用 tf.unstack
.
I'm trying to unstack a Tensor because I need a sequence as input for the RNN. I am using variable sequence lengths which prevents me from correctly using tf.unstack
.
def MapToSequences(x):
# x.get_shape().as_list() = [64, 1, None, 512]
x = tf.squeeze(x)
# tf.shape(x) = [None, None, None], at runtime would be [64, seqlen, 512]
x = tf.transpose(x, perm=[1, 0, 2])
# [seqlen, 64, 512]
# Here I'd like to unstack with seqlen as num
x = tf.unstack(x) # Cannot infer num from shape (?, ?, ?)
return x
我尝试使用 tf.shape(x)
来推断 seqlen 并将其用作 num
,但我得到 Expected int for argument 'num' not<tf.Tensor 'strided_slice:0' shape=() dtype=int32>
I tried using tf.shape(x)
to infer the seqlen and use it as num
, but I get Expected int for argument 'num' not <tf.Tensor 'strided_slice:0' shape=() dtype=int32>
推荐答案
我相信这可能会在其他地方得到解答,但这里有一个答案.您不能将 tf.unstack
与不可推断的维度一起使用.这是因为如何使用定义张量转换的计算图来设计 tensorflow.每个操作添加一个节点,每个 Tensor 是节点之间的一条边.当你 tf.unstack
一个张量时,你会生成多个新的张量(边).如果未定义从 tf.unstack
操作创建的新张量的数量,则计算图具有未定义的边数,但不能如此.不向图中添加多个新边的操作允许具有推断维度的输入张量(大多数操作).
I believe this may be answered elsewhere, but here's an answer here. You cannot use tf.unstack
with non-inferrable dimensions.
This is because of how tensorflow is designed with computation graphs defining transformations of Tensors. Each operation adds a node, and each Tensor is an edge between Nodes. When you tf.unstack
a Tensor you generate multiple new Tensors (edges). If the number of new tensors created from a tf.unstack
operation is undefined then the computation graph has an undefined number of edges which must not be.
Operations that don't add multiple new edges to the graph are allowed to have input Tensors with inferred dimensions (most operations).
为了解决这个问题,有两种选择对于批处理操作很有用,即当您尝试 tf.unstack
维度为 (batch_size, ...)
和 batch_size
是可推断的.
To get around this one has two choices useful for the case of batched operations, i.e. in the case when you are trying to tf.unstack
a Tensor with dimensions (batch_size, ...)
and batch_size
is inferrable.
我会在 keras.topology.Input
中使用 batch_shape
参数.生成的权重张量始终可以与使用不同 batch_size
生成的另一个模型互换.
I would use the batch_shape
argument to keras.topology.Input
.
The weight Tensors produced will always be interchangable with another model generated with different batch_size
.
除非您需要访问具有不可推断维度的计算图,否则您没有理由不选择这条路线.
Unless you need access to the computation graph with that non-inferrable dimension there is no reason why you should not that this route.
如果您知道最大 batch_size
,第二种选择是使用 tf.dynamic_partition
.
A second option, in the case when you know a maximal batch_size
, is to use tf.dynamic_partition
.
tensor = tf.placeholder(tf.float32,shape=(None,10))
partitions = tf.range(max_batch_size)
num_partitions = max_batch_size
partitioned = tf.dynamic_partition(tensor, partitions, num_partitions, name='dynamic_unstack')
当您实际给出 batch_size
时,它将为第一个 batch_size
索引生成未堆叠的 Tesor,而为其余的 []
生成空张量.
When you actually give a batch_size
it will produce unstacked Tesors for the first batch_size
indices, and []
empty Tensors for the rest.
这篇关于具有动态形状的 tf.unstack的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!