【深度学习】Global Pooling,Depth-wise Convolution, Concatenate

      最近在读BiSeNet的两篇论文,遇到了三个以前没有接触过的操作,本文来就这三个操作进行简单的讲解以及Pytorch代码实现的思路。

1.Global Pooling

      Global Pooling,中文是全局池化,其实是一种比一般池化还要简单的池化操作。在一般的池化中,我们需要用一个类似卷积核一样的东西,来规定步长从而进行取最大值或者平均值的操作,也就是我们常说的最大池化或者平均池化,这种操作通常会改变特征图的尺寸,而改变后的尺寸计算与卷积的计算完全一致。而Global Pooling就十分简单了,它直接就对整个特征图进行池化操作,也就是说它的核的尺寸就是特征图的的尺寸,最后对整张特征图的每个通道都只得到一个值,所以一个HxWxC的特征图经过一次全局池化它的尺寸就变成了1x1xC 。

      我们用一个2x2x2的特征图来举例说明,它的全局平均池化过程如下图所示:
在这里插入图片描述
      在pytorch中,我们可以直接使用torch.mean进行全局池化,例如:

import torch
x = torch.randn(1, 3, 400, 400)
print('x_size:', x.size())
globalpool = torch.mean(x, dim=(2, 3), keepdim=True)
print('gp_size:', globalpool.size())

      mean函数中的dim参数表示对那几个维度进行求全局平均的操作,这里我们希望对x的高和宽维度上进行平均,所以是2和3(从0开始算)。keepdim表示求平均之后是否要保持原有的维度。原有的x有4个维度,我们让它keepdim,最后得到的输出还会是4个维度,如果不keepdim,可能就会变成两个维度。

      上述代码的输出结果如下:

x_size: torch.Size([1, 3, 400, 400])
gp_size: torch.Size([1, 3])

2.Depth-wise Convolution

      我们所进行的通常的卷积的卷积核,实际上是有通道数的。了解深度学习的小伙伴们都应该知道,我们在一个卷积层中,有几个卷积核就会得到几维的特征图,如果我们输入一个卷积层的特征图的尺寸为HxWxC,那么我们的卷积核的通道数也必须为C,进行的实际上是多维卷积。如果你还不了解卷积神经网络中的多维卷积,可以参考我的这篇博客【小知识】对于LeNet-5网络中卷积层的理解.

      而Depth-wise卷积却不要求卷积核的通道数必须为C,卷积核只有一个通道就可以了,那么我们需要C个这样的卷积核分别在特征图的每个通道上就行卷积,这样的卷积操作都是在二维平面上完成的,完全没有多维卷积的操作。

      比如我们有一个HxWxC的特征图,如果我们想经过一个3x3卷积操作得到的特征图的尺寸还是HxWxC,采用普通的卷积需要C个3x3xC的卷积核来实现,而采用Depth-wise卷积我们只需要C个3x3的卷积核就能实现。当然,他们得到的特征图是不同的,Depth-wise卷积可以很好地减少参数量,但是提取到的特征在有些时候可能并不是我们需要的特征。

      如果想要看图示理解的话,可以参看这篇博客Depthwise卷积与Pointwise卷积

      pytorch代码实现上实际上特别简单,只需要把普通的卷积层里的参数groups修改成与输入特征图的通道数相同即可,即把原来的通道进行分组,分成通道数那么多组就是在每一个通道上进行卷积。代码形式如下:

nn.Conv2d(inputchannel, outputchannel, kernel_size=3, stride=1,
			padding=1, groups=inputchannel, bias=False)

3.Concatenate

      在BiseNetV2中,有一种操作较concatenated,简单来说就是串联的意思,原文中的图如下:
在这里插入图片描述
      本来串联很好理解,但是这个图乍一看会让人有些不懂,为什么两个H/4xW/4xC串联起来得到的结果不是H/4xW/4x2C而还是H/4xW/4xC?仔细一看原来是因为中间还有一个卷积操作,串联的结果就是H/4xW/4x2C,只不过作者又使用了C个3x3x2C的卷积核,才把它变成了H/4xW/4xC。

      Concatenate好像经常被用在各种深度学习的网络中,主要作用就是进行特征的融合,融合的方法简单粗暴,就对得到的两个特征图进行拼接,在pytorch中直接采用cat函数就能实现,例如:

concatenate = torch.cat([left, right], dim=1)

      其中left和right就代表两个特征图,直接cat到了一起就得到了concatenate。

      如果想要对两个尺寸不相同(W和H不同)的特征图进行concatenate操作,则需要事先进行upsampling或者downsampling,将它们调整成相同的W和H,在进行cat操作就可以了。

猜你喜欢

转载自blog.csdn.net/weixin_43728604/article/details/109738675