Conv2d和Conv3d完全相同,输入由(N, C , H, W)变为(N, C, D, H, W)。
因此,本文只探讨PyTorch中的torch.nn.Conv2d
类。由于该类几乎能够实现当下所有对卷积的特殊操作,所以我们只需要完全弄清楚该类的所有参数就可以搞懂当下比较新的算法。本文的侧重点在于dilation和groups这两参数。
本文主要参考PyTorch的Conv2d官方文档。
class Conv2d(_ConvNd):
def __init__(
self,
in_channels: int,
out_channels: int,
kernel_size: _size_2_t,
stride: _size_2_t = 1,
padding: Union[str, _size_2_t] = 0,
dilation: _size_2_t = 1,
groups: int = 1,
bias: bool = True,
padding_mode: str = 'zeros', # TODO: refine this type
device=None,
dtype=None
) -> None:
以上代码是复制的源代码,只包括初始化参数部分。下面进行参数的讲解。
- in_channels:输入通道数,由输入图像通道数决定。
- out_channels:输出通道数,由卷积核数量决定,也代表最终输出通道数。
- kernel_size:卷积核大小 (f),控制输出大小。
- stride:步长 (s),也控制输出大小。
- padding:记为 p,除了可以使用数字表示pad多少外,还可以使用str:“valid”、“same”。valid代表padding为0,same代表输出大小和输入大小(n)相同。
注意:kernel_size、stride和padding这三者可以是一个int数字,表示宽和高使用相同的值。也可以是一个元组,分别代表高和宽方向。通常都是使用相同的值。
以上五个参数是最基础的部分,本文并没有细讲。通过以下公式计算输出大小:( n+2p-f ) / s + 1,n为输入大小。
虽然下面两个参数不常用,但是会具体讲解,这可以帮助我们了解更多思想和算法。 - dilation:同上面几个参数一样既可以是 int 也可以是 tuple 。顾名思义,使用了这个参数代表膨胀卷积(dilation conv),或者称为空洞卷积(Atrous conv)。简单来说,就是膨胀原有卷积核,让卷积核变大,增加感受野大小。具体实现使用留出空洞的方法让卷积变大。看图(dilation = 2):
- 注:上图来源于博主:行者无疆兮,本部分也参考了他的博客。
上图中的 dilatinotallow=2 ,对卷积进行膨胀操作后得到卷积大小:(f-1)(d-1)+f = (f-1)d+1 = (3-1)2+1 = 5,使用了dilation后卷积输出大小为:[ n+2p - ( f -1)d -1 ] / s + 1 - groups:就是分组的意思,按channel方向进行分组,所以in_channel和out_channel必须能够整除groups。下面看一个图就可以理解了。
- 解释一下,图中左边部分 groups=1,右边部分 groups=3,两边最终的结果大小和channel都相同。图中的小写 i 为in_channel数,小写 o 为out_channel数,都可以被整除。区别在于,左边中,每个filter会处理所以通道,而右边被分成三个部分,所以每个部分对应不同的filter,每个部分是独立的。
特别的,当 groups=in_channel 时,每一个channel都有自己的 filters ,数量为:out_channel / in_channel。 - bias:True or False
- padding_mode:对图像进行边缘填充方式,默认为 0 填充(‘zeros’),还有: ‘reflect’, ‘replicate’ or ‘circular’ 。