tensorflow Conv2D 中的 padding='same' 到底是啥意思?是最小填充还是 input_shape == output_shape
Posted
技术标签:
【中文标题】tensorflow Conv2D 中的 padding=\'same\' 到底是啥意思?是最小填充还是 input_shape == output_shape【英文标题】:What does padding='same' exactly mean in tensorflow Conv2D? Is it minimum padding or input_shape == output_shapetensorflow Conv2D 中的 padding='same' 到底是什么意思?是最小填充还是 input_shape == output_shape 【发布时间】:2021-09-03 04:59:27 【问题描述】:TL;DR:如何修改下面给出的代码以合并padding = 'same'
方法?
我试图使用numpy
构建自己的CNN
,但由于padding = 'same'
的两个答案而感到困惑。
This Answer says那个
Keras 中的 padding='Same' 表示当输入大小和内核大小不完全匹配时,根据需要添加填充以弥补重叠
所以据此,same
表示每个方向所需的最小填充。如果是这样的话,这不应该是双方平等的吗?或者,如果 minimum 所需的填充是 2,那么这不应该是填充均匀分布在所有 4 个边上的有效候选者。如果所需的填充只有 3 怎么办?然后会发生什么?
另外,困扰我的是the official documentation of tensorflow 他们说:
“相同”导致在输入的左/右或上/下均匀填充零,以使输出具有与输入相同的高度/宽度尺寸。
那么正确答案是什么?
这是我为填充编写的代码
def add_padding(X:np.ndarray, pad_size:Union[int,list,tuple], pad_val:int=0)->np.ndarray:
'''
Pad the input image array equally from all sides
args:
x: Input Image should be in the form of [Batch, Width, Height, Channels]
pad_size: How much padding should be done. If int, equal padding will done. Else specify how much to pad each side (height_pad,width_pad) OR (y_pad, x_pad)
pad_val: What should be the value to be padded. Usually it os 0 padding
return:
Padded Numpy array Image
'''
assert (len(X.shape) == 4), "Input image should be form of [Batch, Width, Height, Channels]"
if isinstance(pad_size,int):
y_pad = x_pad = pad_size
else:
y_pad = pad_size[0]
x_pad = pad_size[1]
pad_width = ((0,0), (y_pad,y_pad), (x_pad,x_pad), (0,0)) # Do not pad first and last axis. Pad Width(2nd), Height(3rd) axis with pad_size
return np.pad(X, pad_width = pad_width, mode = 'constant', constant_values = (pad_val,pad_val))
# Another part of my Layer
# New Height/Width is dependent on the old height/ width, stride, filter size, and amount of padding
h_new = int((h_old + (2 * padding_size) - filter_size) / self.stride) + 1
w_new = int((w_old + (2 * padding_size) - filter_size) / self.stride) + 1
Full Code for this layer is presented here
【问题讨论】:
其实两者都是真的。padding=same
指定填充,如果步幅为 1,则输出形状等于输入形状。但如果您指定步幅其他值,则会得到不同的结果。
不知道是什么问题。文档非常清楚:用零填充,以便输出与输入具有相同的大小。不管你垫多少,“最低限度”都是多余的。如果你填充更多,你只是在浪费空间。输出大小已给出。
【参考方案1】:
根据这个SO answer,名称'SAME'
padding 只是来自当stride 等于1 时,输出空间形状与输入空间形状相同的属性。
但是,当步幅不等于 1 时,情况并非如此。输出空间形状由以下公式确定。
对于所有情况,“SAME”的定义意味着以张量流方式应用填充,这样
对于每个空间维度 i, output_spatial_shape[i] = ceil(input_spatial_shape[i] / strides[i])
那么 tensorflow 应用填充的方式是什么?
首先,每个空间维度所需的填充由以下算法确定。
#e.g. for 2D image, num_spatial_dim=2
def get_padding_needed(input_spatial_shape,filter_shape,strides):
num_spatial_dim=len(input_spatial_shape)
padding_needed=[0]*num_spatial_dim
for i in range(num_spatial_dim):
if input_spatial_shape[i] % strides[i] == 0:
padding_needed[i] = max(filter_shape[i]-strides[i],0)
else:
padding_needed[i] = max(filter_shape[i]-(input_spatial_shape[i]%strides[i]),0)
return padding_needed
#example
print(get_padding_needed(input_spatial_shape=[2000,125],filter_shape=[8,4],strides=[4,1]))
#[4,3]
如您所见,第一个空间维度所需的填充是偶数 4。这很简单,只需在第一个空间维度的每一端填充 2 个零即可。
第二,第二维所需的填充是奇数。然后,tensorflow 将在起始端填充更少的零。
换句话说,如果维度是高度并且需要的填充是 3,它将在顶部填充 1 个零,在底部填充 2 个零。如果维度是宽度,并且需要的填充是5,它将在左侧填充2个零,在右侧填充3个零,等等。
参考资料:
-
https://www.tensorflow.org/api_docs/python/tf/nn/convolution
https://mmuratarat.github.io/2019-01-17/implementing-padding-schemes-of-tensorflow-in-python
【讨论】:
参考#1,目前有更多细节tensorflow.org/api_docs/python/tf/nn#notes_on_padding_2以上是关于tensorflow Conv2D 中的 padding='same' 到底是啥意思?是最小填充还是 input_shape == output_shape的主要内容,如果未能解决你的问题,请参考以下文章
Tensorflow Profile 为 Conv2D 输出 2 FLOPS 而不是 1
tensorflow Conv2D 中的 padding='same' 到底是啥意思?是最小填充还是 input_shape == output_shape