视觉处理基础2
目录
1.池化层
1.1 概述
1.2 池化层计算
1.3 步长Stride
1.4 边缘填充Padding
1.5 多通道池化计算
1.6 池化层的作用
2. 卷积拓展
2.1 二维卷积
2.1.1 单通道版本
2.1.2 多通道版本
2.2 三维卷积
2.3 反卷积
2.4 空洞卷积(膨胀卷积)
2.5 可分离卷积
2.5.1 空间可分离卷积
2.5.2 深度可分离卷积
2.6 扁平卷积
2.7 分组卷积
2.8 混洗分组卷积
3.感受野
3.1 理解感受野
3.2 感受野的作用
1.池化层
1.1 概述
池化层 (Pooling) 降低维度, 缩减模型大小,提高计算速度. 即: 主要对卷积层学习到的特征图进行下采样(SubSampling)处理。
池化层主要有两种:
-
最大池化 max pooling
最大池化是从每个局部区域中选择最大值作为池化后的值,这样可以保留局部区域中最显著的特征。最大池化在提取图像中的纹理、形状等方面具有很好的效果。
-
平均池化 avgPooling
平均池化是将局部区域中的值取平均作为池化后的值,这样可以得到整体特征的平均值。平均池化在提取图像中的整体特征、减少噪声等方面具有较好的效果。
1.2 池化层计算
1.3 步长Stride
1.4 边缘填充Padding
1.5 多通道池化计算
在处理多通道输入数据时,池化层对每个输入通道分别池化,而不是像卷积层那样将各个通道的输入相加。这意味着池化层的输出和输入的通道数是相等。
1.6 池化层的作用
池化的优势:
-
通过降低特征图的尺寸,池化层能够减少计算量,从而提升模型的运行效率。
-
池化操作可以带来特征的平移、旋转等不变性,这有助于提高模型对输入数据的鲁棒性。
-
池化层通常是非线性操作,例如最大值池化,这样可以增强网络的表达能力,进一步提升模型的性能。
池化的缺点:
-
池化操作会丢失一些信息。
最大池化:
import torch.nn as nn
import torch torch.random.manual_seed(0)# 输入的特征图数据
input = torch.randint(0,225,(1,64,224,224),dtype=torch.float32)pool = nn.MaxPool2d(kernel_size =2,# 池化核大小stride = 2,# 步长return_indices = True,# 返回索引
)output,indices = pool(input)print(input[0] [0] [:10, :10])
print(output[0] [0] [:10, :10])
print(indices[0] [0] [:5, :5])
平均池化:
import torch.nn as nn
import torch torch.random.manual_seed(0)# 输入的特征图数据
input = torch.randint(0,225,(1,64,224,224),)pool = nn.AvgPool2d(kernel_size =2,# 池化核大小stride = 2,# 步长ceil_mode =False,
)output= pool(input)print(input[0] [0] [:10, :10])
print(output[0] [0] [:5, :5])
2. 卷积拓展
2.1 二维卷积
分单通道版本和多通道版本。
2.1.1 单通道版本
只有一个通道的卷积叫做二维卷积(单通道卷积版本)。
2.1.2 多通道版本
彩色图像拥有R、G、B这三层通道,因此我们在卷积时需要分别针对这三层进行卷积。最后将三个通道的卷积结果进行合并(元素相加),得到卷积结果。
2.2 三维卷积
二维卷积是在单通道的一帧图像上进行滑窗操作,输入是高度H宽度W的二维矩阵。
而如果涉及到视频上的连续帧或者立体图像中的不同切片,就需要引入深度通道,此时输入就变为高度H宽度W*深度C的三维矩阵。
不同于二维卷积核只在两个方向上运动,三维卷积的卷积核会在三个方向上运动,使得三维卷积能够有效地描述3D空间中的对象关系,它在一些应用中具有显著的优势,例如3D对象的分割以及医学图像的重构等。
2.3 反卷积
卷积是对输入图像及进行特征提取,这样会导致尺寸会越变越小,而反卷积是进行相反操作。并不会完全还原到跟输入图一样,只是保证了与输入图像尺寸一致,主要用于向上采样。从数学上看,反卷积相当于是将卷积核转换为稀疏矩阵后进行转置计算。也被称为转置卷积。
反卷积计算过程
如图,在2x2的输入图像上使用【步长1、边界全0填充】的3x3卷积核,进行转置卷积(反卷积)计算,向上采样后输出的图像大小为4x4。
2.4 空洞卷积(膨胀卷积)
为扩大感受野,在卷积核的元素之间插入空格“膨胀”内核,形成“空洞卷积”(或称膨胀卷积),并用膨胀率参数L
表示要扩大内核的范围,即在内核元素之间插入L-1
个空格。当L=1
时,则内核元素之间没有插入空格,变为标准卷积。图中是L=2
的空洞卷积。
import torch
import torch.nn as nn
import numpy as npclass Network(nn.Module):def __init__(self):super(Network,self).__init__()self.conv = nn.Conv2d(in_channels= 1,out_channels =1,kernel_size = (3,3),stride = 1,padding=0,dilation=3# 膨胀)def forward(self,x):x = self.conv(x)return xtorch.random.manual_seed(0)
input = torch.randint(0,255,(1,1,32,32),dtype=torch.float32)model = Network()
output = model(input)
print(output.shape)
2.5 可分离卷积
2.5.1 空间可分离卷积
空间可分离卷积是将卷积核分解为两项独立的核分别进行操作。
import torch
import torch.nn as nn
import numpy as npclass Network(nn.Module):def __init__(self):super(Network,self).__init__()self.conv = nn.Conv2d(in_channels= 1,out_channels =1,kernel_size = (3,3),bias = False,)def forward(self,x):x = self.conv(x)return xclass Network2(nn.Module):def __init__(self):super(Network2,self).__init__()self.conv = nn.Conv2d(in_channels= 1,out_channels =1,kernel_size = (1,3),# 空间可分离卷积bias = False,)self.conv2 = nn.Conv2d(in_channels= 1,out_channels =1,kernel_size = (3,1),# 空间可分离卷积bias = False,) def forward(self,x):x = self.conv(x)x = self.conv2(x)return xtorch.random.manual_seed(0)
input=torch.randint(0,255,(1,1,32,32),dtype=torch.float32)model1= Network()
model2= Network2()# for name,param in model1.named_parameters():# 参数量:8*8*3*3 =576
# print(name,param.shape)
# for name,param in model2.named_parameters():# 参数量:8*1*3*3+8*8 = 136
# print(name,param.shape)model1.conv.weight.data=torch.tensor([[[[0.1500, 0.2000, 0.2500],[0.2100, 0.2800, 0.3500],[0.2400, 0.3200, 0.4000]]]])
# for name,param in model1.named_parameters():
# print(name,param)
model2.conv.weight.data=torch.tensor([[[[0.3,0.4,0.5]]]])
model2.conv2.weight.data=torch.tensor([[[[0.5],[0.7],[0.8]]]])
# for name,param in model2.named_parameters():
# print(name,param)output1 = model1(input)
output2 = model2(input)
# 查看结果是否一样
print(output1[:,:,:5,:5])
print(output2[:,:,:5,:5])
2.5.2 深度可分离卷积
深度可分离卷积由两部组成:深度卷积和1x1卷积。
输入图的每一个通道,都使用了对应的卷积核进行卷积。 输入通道数量 = 卷积核个数。
对输出内容进行数量为通道个数的1x1
的卷积。输出通道数量 = 卷积核个数。
import torch
import torch.nn as nn
import numpy as npclass Network(nn.Module):def __init__(self):super(Network,self).__init__()self.conv = nn.Conv2d(in_channels= 8,out_channels =8,kernel_size = (3,3),bias = False,)def forward(self,x):x = self.conv(x)return xclass Network2(nn.Module):def __init__(self):super(Network2,self).__init__()self.conv = nn.Conv2d(in_channels= 8,out_channels =8,kernel_size = (3,3),groups = 8, # 空间可分离卷积bias = False)self.conv2 = nn.Conv2d(in_channels= 8,out_channels =8,kernel_size = (1,1),# 空间可分离卷积bias = False) def forward(self,x):x = self.conv(x)x = self.conv2(x)return x# 输入的特征图数据
input = torch.randint(0,225,(1,8,32,32),dtype=torch.float32)model1= Network()
model2= Network2()
output1 = model1(input)
output2 = model2(input)for name,param in model1.named_parameters():# 参数量:8*8*3*3 =576print(name,param.shape)
for name,param in model2.named_parameters():# 参数量:8*1*3*3+8*8 = 136print(name,param.shape)
2.6 扁平卷积
扁平卷积是将标准卷积拆分成为3个1x1
的卷积核,然后再分别对输入层进行卷积计算。
-
标准卷积参数量X*Y*C,计算量为M*N*C*X*Y
-
拆分卷积参数量(X+Y+C),计算量为M*N*(C+X+Y)
2.7 分组卷积
2012年,AlexNet论文中最先提出来的概念,当时主要为了解决GPU显存不足问题,将卷积分组放到两个GPU中并行执行。
2.8 混洗分组卷积
分组卷积中最终结果会按照原先的顺序进行合并组合,阻碍了模型在训练时特征信息在通道间流动,削弱了特征表示。混洗分组卷积,主要是将分组卷积后的计算结果混合交叉在一起输出。
在分组卷积中,卷积核被分成不同的组,每组负责对相应的输入层进行卷积计算,最后再进行合并。
3.感受野
3.1 理解感受野
字面意思是感受的视野范围,为得到一个特征值,输入数据的size。
3.2 感受野的作用
卷积核所需的参数更少一些。
卷积过程越多,特征提取也会越细致,加入的非线性变换也随着增多 。