我正在尝试从不同大小的图像中随机裁剪(大小随时间变化并存储在 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'
。我有最后一行的原因是我的代码需要指定 channel 数,否则我会得到 ValueError: The channel dimension of inputs should be defined。发现“无”。
最终,我设法让它与这个一起工作:
patches.set_shape([num_patches, None, None, 3])
但是我有以下几行:
net = slim.flatten(net)
logits = slim.fully_connected(net, 1, activation_fn=None)
现在失败并显示 ValueError:应该定义输入到
Dense 的最后一个维度。发现“无”。
所以这仍然是一个问题。如何处理可变大小的图像裁剪?
最佳答案
set_shape
方法不允许用张量定义形状。这是合理的,因为它没有进行 TensorFlow 操作。它实际上是当场重新定义了张量的静态形状。
由于 patch_size
是动态的,因此不应将其用于设置静态形状。相反,正如您已经知道的那样,这些维度必须保持未定义状态:
patches.set_shape([num_patches, None, None, 3])
第二个问题的出现是因为某些操作需要定义输入的特定维度。特别地,全连接层保留权重矩阵 [#I, #O]
,其中 #I
和 #O
是大小输入和输出,分别。如果输入端没有静态形状,则无法正确初始化该矩阵。密集层不会立即起作用,即使在展平之后也是如此(这只是为了 #I = W * H
)。另一方面,二维卷积起作用,因为权重矩阵仅取决于内核大小和滤波器数量 [nf, kh, kw]
。
不可避免地,这种活力会带来一定的代价:您的网络模型需要以一种独立于高度和宽度维度上的传入输入大小的方式工作。在 CNN 中,一种可能的方法是使用 N
过滤器执行 1x1 卷积,然后是全局平均 2D 池。后者的最短实现是 tf.reduce_mean(x, [1, 2])
。此时你有一个静态形状的张量 [B, N]
,其中 N
是静态已知的,B
只是批量大小,在典型情况下可以是 None
。
关于python - 如何使用可变补丁大小的 tf.random_crop 定义形状?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45062035/