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

T. *_*awa 8 python conv-neural-network tensorflow

我读了张量流的 tf.nn.max_pool 中的“SAME”和“VALID”填充有什么区别?但这对我的实验来说不是真的。

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)
Run Code Online (Sandbox Code Playgroud)

产生

(1, 64, 64, 3)
(1, 32, 32, 6)
Run Code Online (Sandbox Code Playgroud)

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

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

BiB*_*iBi 9

Keras 使用 TensorFlow 实现填充。此处此处的文档中提供了所有详细信息。

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

out_height = ceil(float(in_height) / float(strides[1]))
out_width  = ceil(float(in_width) / float(strides[2]))
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

最后,顶部、底部、左侧和右侧的填充是:

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
Run Code Online (Sandbox Code Playgroud)

请注意,除以 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]))
Run Code Online (Sandbox Code Playgroud)

并且不使用填充。