为什么`tf.pad`填充参数需要额外的增量才能保证准确性?

时间:2019-02-12 15:07:09

标签: python tensorflow keras caffe

我正在尝试在Keras中实现对称填充层,就像Caffe实施该填充层一样,我遇到了一个奇怪的问题。

假设我们有一个带有1x1280x1280x3个通道的3图像,并且我们想对其进行卷积,以便它返回一个{{1} }频道。在Caffe中,我们可以在卷积层中直接设置1x320x320x96参数:

96

如果您尝试使用Caffe进行编译,则输出pad的形状确实为input: "image" input_shape { dim: 1 dim: 3 dim: 1280 dim: 1280 } layer { name: "conv1" type: "Convolution" bottom: "image" top: "conv1" param { lr_mult: 1 decay_mult: 1 } param { lr_mult: 2 decay_mult: 0 } convolution_param { num_output: 96 kernel_size: 11 pad: 5 # Padding parameter stride: 4 } } layer { name: "relu1" type: "ReLU" bottom: "conv1" top: "conv1" }


现在让我们使用conv11x320x320x96层对Keras进行相同的尝试:

tf.pad

问题

如果我们测量以上代码中定义的Lambda的形状,它将是from keras.layers import Input, Lambda import tensorflow as tf image = Input(shape=(1280, 1280, 3), dtype='float32', name='image') sym_pad = Lambda(lamda x: tf.pad(x, [[0, 0], [0, 5], [0, 5], [0, 0]])) # padding = 5 conv1 = Conv2D(filters=96, kernel_size=11, strides=(4, 4), activation=relu, padding='valid', # valid instead of 'same' name='conv1')(image) 而不是conv1

但是,如果我们增加1x319x319x96的填充,请使用1x320x320x96填充而不是2,如下所示:

7x7
当我们传递带有5x5而不是sym_pad = Lambda(lamda x: tf.pad(x, [[0, 0], [0, 5+2], [0, 5+2], [0, 0]])) # padding = 7 形状的conv1填充输入时,

1x320x320x96将具有期望的形状image注意,只有偶数形图像上的奇数填充会改变卷积的形状,这可能与步幅有关。

为什么会这样? Caffe是否将每个填充参数自动增加1x1287x1287x3?还是我做错了什么?

谢谢!

P.S 我知道Keras层中的1x1285x1285x3参数,但是我正在寻找对称填充而不是非对称填充。

2 个答案:

答案 0 :(得分:2)

如果您正在谈论对称填充,那么我假设您想在图像的左侧和右侧填充相同数量的像素(顶部和底部相同)。 tf.pad当前正在执行的操作是在右侧填充5个像素,在底部填充5个像素。因此,从理论上来说,您要在两边填充2.5像素。

输出形状如下:

floor((input_size-kernel_size+2*padding_size)/stride_size) + 1

因此,在您的情况下,填充2.5像素时会产生319的输出形状。 如果您在两侧都填充5个像素,则可以得到320的期望值。

答案 1 :(得分:2)

在您的示例中,将输入仅填充到底部和右侧。使用:

sym_pad = Lambda(lamda x: tf.pad(x, [[0, 0], [5, 5], [5, 5], [0, 0]]))

获得与Caffe相同的填充。