我正在尝试创建一个可以对图像中的每个像素进行分类的深度CNN。我正在从this论文中拍摄的下图中复制建筑。在论文中提到使用去卷积使得任何大小的输入都是可能的。这可以在下图中看到。
目前,我已经硬编码我的模型以接受大小为32x32x7的图像,但我想接受任何大小的输入。 我需要对代码进行哪些更改以接受可变大小的输入?
x = tf.placeholder(tf.float32, shape=[None, 32*32*7])
y_ = tf.placeholder(tf.float32, shape=[None, 32*32*7, 3])
...
DeConnv1 = tf.nn.conv3d_transpose(layer1, filter = w, output_shape = [1,32,32,7,1], strides = [1,2,2,2,1], padding = 'SAME')
...
final = tf.reshape(final, [1, 32*32*7])
W_final = weight_variable([32*32*7,32*32*7,3])
b_final = bias_variable([32*32*7,3])
final_conv = tf.tensordot(final, W_final, axes=[[1], [1]]) + b_final
答案 0 :(得分:6)
Tensorflow允许在占位符中包含多个动态(a.k.a。<!-- [Kofax] 2016-Apr-14 MAS: Passes through the command-line parameter for selecting the branding and sets
corporate as the default. -->
<condition property="title.branding" value="${title.branding}" else="corporate">
<isset property="title.branding"/>
</condition>
</target>
)维度。在构建图形时,引擎无法确保正确性,因此客户端负责提供正确的输入,但它提供了很大的灵活性。
所以我来自......
None
为...
x = tf.placeholder(tf.float32, shape=[None, N*M*P])
y_ = tf.placeholder(tf.float32, shape=[None, N*M*P, 3])
...
x_image = tf.reshape(x, [-1, N, M, P, 1])
由于您打算将输入重新整形为5D,所以为什么不从一开始就在# Nearly all dimensions are dynamic
x_image = tf.placeholder(tf.float32, shape=[None, None, None, None, 1])
label = tf.placeholder(tf.float32, shape=[None, None, 3])
中使用5D。此时,x_image
的第二个维度是任意的,但我们承诺 tensorflow它将与label
匹配。
接下来,关于tf.nn.conv3d_transpose
的好处是它的输出形状可以是动态的。所以不要这样:
x_image
......你可以这样做:
# Hard-coded output shape
DeConnv1 = tf.nn.conv3d_transpose(layer1, w, output_shape=[1,32,32,7,1], ...)
这样,转置卷积可以应用于任何图像,结果将采用在运行时实际传入的# Dynamic output shape
DeConnv1 = tf.nn.conv3d_transpose(layer1, w, output_shape=tf.shape(x_image), ...)
形状。
请注意,x_image
的静态形状为x_image
。
最后也是最重要的一点是让整个网络卷积,这也包括你最后的密集层。密集层必须静态定义其维度,这会强制整个神经网络修复输入图像维度。
幸运的是,Springenberg在描述了用"Striving for Simplicity: The All Convolutional Net"纸张中的CONV层替换FC层的方法。我将使用带有3个(?, ?, ?, ?, 1)
过滤器的卷积(另请参阅this question):
1x1x1
如果我们确保final_conv = conv3d_s1(final, weight_variable([1, 1, 1, 1, 3]))
y = tf.reshape(final_conv, [-1, 3])
与final
(和其他人)具有相同的维度,则会使DeConnv1
符合我们想要的形状:y
。
您的网络非常庞大,但所有解卷积基本上都遵循相同的模式,因此我将概念验证代码简化为一个解卷积。目标只是展示哪种网络能够处理任意大小的图像。最后评论:图像尺寸可以在批次之间变化,但在一批中它们必须相同。
完整代码:
[-1, N * M * P, 3]
答案 1 :(得分:-1)
理论上,它是可能的。您需要将输入和标签图像占位符的图像大小设置为none
,并让图形从输入数据动态推断图像大小。
但是,定义图表时必须小心。需要使用tf.shape
代替tf.get_shape()
。前者仅在您session.run
时动态推断形状,后者可以在定义图形时获得形状。但是当输入大小设置为none
时,后者不会得到真正的重塑(可能只返回None)。
为了使事情变得复杂,如果您使用tf.layers.conv2d
或upconv2d
,有时这些高级函数不喜欢tf.shape
,因为它们似乎假设形状信息在图形期间可用施工。
我希望我有更好的工作实例来展示上述要点。我将这个答案作为占位符,如果有机会我会回来添加更多内容。