Python Conv2D使用公式转换输出形状

Python Conv2D使用公式转换输出形状,python,tensorflow,convolutional-neural-network,Python,Tensorflow,Convolutional Neural Network,我使用如下所示的转置层获得[-1256256,3]作为输出形状。我打印输出形状。我的问题是关于高度和宽度的,两者都是256。通道似乎是我代码中最后一个转置层的过滤器数量 我相当简单地假设公式是这样的。我读了其他的帖子 H = (H1 - 1)*stride + HF - 2*padding 但当我计算时,我似乎没有得到那个输出。我想我可能错过了填充计算 'SAME'添加了多少填充 我的密码是这个 linear=tf.layers.density(z,512*8*8) 线性=tf.contrib

我使用如下所示的转置层获得
[-1256256,3]
作为输出形状。我打印输出形状。我的问题是关于高度和宽度的,两者都是
256
。通道似乎是我代码中最后一个转置层的过滤器数量

我相当简单地假设公式是这样的。我读了其他的帖子

H = (H1 - 1)*stride + HF - 2*padding
但当我计算时,我似乎没有得到那个输出。我想我可能错过了填充计算
'SAME'
添加了多少填充

我的密码是这个

linear=tf.layers.density(z,512*8*8)
线性=tf.contrib.layers.batch_范数(线性,is_训练=is_训练,衰减=0.88)
conv=tf.重塑(线性,(-1128128,1))
out=tf.layers.conv2d_转置(conv,64,内核大小=4,步幅=2,padding='SAME')
out=tf.layers.dropout(out,keep_prob)
out=tf.contrib.layers.batch\u norm(out,is\u training=is\u training,decage=0.88)
out=tf.nn.leaky_relu(out)
out=tf.layers.conv2d_转置(out,128,内核大小=4,步幅=1,padding='SAME')
out=tf.layers.dropout(out,keep_prob)
out=tf.contrib.layers.batch\u norm(out,is\u training=is\u training,decage=0.88)
out=tf.layers.conv2d_转置(out,3,内核大小=4,步幅=1,padding='SAME')
打印(out.get_shape())

关于
'SAME'
填充,文档提供了一些详细的解释(在这些说明中有更多详细信息)。特别是,当使用
'SAME'
填充时,输出形状的定义如下:

在这种情况下,输出形状仅取决于输入形状和步幅。填充大小从那里计算出来,以满足此形状要求(而使用
'VALID'
填充时,输出形状取决于填充大小)

现在是转置卷积。。。由于此操作是正常卷积(其梯度)的后向对应,这意味着正常卷积的输出形状对应于其对应转置操作的输入形状。换句话说,
tf.layers.conv2d()
的输出形状除以步幅,输出形状 将
tf.layers.conv2d\u transpose()

# for `tf.layers.conv2d_transpose()` with `SAME` padding:
out_height = in_height * strides[1]
out_width  = in_width * strides[2]
但是,再次计算填充大小以获得此输出形状,而不是反过来(对于
相同的
填充)。由于这些值之间的正常关系(即您发现的关系)是:

重新排列我们得到的方程式

padding_height = [strides[1] * (in_height - 1) + kernel_size[0] - out_height] / 2
padding_width  = [[strides[2] * (in_width - 1) + kernel_size[1] - out_width] / 2
注意:如果例如
2*padding\u height
为奇数,则
padding\u height\u top=地板(padding\u height)
;和
padding\u height\u bottom=ceil(padding\u height)
(分别为
padding\u width
padding\u width\u left
padding\u width\u right)

用表达式替换
out\u height
out\u width
,并使用您的值(对于第一次转置卷积):


因此,在数据的每一侧都添加了
1
的填充,以便获得输出dim
out\u dim=in\u dim*stride=strips*(in\u dim-1)+kernel\u size-2*填充=256

我根据@Aldream的答案为自己绘制了一张图表。也许有助于形象化。希望我没弄错。但我必须研究如何以及在何处使用这种填充物来获得最终的形状


让我计算代码。至少有一条线误导了我。编辑了这个问题。我不知道它都在文档中。我试图进一步澄清我的答案。希望有帮助。跨步*(在尺寸-1)+内核大小-2*填充=256你能用值替换这个吗?我昨天去了fast,在
填充高度
填充宽度
的方程式中犯了一个错误,我的错。现在它被更正了,在您的案例中,finally
padding=1
。因此,我们正确地得到了
out\u dim=strips*(in\u dim-1)+kernel\u size-2*padding=2*(128-1)+4-2*1=256
。对于接下来的两个转置,这个形状(256)不会改变。你是说?
# for `tf.layers.conv2d_transpose()` with given padding:
out_height = strides[1] * (in_height - 1) + kernel_size[0] - 2 * padding_height
out_width  = strides[2] * (in_width - 1) + kernel_size[1] - 2 * padding_width
padding_height = [strides[1] * (in_height - 1) + kernel_size[0] - out_height] / 2
padding_width  = [[strides[2] * (in_width - 1) + kernel_size[1] - out_width] / 2
padding = [2 * (128 - 1) + 4 - (128 * 2)] / 2 = 1