具有动态形状的 tf.unstack [英] tf.unstack with dynamic shape

查看:27
本文介绍了具有动态形状的 tf.unstack的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试对张量进行解压,因为我需要一个序列作为 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆