12.03 深度学习-池化+卷积扩展+感受野

发布于:2024-12-06 ⋅ 阅读:(33) ⋅ 点赞:(0)

# ## 3.池化层

# 池化层 (Pooling) 降低维度, 缩减模型大小,提高计算速度. 即: 主要对卷积层学习到的特征图进行下采样(SubSampling)处理。

# 1. 最大池化  max  pooling

#    最大池化是从每个局部区域中选择最大值作为池化后的值,这样可以保留局部区域中最显著的特征。最大池化在提取图像中的纹理、形状等方面具有很好的效果。

# 2. 平均池化  avgPooling

#    平均池化是将局部区域中的值取平均作为池化后的值,这样可以得到整体特征的平均值。平均池化在提取图像中的整体特征、减少噪声等方面具有较好的效果。

# 就是把卷积出来的特征图 再进行划分区域 然后每个区域取一个最大值 或者平均值 代表这个区域 然后全部区域的在装为一个新的图 这样图的大小就变了小了 而且特征也被强化了

# 一般池化核大小为2*2  步长也为2

# 池化在 卷积层之后 对卷积出来的特征图 进行池化 即缩小 不减少特征图的数量

# 池化的结果一般是原矩阵 的一般规格

# 池化操作的优势有:

# 1. 通过降低特征图的尺寸,池化层能够减少计算量,从而提升模型的运行效率。

# 2. 池化操作可以带来特征的平移、旋转等不变性,这有助于提高模型对输入数据的鲁棒性。

# 3. 池化层通常是非线性操作,例如最大值池化,这样可以增强网络的表达能力,进一步提升模型的性能。

# 但是池化也有缺点:

# 1. 池化操作会丢失一些信息,这是它最大的缺点;

import torch

from torch import nn

def demo1():

    # 池化核定义 最大2d池化

    pool=nn.MaxPool2d(kernel_size=2,stride=2,padding=0) # stride 默认跟kernel_size相同 池化也能填充

    # 数据定义

    input1=torch.randint(1,255,(1,64,224,224))

    # 池化结果

    out=pool(input1)

    print(out.shape)


 

# 卷积+池化+全连接

def demo2():

    class MyNet(nn.Module):

        def __init__(self, *args, **kwargs):

            super().__init__(*args, **kwargs)

            # 这里是可以看别人网路的图来指定网络  s代表池化 c代表卷积 layer代表线性

            self.hidden1=nn.Sequential(nn.Conv2d(1,6,kernel_size=5),nn.ReLU())

            self.hidden2=nn.Sequential(nn.MaxPool2d(kernel_size=2,stride=2))

            self.hidden3=nn.Sequential(nn.Conv2d(6,16,kernel_size=5),nn.ReLU())

            # 线性层要拉平算

            self.hidden4=nn.Sequential(nn.Linear(16*5*5,120),nn.ReLU())

            self.hidden5=nn.Sequential(nn.Linear(120,84),nn.ReLU())

            self.out=nn.Sequential(nn.Linear(84,10),nn.Softmax(dim=1))

        def forward(self,x):

            x=self.hidden1(x)

            x=self.hidden2(x)

            x=self.hidden3(x)

            x=self.hidden2(x)

            x=x.view(x.shape[0],-1)

            x=self.hidden4(x)

            x=self.hidden5(x)

            return self.out(x)

    net1=MyNet()

    input1=torch.rand(1,1,32,32)

    net1.eval()

    out=net1(input1)

    print(out)


 

#

# 卷积有2维 三维三维主要用于3D建模 和医学建模

# 反卷积:特征图像 和 卷积核 变会到原图

# 空洞卷积 卷积核 每一个格子之间空一格 变成一个膨胀的卷积核  这样使得一个卷积核生成出来的特征图 包含了更多的特征

# 设置卷积层的时候 加一个 传入一个参数dilation=N 表示两个卷积核 每一个格子之间空N一1格 当N=1时 相当于普通的卷积 当膨胀卷积核跟传入的数据大小相同时 逻辑上相当于全连接 卷积核大小增加了 N-1

# 空间可分离卷积 将卷积核分为两个矩阵相乘 然后这两个矩阵再分别先后去卷积 原矩阵 这样计算量小一点(卷积核参数少了规格少了) 实际还是在乘那个卷积核

# 深度可分离卷积 每一个通道 先用一个卷积核 卷积 得到 数量为通道数的 没有通道融合的特征图 然后 再用1*通道数的卷积核去按照一个通道的一叠卷积 然后得到一张特征图 (卷积核参数少了规格少了)

# api要用到分组

def demo3():

    class MyNet(nn.Module):

        def __init__(self, *args, **kwargs):

            super().__init__(*args, **kwargs)

           

            self.conv1=nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3,stride=1,groups=8)

            # groups 把输入通道 进行分组 每一组里面的卷积核的通道数为 这个组里面的通道数量 然后每一组的卷积核数量看输出多少特征图 平均分

            self.conv2=nn.Conv2d(in_channels=8,out_channels=8,kernel_size=1,stride=1)

        def forward(self,x):

            x=self.conv1(x)

            x=self.conv2(x)

            return x

    net1=MyNet()        

    input1=torch.rand(1,8,32,32)

    net1.eval()

    out=net1(input1)

    print(out.shape)

# ### 扁平卷积

# 扁平卷积是将标准卷积拆分成为3个`1x1`的卷积核,然后再分别对输入层进行卷积计算。 就是空间分离的变种

# ### 分组卷积   相当于空间分离 分组

# 2012年,AlexNet论文中最先提出来的概念,当时主要为了解决GPU显存不足问题,将卷积分组放到两个GPU中并行执行。

# 在分组卷积中,卷积核被分成不同的组,每组负责对相应的输入层进行卷积计算,最后再进行合并。

# 下图中卷积核被分成两个组,前半部负责处理前半部的输入层,后半部负责后半部的输入层,最后将结果组合。

# 混洗分组卷积

# 分组卷积中最终结果会按照原先的顺序进行合并组合,阻碍了模型在训练时特征信息在通道间流动,削弱了特征表示。混洗分组卷积,主要是将分组卷积后的计算结果混合交叉在一起输出。

# 分完组之后再把 全部组里面的通道顺序全打乱

# 感受野

# 特征图上 的一个特征值 需要多少个数据

# 多层叠加的感受野要去重算 多层就是卷积多次 每一层有自己的感受野 为卷积核大小

# 多层感受野有更是的参数 更多的运算次数 更多的激活函数

# 一般都用小的卷积核去堆叠 而不是大的 卷积核去减少运算次数 一次运算参数太多运输量太大

# 所以空洞卷积的感受野更大


 

if __name__=="__main__":

    # demo1()

    # demo2()

    demo3()

    pass


网站公告

今日签到

点亮在社区的每一天
去签到