我正在尝试创建一个深度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
动态占位符
Tensorflow允许在占位符中有多个动态(即{})维度。在构建图形时,引擎无法确保正确性,因此客户端负责提供正确的输入,但它提供了很大的灵活性。在
所以我要从。。。在
到。。。在
^{pr2}$既然您打算将输入重塑为5D,那么为什么不从一开始就在
x_image
中使用5D呢。在这一点上,label
的第二维是任意的,但是我们保证张量流将与x_image
匹配。在反褶积中的动态形状
接下来,^{} 的好处是它的输出形状可以是动态的。所以不是这样:
。。。您可以这样做:
这样,转置卷积就可以应用到任何图像,结果将呈现在运行时实际传入的
x_image
的形状。在注意,
x_image
的静态形状是(?, ?, ?, ?, 1)
。在全卷积网络
最后也是最重要的部分是使整个网络卷积,这也包括最后的密集层。稠密层必须静态地定义其维数,从而迫使整个神经网络固定输入图像的维数。在
幸运的是,al的Springenberg在"Striving for Simplicity: The All Convolutional Net"论文中描述了一种用CONV层代替FC层的方法。我将使用3
1x1x1
过滤器的卷积(另请参见this question):如果我们确保
final
与DeConnv1
(和其他人)具有相同的维度,那么y
将成为我们想要的形状:[-1, N * M * P, 3]
。在把它们结合在一起
你的网络很大,但所有的反褶积基本上都遵循相同的模式,所以我将我的概念证明代码简化为一个反褶积。我们的目标只是展示什么样的网络能够处理任意大小的图像。最后一点:图像尺寸可以在不同批次之间变化,但在一个批次中,它们必须相同。在
完整代码:
理论上,这是可能的。您需要将输入和标签图像占位符的图像大小设置为
none
,并让图形从输入数据动态推断图像大小。在但是,在定义图形时必须小心。需要使用
tf.shape
而不是tf.get_shape()
。前者仅在session.run
时动态推断形状,后者在定义图形时才能得到形状。但是,当input size设置为none
时,后者不会得到真正的整形(可能只返回None)。在为了使事情复杂化,如果使用},有时这些高级函数不喜欢
tf.layers.conv2d
或{tf.shape
,因为它们似乎认为形状信息在图形构造过程中是可用的。在我希望我有更好的工作例子来说明以上几点。我将把这个答案作为占位符,如果有机会,我会回来添加更多内容。在
相关问题 更多 >
编程相关推荐