在TensorFlow中展平张量的两个最后维度

问题描述 投票:3回答:2

我正试图将[A, B, C, D]的张量重塑成[A, B, C * D]并将其喂入dynamic_rnn。假设我事先不知道B,C和D(它们是卷积网络的结果)。

我认为在Theano这样的重塑会像这样:

x = x.flatten(ndim=3)

似乎在TensorFlow中没有简单的方法可以做到这一点,到目前为止,这是我想出的:

x_shape = tf.shape(x)
x = tf.reshape(x, [batch_size, x_shape[1], tf.reduce_prod(x_shape[2:])]

即使在图形构建期间知道x的形状(即print(x.get_shape())打印出绝对值,如重塑[10, 20, 30, 40]变成get_shape()之后的[10, None, None]。再次,仍然假设初始形状未知,所以我不能用绝对值操作。

当我将x传递给dynamic_rnn时,它失败了:

ValueError: Input size (depth of inputs) must be accessible via shape inference, but saw value None.

为什么reshape无法处理此案?在TensorFlow中复制Theano的flatten(ndim=n)的正确方法是什么?使用4级以上的张量?

python tensorflow theano rnn
2个回答
2
投票

我根据你的要求尝试了一个简单的代码。由于您正在尝试重塑CNN输出,因此X的形状与Tensorflow中CNN的输出相同。

HEIGHT = 100
WIDTH  = 200
N_CHANELS =3

N_HIDDEN =64

X = tf.placeholder(tf.float32, shape=[None,HEIGHT,WIDTH,N_CHANELS],name='input') # output of CNN

shape = X.get_shape().as_list() # get the shape of each dimention shape[0] =BATCH_SIZE , shape[1] = HEIGHT , shape[2] = HEIGHT = WIDTH , shape[3] = N_CHANELS

input = tf.reshape(X, [-1, shape[1] , shape[2] * shape[3]])
print(input.shape) # prints (?, 100, 600)

#Input for tf.nn.dynamic_rnn should be in the shape of [BATCH_SIZE, N_TIMESTEPS, INPUT_SIZE]     

#Therefore, according to the reshape N_TIMESTEPS = 100 and INPUT_SIZE= 600

#create the RNN here
lstm_layers = tf.contrib.rnn.BasicLSTMCell(N_HIDDEN, forget_bias=1.0)
outputs, _ = tf.nn.dynamic_rnn(lstm_layers, input, dtype=tf.float32)

希望这可以帮助。


2
投票

它不是reshape的缺陷,而是tf.dynamic_rnn的限制。

用于展平最后两个维度的代码是正确的。并且,reshape也正确行为:如果在定义展平操作时最后两个维度是未知的,那么它们的产品也是如此,而None是此时可以返回的唯一合适的值。

罪魁祸首是tf.dynamic_rnn,它期望在构造期间具有完全定义的特征形状,即必须知道除第一(批量大小)和第二(时间步长)之外的所有尺寸。这或许有点不幸,但目前的实施似乎并不允许具有可变数量特征的RNN,即FCN。

© www.soinside.com 2019 - 2024. All rights reserved.