为什么 `tf.pad` 填充参数需要额外增加以确保准确性?

Why do `tf.pad` padding arguments need additional incrementation for accuracy?

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

假设我们有一个具有 3 个通道的 1x1280x1280x3 图像,我们想对其执行卷积,使其 returns 成为一个形状为 1x320x320x9696 个频道。在 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"
}

如果你尝试用 Caffe 编译它,conv1 的输出形状确实是 1x320x320x96


现在让我们使用 tf.padLambda 层在 Keras 上尝试同样的事情:

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
当我们传递形状为 1x1287x1287x3 而不是 1x1285x1285x3 的填充输入 image 时,

conv1 将具有所需的形状 1x320x320x96注意偶数形状图像上只有奇数填充会改变卷积的形状,这可能与步长有关)。

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

谢谢!

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

如果您谈论的是对称填充,我假设您想要在图像的左侧和右侧填充相同数量的像素(顶部和底部相同)。您当前使用 tf.pad 所做的是向右填充 5 个像素,向底部填充 5 个像素。因此,您要向两侧填充 2.5 像素(理论上)。

输出形状由下式给出:

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

所以在你的情况下,当填充 2.5 像素时,这会产生 319 的输出形状。 如果你向两边填充 5 个像素,你会得到你所期望的,即 320.

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

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

获得与 Caffe 中相同的填充。