池化层/汇聚层以及L2池化

池化层/汇聚层

摘自《动手学深度学习》:

通常当我们处理图像时,我们希望逐渐降低隐藏表示的空间分辨率、聚集信息,这样随着我们在神经网络中层叠的上升,每个神经元对其敏感的感受野(输入)就越大。

而我们的机器学习任务通常会跟全局图像的问题有关(例如,“图像是否包含一只猫呢?”),所以我们最后一层的神经元应该对整个输入的全局敏感。通过逐渐聚合信息,生成越来越粗糙的映射,最终实现学习全局表示的目标,同时将卷积图层的所有优势保留在中间层。

汇聚(pooling)层,它具有双重目的:降低卷积层对位置的敏感性,同时降低对空间降采样表示的敏感性。

我也觉得翻译成汇聚层可能更好,但是已经改口改不过来了。下面的文字会出现汇聚与池化混用的情况。

卷积层与池化层

与卷积层类似,汇聚层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口(有时称为汇聚窗口)遍历的每个位置计算一个输出。 然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数。 相反,池运算是确定性的,我们通常计算汇聚窗口中所有元素的最大值或平均值。这些操作分别称为最大汇聚层(maximum pooling)和平均汇聚层(average pooling)。
在这里插入图片描述

在Resnet中,网络的开始有一个3x3大小,stride为2的最大池化层。在pytroch实现的resnet中也可以看到,其具有kernel_size, stride, padding等与卷积层一样的参数。而Resnet最后的平均池化,可以看作其核大小为7。
在这里插入图片描述
在这里插入图片描述

最大汇聚与平均汇聚

首先它们都具有汇聚的特点,那就是减少数据量。最大池化是一个窗口得到一个最大值,平均池化是一个窗口得到一个平均值,都是一个窗口得到一个值,多个汇聚成一个。具体的降采样效率,那就取决于窗口大小,步长等参数了。

最大汇聚

最大池化选择池化窗口中数值最大的元素,这意味着它优先保留局部区域中最显著的特征,忽略其他较小的值,保留图像中的关键信息,所以对与边缘、轮廓等高对比度的信息十分有效。并且池化后的特征对小幅度的平移、旋转等变化有较强的鲁棒性。

不过由于最大汇聚忽略了较小的值,可能会导致某些背景信息或对比度的特征丢失。而且,相对于平均池化,其只关心局部最大值,而丢失了更多的上下文信息。

平均汇聚

平均池化计算池化窗口内所有元素的平均值,考虑了池化窗口中所有像素的贡献,从而保留了局部区域的整体信息,所以其具有更强的平滑效果,并且能够保留更多的信息,比如背景信息。

因为由于它计算的是均值,可能会忽略局部的显著特征,尤其是对于高对比度的特征,平均池化会削弱其效果。

在Resnet中,网络的开始阶段使用了一个步长为2的最大池化层,主要目的是为了降低数据量,并且保留轮廓等显著特征。在网络的最后,特征送入全连接层之前,进行一次全局平均池化,一个7x7的特征,降低为1x1的特征,这里是为了给经过一层层抽象后的特征保留更多的信息。

其他池化方法

在一篇论文中,其使用L2池化去

For normalization and pooling we use Euclidean norm which is defined by F i = F i max ⁡ ( ∥ F i ∥ 2 , ϵ ) F_i=\frac{F_i}{\max \left(\left\|F_i\right\|_2, \epsilon\right)} Fi=max(Fi2,ϵ)Fi followed by a l 2 l_2 l2 pooling layer which has been used to demonstrate the behavior of complex cells in primary visual cortex. The l 2 l_2 l2 pooling layer defines by:
P ( x ) = g ∗ ( x ⊙ x ) P(x)=\sqrt{g *(x \odot x)} P(x)=g(xx)
where ⊙ \odot denotes point-wise product, and the blurring kernel g ( . ) g(.) g(.) is implemented via a Hamming window that approximately applies the Nyquist criterion.

归一化使用欧氏范数,接下来跟一个 l 2 l_2 l2池化,这种池化方式已经被用于展示初级视觉皮层中复杂细胞的行为。

相对与进行 l 2 l_2 l2池化,这里还加了个 g g g函数,叫做模糊核,使用应用了Nyquist准则的Hamming窗口实现。

一开始对与 l 2 l_2 l2池化层感觉十分疑惑,这是干什么的,还有这种池化吗?问了问GPT,它这样说:

L2池化(L2 pooling)是一种用于降采样特征图的池化技术,常用于卷积神经网络(CNN)中。与更常见的最大池化(Max Pooling)和平均池化(Average Pooling)不同,L2池化通过计算池化窗口内所有数值的L2范数(即欧几里得范数)来进行特征聚合。

或许它叫L2汇聚就容易一眼看出来它的意义了。将一个窗口汇聚成最大值,汇聚成平均值,汇聚成L2范数,都是汇聚,都是池化。优点就是它比最大池化和平均池化对噪声更加鲁棒,在处理平滑过渡或者具有复杂特征的图像时表现得更好,可以保持更多的特征信息。

至于加了一个模糊核,是为了保留更多的信息,让数据处理更加平滑。

实现:

class L2pooling(nn.Module):
    def __init__(self, filter_size=5, stride=1, channels=None, pad_off=0):
       super(L2pooling, self).__init__()
       self.padding = (filter_size - 2)//2
       self.stride = stride
       self.channels = channels
       a = np.hanning(filter_size)[1:-1]            # filter_size为5时,a的长度是3,一个numpy的1维ndarray
       g = torch.Tensor(a[:, None]*a[None, :])      # 3*1和1*3的矩阵相乘,得到3*3的矩阵
       g = g/torch.sum(g)                           # 归一化
       self.register_buffer('filter', g[None, None, :, :].repeat((self.channels, 1, 1, 1)))  # shape: [channels, 1, size, size]
       # register_buffer是 PyTorch 用来注册一个不会被视为模型参数(不会更新)但需要存储的变量的方法。

    def forward(self, input):     # input's shape: [batch_size, in_channels, height, width]
       input = input**2
       out = F.conv2d(input, self.filter, stride=self.stride, padding=self.padding, groups=input.shape[1])
       return (out+1e-12).sqrt()

conv2d参数中,第二个位置的形状为 ( o u t p u t _ c h a n n e l s , i n _ c h a n n e l s g r o u p s , h e i g h t , w i d t h ) (output\_channels,\frac{in\_channels}{groups}, height, width) (output_channels,groupsin_channels,height,width),这里用了分组卷积,分的组数等于输入通道数,也就是一个通道一组,每个通道使用各自的filter进行卷积。


# 我们平时会这样使用一个卷积层,并且都是用的groups=1,没有将输入按照通道进行分组。进行分组的话就是在每组上分别进行卷积,最后连接起来。
class Net:
    def __init__(self):
		self.conv2d_1 = nn.Conv2d(128, 256, 3, 2, 1)
        
    def forward(self, input):
        out = self.conv2d_1(input)
        return out
    
# 当我们定义这样一个网络,并输入一个shape为 (128, 56, 56)的张量
# 前向传播后变为(256, 28, 28)

# 使用torch.nn.functional去实现,这样方便自己去设置卷积核
input = torch.rand((128, 56, 56))
filter = torch.rand((256, 128, 3, 3))    # 也就是准备了256个128x3x3的卷积核
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值