Tensorflow 和 Pytorch 中 Conv2d Padding的区别
Pytorch中Conv2d的Padding

可以是整数,二元组,字符串三种形式。
- 整数(int)。如果输入的padding为整数则代表在 上,下,左,右 四个方向都充填一样数量的0或者由padding_mode 确定的padding类型。
- 二元组(tuple)。如果输入的padding 为二元组(padding[0],padding[1]),则padding[0]代表上下两个方向的padding大小,padding[1]则代表左右两个方向的padding大小。
- 字符串(str)。字符串模式可选参数为
valid和same,valid模式表示不充填,same模式表示输入与输出的形状大小保持一致(但是仅仅适用于stride=1的情况!!!)
可以看出pytorch都是对称的进行padding,要么是四个方向都是一样的padding,要么上下或左右做一样的padding。
最后的输出形状计算公式如下:
Hout=⌊Hin+2×padding[0]−dilation[0]×(kernel_size[0]−1)−1stride[0]+1⌋
H_{out} = \left\lfloor\frac{H_{in} + 2 \times \text{padding}[0] - \text{dilation}[0]
\times (\text{kernel\_size}[0] - 1) - 1}{\text{stride}[0]} + 1\right\rfloor
Hout=⌊stride[0]Hin+2×padding[0]−dilation[0]×(kernel_size[0]−1)−1+1⌋
Wout=⌊Win+2×padding[1]−dilation[1]×(kernel_size[1]−1)−1stride[1]+1⌋ W_{out} = \left\lfloor\frac{W_{in} + 2 \times \text{padding}[1] - \text{dilation}[1] \times (\text{kernel\_size}[1] - 1) - 1}{\text{stride}[1]} + 1\right\rfloor Wout=⌊stride[1]Win+2×padding[1]−dilation[1]×(kernel_size[1]−1)−1+1⌋
Tensorflow 中 Conv2d的padding

可以是 字符串和列表两种形式:
- 字符串。 字符串是可选
SAME和VALID。SAME模式下,根据以下公式计算各方向的padding:
PadH=max(filterH−(InH % strideH),0) Pad_{H} = max(filter_H - (In_H \space \% \space stride_H),0) PadH=max(filterH−(InH % strideH),0)
PadW=max(filterW−(InW % strideW),0) Pad_{W} = max(filter_W - (In_W \space \% \space stride_W),0) PadW=max(filterW−(InW % strideW),0)
Padtop=⌊PadH2⌋ Pad_{top} =\left\lfloor \frac{Pad_{H}}{2} \right\rfloor Padtop=⌊2PadH⌋
Padbottom=PadH−Padtop Pad_{bottom} = Pad_{H} - Pad_{top} Padbottom=PadH−Padtop
Padleft=⌊PadW2⌋ Pad_{left} = \left\lfloor \frac{Pad_{W}}{2} \right\rfloor Padleft=⌊2PadW⌋
Padright=PadW−Padleft Pad_{right} = Pad_{W} - Pad_{left} Padright=PadW−Padleft
不同于pytorch,tensorflow的SAME模式适用于任何的Stride时的padding,输出的形状为:
OutH=InHstride
Out_{H} = \frac{In_{H}}{stride}
OutH=strideInH
OutW=InWstride Out_{W} = \frac{In_{W}}{stride} OutW=strideInW
可以看出,tensorflow的padding不要求是对称的,上下左右的padding大小都可以不一样,而且优先进行右边和下边的padding(因为SAME模式设计的初衷就是为了应对输出形状无法整除卷积核大小,而导致的最右边或最下边无法卷积的情况),当你不关心padding的方向和大小,只关心输出的形状是不是原来形状的整数倍时,就可以无脑使用SAMEpadding 模式,tensorflow会自动帮你计算好要padding的大小。
VALID模式下,与pytorch一样,直接不padding 。当输入形状不能整除卷积核大小,滑动窗口滑到最右边发现无法满足卷积条件时,多出来的那部分直接会被舍弃掉,输出的形状为:
OutH=InH−filterH+1strideH
Out_{H} = \frac{In_H - filter_H + 1}{stride_{H}}
OutH=strideHInH−filterH+1
OutW=InW−filterW+1strideW Out_{W} = \frac{In_W - filter_W + 1}{stride_{W}} OutW=strideWInW−filterW+1
- 列表(list)。Tensor格式为默认的**“NHWC”** 时, padding list的格式为 [[0,0],[pad_top,pad_bottom],[pad_left,pad_right],[0,0]];采用的**“NCHW”**格式存储的Tensor时,padding list 的格式为 [[0,0],[0,0],[pad_top,pad_bottom],[pad_left,pad_right]]。输出的形状为:
OutH=InH+padtop+padbottom−dilationH×(filterH−1)−1strideH Out_{H} = \frac{In_{H} + \text{pad}_{top}+\text{pad}_{bottom} - \text{dilation}_{H} \times (\text{filter}_{H}- 1) - 1}{\text{stride}_{H}} OutH=strideHInH+padtop+padbottom−dilationH×(filterH−1)−1
OutW=InW+padright+padleft−dilationW×(filterW−1)−1strideW Out_{W} = \frac{In_{W} + \text{pad}_{right}+\text{pad}_{left} - \text{dilation}_{W} \times (\text{filter}_{W}- 1) - 1}{\text{stride}_{W}} OutW=strideWInW+padright+padleft−dilationW×(filterW−1)−1
注意: Tensorflow 和 Pytorch 中Conv2D 对输出的形状大小的小数部分处理不一样。Pytorch中都是做截断处理,或者说向下取整,例如 输出若为 117.5 则直接取 117;而Tensorflow中对小数的处理采用的则是向上取整,输出若为117.5,则取128。
参考
https://www.tensorflow.org/api_docs/python/tf/nn#notes_on_padding_2
https://www.tensorflow.org/api_docs/python/tf/nn/conv2d
https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html
本文详细比较了Tensorflow和Pytorch中Conv2d层的Padding实现方式。Pytorch的Padding支持整数、二元组和字符串模式,Tensorflow则接受字符串和列表,其SAME模式在任意Stride下都能保持输出形状。两者的Padding计算和输出形状处理有所不同,尤其在边界处理和舍入方式上有明显差异。对于关注输出形状的开发者,Tensorflow的SAME模式更为便捷。
4551

被折叠的 条评论
为什么被折叠?



