我正在尝试将张量从[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及以上的张量进行复制?
答案 0 :(得分: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)
希望这有帮助。
答案 1 :(得分:2)
这不是reshape
中的缺陷,而是tf.dynamic_rnn
的限制。
用于展平最后两个维度的代码是正确的。而且,reshape
也表现正确:如果在定义展平操作时最后两个维度未知,那么它们的产品也是如此,None
是此时唯一可以返回的值。
罪魁祸首是tf.dynamic_rnn
,它期望在构造期间具有完全定义的特征形状,即必须知道除第一个(批量大小)和第二个(时间步长)之外的所有维度。这或许有点不幸,但目前的实施似乎并不允许具有可变数量功能的RNN,即FCN。
答案 2 :(得分:0)
我通过使用 .get_shape() 找到了解决方案。 假设“x”是一个 4-D 张量。
这仅适用于 Reshape Layer。当您对模型的架构进行更改时,这应该会起作用。
x = tf.keras.layers.Reshape(x, [x.get_shape()[0], x.get_shape()[1], x.get_shape()[2] * x.get_shape()][3])
希望这有效!