3 池化层
1.概述
池化层 (Pooling) : 主要对卷积层学习到的特征图进行下采样(SubSampling)处理,可以降低空间维度, 缩减模型大小,提高计算速度。
分类:
1.最大池化max pooling:从每个局部区域中选择最大值作为池化后的值,可以保留局部区域中最显著的特征,在提取图像中的纹理、形状等方面具有很好的效果。
2.平均池化 avgpooling:从每个局部区域中取平均值作为池化后的值,可以得到整体特征的平均值,在提取图像中的整体特征、减少噪声等方面具有较好的效果。
2.计算
3.步长Stride
4.边缘填充Padding
5.多通道池化计算
在处理多通道输入数据时,池化层对每个输入通道分别池化。
池化层的输出通道数=输入通道数
6.池化层的作用
优点:
1.降低特征图的尺寸,减少计算量,提升模型的运行效率
2.池化操作可以带来特征的平移、旋转等不变性,提高模型对输入数据的鲁棒性
3.池化层通常是非线性操作,可以增强网络的表达能力,进一步提升模型的性能
缺点:
会丢失一些信息
eg1
import torch
import torch.nn as nn
def test01():torch.random.manual_seed(1)#输入的特征图数据input=torch.randint(0,255,(1,64,224,224),dtype=torch.float32)print(input[0][0][:4,:5])#池化核pool=nn.MaxPool2d(kernel_size=2,#池化核大小stride=2,#步长return_indices=True,#返回索引)#对数据进行池化操作out,indices=pool(input)print(out.shape)print(indices)
if __name__=="__main__":test01()
4 整体结构
1.特征图变化
import torch
import torch.nn as nn
class numberModel(nn.Module):def __init__(self):super(numberModel,self).__init__()self.C1=nn.Sequential(nn.Conv2d(in_channels=1,out_channels=6,kernel_size=5,stride=1,padding=0),nn.ReLU())self.S2=nn.MaxPool2d(kernel_size=2,stride=2,padding=0)self.C3=nn.Sequential(nn.Conv2d(in_channels=6,out_channels=16,kernel_size=5,stride=1,padding=0),nn.ReLU())#self.S4=nn.MaxPool2d(kernel_size=2,stride=2,padding=0)#C5层self.C5=nn.Sequential(nn.Linear(in_features=16*5*5,out_features=120,bias=True),nn.ReLU())#F6层self.F6=nn.Sequential(nn.Linear(in_features=120,out_features=84,bias=True),nn.ReLU())#OUTPUTself.out=nn.Sequential(nn.Linear(in_features=84,out_features=10,bias=True),nn.Softmax(dim=1))
def forward(self,x): x=self.C1(x)x=self.S2(x)x=self.C3(x)x=self.S2(x)x=self.C5(x.view(-1,16*5*5))#-1是自动计算的数量Batchx=self.F6(x)out=self.out(x)return outpass
if __name__=="__main__":
#网络model=numberModel()#输入数据 NCHWtorch.random.manual_seed(1)input=torch.randn(1,1,32,32)#输出结构6@28*28output=model(input)print(output.shape)
5 卷积知识扩展
卷积实际上将原本图像中的某一特征进行提取
1.二维卷积
①.单通道版本
只有一个通道的卷积
②.多通道版本
彩色图像拥有RGB三层通道,在卷积时需要分别针对这三层进行卷积,最后将三个通道的卷积结果进行合并(就是在通道上进行通道融合,即元素相加),得到卷积结果。
2.三维卷积
二维卷积是在单通道的一帧图像上进行滑窗操作,输入是高度H宽度W的二维矩阵。
三维(涉及到视频上的连续帧或者立体图像中的不同切片)要引入深度通道,此时输入就变为高度H宽度W*深度C的三维矩阵。
三维卷积的卷积核会在三个方向上运动,因此需要有三个自由度,使得三维卷积能够有效地描述3D空间中的对象关系。
对3D对象的分割以及医学图像的重构等具有显著的优势。
3.反卷积
卷积是对输入图像及进行特征提取,这样会导致尺寸会越变越小,而反卷积是进行相反操作。
向上采样。反卷积相当于是将卷积核转换为稀疏矩阵后进行转置计算。也被称为转置卷积。
4.膨胀卷积(空洞卷积)
为扩大感受野,在卷积核俩面的元素之间插入空格“膨胀”内核,形成“空洞卷积”(或称膨胀卷积),并用膨胀率参数L
表示要扩大内核的范围,即在内核元素之间插入L-1
个空格。当L=1
时,则内核元素之间没有插入空格,变为标准卷积。
import torch
import torch.nn as nn
def test01():input=torch.randn(1,1,10,10)#创建一个卷积核conv=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=(5,5),stride=1,dilation=2#卷积核间距=dilation-1,膨胀率表示在卷积核内行和行列和列之间插入间距为(dilation-1),#那么此时的卷积核大小变为kernel_size+(kernel_size-(dilation-1))#输出的size为10-(5+(5-1))+1=2)#使用卷积核对数据进行卷积操作out=conv(input)print(out.shape)
if __name__=="__main__":test01()
5.可分离卷积
①.空间可分离卷积
将卷积核分解为两项独立的核分别进行操作。所以对3x3的卷积核,我们同样可以拆分成 3x1 和 1x3 的两个卷积核,对其进行卷积,且采用可分离卷积的计算量比标准卷积要少。
import torch
import torch.nn as nn
class normalModel(nn.Module):def __init__(self):super(normalModel,self).__init__()self.conv1=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=3,stride=1,padding=0,bias=False)
def forward(self,x):return self.conv1(x)class waveModel(nn.Module):def __init__(self):super(waveModel,self).__init__()self.conv1=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=(3,1),stride=1,padding=0,bias=False,groups=1)self.conv2=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=(1,3),stride=1,padding=0,bias=False,groups=1)def forward(self,x):x=self.conv1(x)out=self.conv2(x)return outif __name__=="__main__":model1=normalModel()for name,param in model1.named_parameters():print(name,param.size())print("-----------------")model2=waveModel()for name,param in model2.named_parameters():print(name,param.size())
②.深度可分离卷积
深度可分离卷积由两部组成:深度卷积核1x1卷积(升维和降维)
输入图的每一个通道,我们都使用了对应的卷积核进行卷积。 通道数量 = 卷积核个数,每个卷积核只有一个通道
完成卷积后,对输出内容进行1x1
的卷积
import torch
import torch.nn as nn
class normalModel(nn.Module):def __init__(self):super(normalModel,self).__init__()self.conv1=nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3,stride=1,padding=0,bias=False)
def forward(self,x):return self.conv1(x)pass
class deepwaveModel(nn.Module):def __init__(self):super(deepwaveModel,self).__init__()self.conv1=nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3,stride=1,padding=0,bias=False,groups=8#卷积核数量等于输入通道数)self.conv2=nn.Conv2d(in_channels=8,out_channels=8,kernel_size=1,stride=1,padding=0,bias=False)
def forward(self,x):x=self.conv1(x)x=self.conv2(x)return xif __name__=="__main__":model1=normalModel()#8*8*3*3=576for name,param in model1.named_parameters():print(name,param.size())print("-----------------")model2=deepwaveModel()#8*1*3*3+8*8*1*1=136for name,param in model2.named_parameters():print(name,param.size())
6.扁平卷积
扁平卷积是将标准卷积拆分成为3个1x1
的卷积核,然后再分别对输入层进行卷积计算。
-
标准卷积参数量XYC,计算量为MNCXY
-
拆分卷积参数量(X+Y+C),计算量为MN(C+X+Y)
7.分组卷积
为了解决GPU显存不足问题,将卷积分组放到两个GPU中并行执行。
在分组卷积中,卷积核被分成不同的组,每组负责对相应的输入层进行卷积计算,最后再进行合并。
import torch
import torch.nn as nn
class groupModel(nn.Module):def __init__(self):super(groupModel,self).__init__()self.conv1=nn.Conv2d(in_channels=16,out_channels=24,kernel_size=3,padding=0,groups=8,bias=False)passdef forward(self,x):out=self.conv1(x)return out
if __name__=="__main__":model1=groupModelfor name,param in model1.named_parameters():print(name,param.size())print("-----------------")
8.混洗分组卷积
分组卷积中最终结果会按照原先的顺序进行合并组合,阻碍了模型在训练时特征信息在通道间流动,削弱了特征表示。混洗分组卷积,主要是将分组卷积后的计算结果混合交叉在一起输出。
9.多通道卷积与偏置
卷积核卷完之后,偏置矩阵就会与输出特征矩阵相加,得到本次卷积的最终结果。
有两个结论:
-
输入特征的通道数决定了卷积核的通道数(卷积核通道个数=输入特征通道个数)。
-
卷积核的个数决定了输出特征矩阵的通道数与偏置矩阵的通道数(卷积核个数=输出特征通道数=偏置矩阵通道数)。
6 感受野
感受的视野范围
1.作用
如果堆叠3个3 x 3的卷积层,并且保持滑动窗口步长为1,其感受野就是7×7的了, 这跟一个使用7x7卷积核的结果是一样的
假设输入大小都是h × w × C,并且都使用C个卷积核(得到C个特征图),
$$
7*7卷积核所需参数:C×7×7×C=49C^2
$$
$$
3个3*3卷积核所需参数:3×C×3×3×C=27C^2
$$
堆叠小的卷积核所需的参数更少一些,并且卷积过程越多,特征提取也会越细致,加入的非线性变换也随着增多,还不会增大权重参数个数,这就是感受野的基本出发点,用小的卷积核来完成体特征提取操作。