padding='same' 和 strides > 1 的 tf.keras.layers.Conv2D 表现如何?

Posted

技术标签:

【中文标题】padding=\'same\' 和 strides > 1 的 tf.keras.layers.Conv2D 表现如何?【英文标题】:How does tf.keras.layers.Conv2D with padding='same' and strides > 1 behave?padding='same' 和 strides > 1 的 tf.keras.layers.Conv2D 表现如何? 【发布时间】:2019-05-18 01:46:41 【问题描述】:

我阅读了What is the difference between 'SAME' and 'VALID' padding in tf.nn.max_pool of tensorflow?,但这不适用于我的实验。

import tensorflow as tf

inputs = tf.random_normal([1, 64, 64, 3])
print(inputs.shape)
conv = tf.keras.layers.Conv2D(6, 4, strides=2, padding='same')
outputs = conv(inputs)
print(outputs.shape)

生产

(1, 64, 64, 3)
(1, 32, 32, 6)

。然而,按照上面的链接会产生(1, 31, 31, 6),因为没有任何超出过滤器范围的额外值没有任何填充。

tf.keras.layers.Conv2D 与 padding='same' 和 strides > 1 的行为如何? 我想知道确切的答案及其证据。

【问题讨论】:

【参考方案1】:

Keras 使用 TensorFlow 实现填充。所有详细信息都可在文档here

中找到

首先,考虑“SAME”填充方案。的详细解释 其背后的原因在these notes 中给出。在这里,我们总结 这种填充方案的机制。使用“SAME”时,输出 高度和宽度计算为:

out_height = ceil(float(in_height) / float(strides[1]))
out_width  = ceil(float(in_width) / float(strides[2]))

沿高度和宽度应用的总填充计算如下:

if (in_height % strides[1] == 0):
  pad_along_height = max(filter_height - strides[1], 0)
else:
  pad_along_height = max(filter_height - (in_height % strides[1]), 0)
if (in_width % strides[2] == 0):
  pad_along_width = max(filter_width - strides[2], 0)
else:
  pad_along_width = max(filter_width - (in_width % strides[2]), 0)

最后,上、下、左、右的内边距分别是:

pad_top = pad_along_height // 2
pad_bottom = pad_along_height - pad_top
pad_left = pad_along_width // 2
pad_right = pad_along_width - pad_left

请注意,除以 2 意味着在某些情况下, 两侧的填充(顶部与底部,右侧与左侧)相差 1。 在这种情况下,底部和右侧总是得到一个额外的 填充像素。例如pad_along_height为5时,我们填充2个像素 在顶部和底部 3 个像素。请注意,这是不同的 来自现有的库,例如 cuDNN 和 Caffe,它们明确地 指定填充像素的数量并始终填充相同数量的像素 两边的像素。

对于 'VALID' 方案,输出高度和宽度计算如下:

out_height = ceil(float(in_height - filter_height + 1) / float(strides[1]))
out_width  = ceil(float(in_width - filter_width + 1) / float(strides[2]))

并且没有使用填充。

【讨论】:

链接不再有效。请参阅tensorflow.org/versions/r1.12/api_guides/python/nn。【参考方案2】:

在 tensorflow 中,对于步幅 s 和输入大小 n,使用相同的填充:

⌈n/s⌉

或输入大小的上限除以步幅。

【讨论】:

以上是关于padding='same' 和 strides > 1 的 tf.keras.layers.Conv2D 表现如何?的主要内容,如果未能解决你的问题,请参考以下文章

自定义CNN实现图像分类

卷积神经网络padding和strides图示

卷积层里的填充Padding和步幅Stride 动手学深度学习v2 pytorch

深度学习:《PyTorch入门到项目实战》卷积神经网络:填充(padding)和步幅(stride)

卷积神经网络填充和步幅(padding-and-strides)

padding='same' 转换为 PyTorch padding=#