我想训练一个具有两种不同形状的输入张量的网络。每个时代选择一种类型。 这里我写了一段小代码:
import tensorflow as tf
import numpy as np
with tf.Session() as sess:
imgs1 = tf.placeholder(tf.float32, [4, 224, 224, 3], name = 'input_imgs1')
imgs2 = tf.placeholder(tf.float32, [4, 180, 180, 3], name = 'input_imgs2')
epoch_num_tf = tf.placeholder(tf.int32, [], name = 'input_epoch_num')
imgs = tf.cond(tf.equal(tf.mod(epoch_num_tf, 2), 0),
lambda: tf.Print(imgs2, [imgs2.get_shape()], message='(even number) input epoch number is '),
lambda: tf.Print(imgs1, [imgs1.get_shape()], message='(odd number) input epoch number is'))
print(imgs.get_shape())
for epoch in range(10):
epoch_num = np.array(epoch).astype(np.int32)
imgs1_input = np.ones([4, 224, 224, 3], dtype = np.float32)
imgs2_input = np.ones([4, 180, 180, 3], dtype = np.float32)
output = sess.run(imgs, feed_dict = {epoch_num_tf: epoch_num,
imgs1: imgs1_input,
imgs2: imgs2_input})
当我执行它时,imgs.get_shape()
的输出是(4, ?, ?, 3)
即 imgs.get_shape()[1]=None、imgs.get_shape()[2]=None
。
但我将使用 imgs.get_shape()
的输出值来定义内核 (ksize
) 和步幅大小 (strides
>) 的 tf.nn.max_pool()
例如ksize=[1,imgs.get_shape()[1]/6, imgs.get_shape()[2]/6, 1]
在以后的代码中。
我认为 ksize
和 strides
无法支持 tf.Tensor
值。
如何解决这个问题?或者如何有条件地设置imgs
的形状?
最佳答案
当您执行print(a.get_shape())
时,您将获得张量a
的静态形状。假设您在上面的代码中指的是 imgs.get_shape()
而不是 a.get_shape()
,则 imgs
的尺寸 1 和 2 会动态变化epoch_num_tf
的值。因此,这些维度中的静态形状是未知的,TensorFlow 将其表示为 None
。
如果您想在后续代码中使用imgs
的动态形状,则应使用tf.shape()
运算符以 tf.Tensor 形式获取形状。例如,您可以使用 tf.shape(imgs)[2]
,而不是 imgs.get_shape()[2]
。
不幸的是,tf.nn.max_pool()
的 ksize
和 strides
参数不接受 tf.Tensor 值。 (我认为这是一个历史限制,因为它们被配置为“attrs”而不是相应内核的“输入”。如果您想请求此功能,请打开GitHub issue!)一种可能的解决方法是使用另一个tf.cond()
:
imgs = ...
# Could also use `tf.equal(tf.mod(epoch_num_tf, 2), 0)` as the predicate.
pool_output = tf.cond(tf.equal(tf.shape(imgs)[2], 180),
lambda: tf.nn.max_pool(imgs, ksize=[1, 180/6, 180/6, 1], ...),
lambda: tf.nn.max_pool(imgs, ksize=[1, 224/6, 224/6, 1], ...))
关于python - tensorflow:如何使用不同的条件语句设置张量的形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40932002/