为什么`tf.pad`填充参数需要额外的增量来提高准确性?

问题描述 投票:1回答:2

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

假设我们有一个1x1280x1280x3图像和3通道,我们想对它进行卷积,以便它返回一个形状为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"
}

如果你试图用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 pad而不是5x5,如下所示:

sym_pad = Lambda(lamda x: tf.pad(x, [[0, 0], [0, 5+2], [0, 5+2], [0, 0]]))  # padding = 7

当我们通过带有conv1而不是1x320x320x96image的填充输入时,1x1287x1287x3将具有所需的1x1285x1285x3形状(注意,偶数形状图像上的奇数填充改变了卷积的形状,这可能与步幅有关)。

为什么会这样? Caffe会自动通过2递增每个填充参数吗?或者我做错了什么?

谢谢!

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

python tensorflow keras caffe
2个回答
2
投票

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

输出形状由下式给出:

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

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


2
投票

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

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

得到像Caffe一样的填充物。

© www.soinside.com 2019 - 2024. All rights reserved.