视觉经典网络学习02_池化层感受野

news/2024/12/5 3:51:08/

目录

一、池化层

池化API使用

多通道池化计算

池化层的作用

二、感受野

感受野的作用

三、其他卷积知识扩展

1、二维卷积

单通道

多通道

2、三维卷积

3、反卷积

4、空洞卷积(膨胀卷积)

5、可分离卷积

空间可分离卷积

深度可分离卷积

6、分组卷积


一、池化层

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

池化层主要有两种:

  1. 最大池化 max pooling

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

  2. 平均池化 avgPooling

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

池化API使用

池化层中没有设置参数:

import torch
import torch.nn as nn"""池化层API的使用"""
def test01():torch.manual_seed(1)# 输入特征图input = torch.randint(0,255,(1,64,224,224)).float()# 池化核pool = nn.MaxPool2d(kernel_size=2,stride=2,return_indices=True # 返回索引)# 池化操作out,indices = pool(input)print(out.shape)  # torch.Size([1, 64, 112, 112])print(indices)if __name__ == '__main__':test01()

多通道池化计算

在处理多通道输入数据时,池化层对每个输入通道分别池化,而不是像卷积层那样将各个通道的输入相加。这意味着池化层的输出和输入的通道数是相等的

池化层的作用

池化操作的优势有:

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

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

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

但是池化也有缺点:

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

二、感受野

感受野(Receptive Field, RF)是神经网络中一个非常重要的概念,特别是在卷积神经网络(CNN)中。它描述了网络中某个节点(或输出单元)能够看到的输入图像中的区域大小。简单来说,就是指该节点对输入数据哪个部分敏感,即感受的视野范围。

感受野的作用

案例:如果堆叠3个3 x 3的卷积层,并且保持滑动窗口步长为1,其感受野就是7×7的了, 这跟一个使用7x7卷积核的结果是一样的,为什么非要堆叠3个小卷积呢?

假设输入大小都是h × w × C,并且都使用C个卷积核(得到C个特征图):

 很明显,堆叠小的卷积核所需的参数更少一些,并且卷积过程越多,特征提取也会越细致,加入的非线性变换也随着增多,还不会增大权重参数个数,这就是感受野的基本出发点,用小的卷积核来完成体特征提取操作。

三、其他卷积知识扩展

1、二维卷积

单通道

单通道卷积也叫叫做二维卷积,即只有一个通道的卷积。

如下图,我们对于卷积核(kernel)的描述一般是大小3x3、步长(stride)为1、填充(Padding)为0

多通道

彩色图像拥有R、G、B这三层通道,因此我们在卷积时需要分别针对这三层进行卷积:

最后将三个通道的卷积结果进行合并(元素相加),得到卷积结果。

2、三维卷积

二维卷积是在单通道的一帧图像上进行滑窗操作,输入是高度H宽度W的二维矩阵。

而如果涉及到视频上的连续帧或者立体图像中的不同切片,就需要引入深度通道,此时输入就变为高度H宽度W*深度C 的三维矩阵。

不同于二维卷积核只在两个方向上运动,三维卷积的卷积核会在三个方向上运动,因此需要有三个自由度

3、反卷积

卷积是对输入图像及进行特征提取,这样会导致尺寸会越变越小,而反卷积是进行相反操作。并不会完全还原到跟输入图一样,只是保证了与输入图像尺寸一致,主要用于向上采样。

从数学上看,反卷积相当于是将卷积核转换为稀疏矩阵后进行转置计算。也被称为转置卷积。

计算过程

如图,在2x2的输入图像上使用【步长1、边界全0填充】的3x3卷积核,进行转置卷积(反卷积)计算,向上采样后输出的图像大小为4x4

4、空洞卷积(膨胀卷积)

为扩大感受野,在卷积核俩面的元素之间插入空格“膨胀”内核,形成“空洞卷积”(或称膨胀卷积),并用膨胀率参数 L 表示要扩大内核的范围,即在内核元素之间插入 L-1 个空格。

L=1时,则内核元素之间没有插入空格,变为标准卷积。图中是L=2的空洞卷积。

import torch
import torch.nn as nn"""膨胀卷积"""
def test01():# 输入数据input = torch.randn(1,1,7,7)# 创建卷积核conv = nn.Conv2d(in_channels=1,  # 输入通道数out_channels=1,  # 输出通道数kernel_size=(3,3),  # 卷积核大小stride=1,  # 步长dilation=3,  # 卷积核间距(膨胀率))# 卷积操作out = conv(input)print(out.shape) # torch.Size([1, 1, 1, 1])# 若 dilation=1 则结果为 torch.Size([1, 1, 5, 5])if __name__ == '__main__':test01()

5、可分离卷积

空间可分离卷积

空间可分离卷积是将卷积核分解为两项独立的核分别进行操作。

在数学中我们可以将矩阵分解:

\left[ \begin{matrix} -1 & 0 & 1 \\ -2 & 0 & 2 \\ -1 & 0 & 1 \end{matrix} \right]= \left[ \begin{matrix} 1 \\ 2 \\ 1 \end{matrix} \right]\times \left[ \begin{matrix} -1 & 0 & 1 \end{matrix} \right]

所以对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),kernel_size=(1,3), # 分离stride=1,bias=False,groups=1)def forward(self,x):x = self.conv1(x)return xif __name__ == '__main__':model1 = NormalModel()# 打印参数for name,param in model1.named_parameters():print(name,param.size())print("-"*20)model2 = WaveModel()for name,param in model2.named_parameters():print(name,param.size())
深度可分离卷积

深度可分离卷积由两部组成:深度卷积核1x1卷积

import torch
import torch.nn as nn"""对比普通卷积"""
class NormalModel(nn.Module):def __init__(self):super(NormalModel,self).__init__()self.conv1(in_channels=8,out_channels=8,kernel_size=3,stride=1,padding=0,bias=False)def forward(self,x):return self.conv1(x)"""分离"""
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 # 输入通道平均分成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.shape)print("-"*20)model2 = deepWaveModel() # 8*1*3*3+8*8*1*1=136for name, param in model2.named_parameters():print(name, param.shape)# conv1.weight torch.Size([8, 1, 3, 3]) 8个通道 8个输入通道分成8组每组一个核 大小3*3# conv2.weight torch.Size([8, 8, 1, 1]) 8个通道 8个核 大小1*1

6、分组卷积

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

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

import torch
import torch.nn as nnclass GroupModel(nn.Module):def __init__(self):super(GroupModel, self).__init__()self.conv1 = nn.Conv2d(# in_channels=16, # conv1.weight torch.Size([24, 2, 3, 3])in_channels=32, # conv1.weight torch.Size([24, 4, 3, 3])out_channels=24,kernel_size=3,stride=1,padding=0,# 分组卷积,将输入通道分成groups组,每组in_channels/groups个核,每个核与输入通道的每个通道进行卷积groups=8,bias=False)def forward(self, x):x = self.conv1(x)return xif __name__ == '__main__':model = GroupModel()for name, param in model.named_parameters():print(name, param.shape)

 


http://www.ppmy.cn/news/1552461.html

相关文章

BFD双向转发检测协议——BFD+VRRP配置实现

BFD双向转发检测协议 Tips: 一种全网统一、检测迅速、监控网络中链路或者IP路由的双向转发连通状况,并为上层应用提供服务的技术。联动功能由检测模块、Track和应用模块三部分组成。查看bfd会话命令:dis bfd session all 本次实验模拟配置BFDVRRP AR…

考研408《计算机网络》复习笔记,第三章《计算机网络分类》

一、按分布范围分类 看下图即可,灰色的不重要,【广域网】和【局域网】是重点!! 【广域网和局域网的关系】 局域网通过路由器,接入广域网 【个域网】 二、按传输技术分类 广播式网络: 【类似 “某人的群…

利用Python爬虫获取淘宝关键词接口的深入解析

引言 随着电子商务的蓬勃发展,淘宝作为中国最大的电商平台之一,其数据挖掘和分析成为了众多商家和研究者关注的焦点。淘宝关键词接口作为获取商品信息的重要途径,能够帮助我们洞察市场趋势、优化商品策略等。本文将详细介绍如何利用Python爬…

如何参加华为欧拉考试?

华为欧拉考试主要针对的是华为欧拉(EulerOS/openEuler)操作系统的认证考试,这一认证体系旨在培养和认证具备基于欧拉操作系统进行企业级应用运行基础环境搭建、管理和调测能力的工程师以及云计算架构师。以下是对华为欧拉考试的详细介绍&…

【测试工具JMeter篇】JMeter性能测试入门级教程(七):JMeter断言

一、前言 在 JMeter 中,断言元件(Assertion)用于验证测试结果是否符合预期。断言元件可以检查服务器的响应数据,以确保它们符合期望的模式或值,从而验证性能测试脚本的正确性。断言元件通常在每个请求的响应中添加&am…

@Cacheable加缓存导致的跳过校验 self自调用

Cacheable加缓存导致的跳过校验 & self自调用 Cacheable加缓存导致的跳过校验 Service public class DataServiceImpl implements DataService {// 这个属性指向当前类的代理对象Autowiredprivate DataService self;OverrideCacheable(value "dataCache", key…

Oracle 插入数据的存储过程

Oracle 插入数据的存储过程 这是用来,把实时表里面的数据插入到某个表A获取到的字段neid,然后拼接成xxx_xxx_neid历史表,接着往里面插入数据 CREATE OR REPLACE PROCEDURE XXX自定义名 IS-- 定义变量v_ne_id_table_name VARCHAR2(100); …

Debian 的更新原理

Debian 是一个遵循点版本(point release)模式的 Linux 发行版,更新原理是基于点版本发布模式,通过 APT 工具来管理和同步软件包,同时考虑到依赖性、安全性和稳定性。用户可以通过简单的命令来更新系统,而不…