PyTorch Conv2d是否无padding='same'选项?如何选择填充侧?
关于PyTorch卷积填充的两个疑问解答
1. PyTorch的Conv2d真的没有padding='same'选项吗?
其实在PyTorch 1.10及以上版本中,nn.Conv2d已经支持padding='same'这个参数了!不过有个小细节需要注意:当你使用非对称卷积核或者步长不等于1时,padding='same'会让输出的空间维度尽可能和输入一致——如果输入维度无法被步长整除,输出维度会向下取整。
如果你的PyTorch版本低于1.10,那确实没有这个快捷选项,就需要像你现在这样手动计算填充量,用ZeroPad2d来实现。
2. 如何确定填充的侧?
首先得明确两个关键点:
填充量的计算逻辑:卷积输出维度的计算公式是:
output_size = floor((input_size + total_padding - kernel_size) / stride) + 1你需要保持高度维度为100,输入高度100,卷积核高度4,步长1,代入公式可得:
100 = floor((100 + total_pad_h - 4)/1) + 1 → total_pad_h = 3也就是说高度方向总共需要填充3个单位,宽度方向因为你的卷积核是1、步长1,不需要填充,所以total_pad_w=0。
ZeroPad2d的参数顺序:
nn.ZeroPad2d的参数是(left, right, top, bottom),也就是先指定宽度方向的左右填充量,再指定高度方向的上下填充量。你选择了
(0, 0, 2, 1),也就是高度方向顶部填2、底部填1,总填充量3,这完全没问题。至于为什么选这个分配方式,主要看你的业务逻辑:比如处理金融时间序列时,如果你觉得应该在**序列的头部(过去方向)填充虚拟数据,就多填top;如果想在尾部(未来方向)**填充,就多填bottom。PyTorch的padding='same'默认会把奇数的填充量优先分配给底部和右侧,你可以根据自己的需求调整。
补充验证你的代码
你的代码已经完美实现了保持高度维度不变的需求:
import torch import torch.nn as nn conv = nn.Conv2d(1, 1, kernel_size=(4, 1)) pad = nn.ZeroPad2d((0, 0, 2, 1)) # 宽度无填充,高度顶部填2、底部填1 x = torch.randint(low=0, high=9, size=(100, 40)) x = x.unsqueeze(0).unsqueeze(0) # 转换成(批量, 通道, 高度, 宽度)的格式 y = pad(x) print(conv(x.float()).shape) # 未填充时输出(1,1,97,40) print(conv(y.float()).shape) # 填充后输出(1,1,100,40),符合预期
内容的提问来源于stack exchange,提问作者Sean
相关产品推荐
相关产品推荐

