我试图从不同大小的图像中获取随机裁剪(大小随时间变化并存储在Variable
中)。补丁的大小发生变化并表示为张量:
patch_size = tf.Variable(128)
patches = []
for i in xrange(num_patches):
patch = tf.random_crop(images, [batch_size, patch_size, patch_size, 3])
patches.append(patch)
patches = tf.stack(patches, axis=0)
patches.set_shape([num_patches, patch_size, patch_size, 3])
但我在最后一行收到错误TypeError: int() argument must be a string or a number, not 'Tensor'
。我最后一行的原因是我的代码需要指定通道数,否则我得到ValueError: The channel dimension of the inputs should be defined. Found 'None'.
最终,我设法使其成功:
patches.set_shape([num_patches, None, None, 3])
但后来我有以下几行:
net = slim.flatten(net)
logits = slim.fully_connected(net, 1, activation_fn=None)
现在,ValueError: The last dimension of the inputs to
密集should be defined. Found 'None'.
所以这仍然是一个问题。如何处理可变尺寸的图像裁剪?
答案 0 :(得分:1)
set_shape
方法不允许使用张量定义形状。这是合理的,因为它不会进行TensorFlow操作。它实际上重新定义了当场张量的静态形状。
由于patch_size
是动态的,因此不应该用它来设置静态形状。相反,正如您已经想到的那样,这些维度必须保持未定义:
patches.set_shape([num_patches, None, None, 3])
第二个问题出现是因为某些操作需要定义输入的某些维度。特别地,完全连接的层保持权重矩阵[#I, #O]
,其中#I
和#O
分别是输入和输出的大小。如果输入处没有静态形状,则无法正确初始化此矩阵。即使在展平之后,一个致密的层也无法立即起作用(这只是使它成为#I = W * H
)。另一方面,2D卷积起作用,因为权重矩阵仅取决于内核大小和过滤器的数量[nf, kh, kw]
。
这种活力不可避免地带来了一定的代价:您的网络模型需要以与高度和宽度维度上的输入输入大小无关的方式工作。在CNN中,一种可能的方法是使用N
过滤器执行1x1卷积,然后是全局平均2D池。后者的最短实施是tf.reduce_mean(x, [1, 2])
。此时,您有一个静态形状的张量[B, N]
,其中N
是静态已知的,而B
只是批量大小,在典型情况下可以是None
。< / p>