经典视觉神经网络1 CNN
一、概述
输入的图像都很大,使用全连接网络的话,计算的代价较高,图像也很难保留原本特征。
卷积神经网络(Convolutional Neural Network,CNN)是一种专门用于处理具有网格状结构数据的深度学习模型。主要应用于计算机视觉任务,但它的成功启发了在其他领域应用,如自然语言处理等。
CNN网络主要有三部分构成:卷积层、池化层和全连接层构成;卷积层负责提取图像中的局部特征;池化层用来大幅降低运算量并特征增强;全连接层类似神经网络的部分,用来输出想要的结果。
1、全连接网络处理图像缺陷
参数结束了巨大:假设使用 100*1000的输入,神经元存在1000*1000,那么其中需要使用权重参数达到 10的十二次方。
表达能力:全连接无法利用好图片像素的空间特性,降低了学习效率
2、卷积思想
分为两个部分:卷和积 ; 卷 表示从左上 开始到右上,最后到右下的循环过程;积 表示将每次卷的内容进行乘积求和。
2.1、局部连接
没有全连接方式,空间距离越近的像素相互影响越大;局部特征完成目标的识别
2.2、权重共享
从一块区域学习的信息应用到其他区域;减少参数量,降低学习难度和计算量
二、 卷积层 Convolutional
1、卷积核
一个矩阵,用于提取图像的特征(根据数值内容处理为具体特征意义的数值)
卷积核(过滤器)的个数决定了卷积层输出特征矩阵的通道数;卷积核的大小一般设置为奇数形式的n*n,少数出现n*m(n决定行的卷积,m决定列的卷积)
2、卷积计算
原图像:5*5 的矩阵,经过边缘填充变成7*7的矩阵; 卷积核:3*3的矩阵; 特征图: 5*5的矩阵
卷积计算过程就是将卷积核放在图片信息上移动计算,每次达到下一个位置时,重合区域点对点相乘后全部相加,这个值就是特征图的一个格子数据,图像遍历完成后,所有的结果拼接变为特征图。
如下图,左上角的区域对于卷积核位置相乘相加:
API:
nn.Conv2d
参数:in_channels= int 图像信息的通道数
out_channels= int 输出特征图的通道数
kernel_size= int 或 tuple 卷积核的大小
stride= int 或 tuple 步长默认1,表示行或列的移动距离
padding= int,默认0 填充,保障边缘信息被提取
dilation= int 或 tuple 默认1,表示无间隔,若为1表示每次卷积核映射图像数据时,点位要行列都间隔1个格子。
groups 分组
bias= 默认True,需要偏置
padding_mode= str 填充模式,默认zero填充
device= 设备
dtype= 数据类型
代码:
import torch
import torch.nn as nn
from matplotlib import pyplot as plt def test001():img = plt.imread('./data/1.jpg')img = torch.tensor(img, dtype=torch.float32).permute(2,0,1).unsqueeze(0)# 创建卷积核conv = nn.Conv2d(in_channels=3, # 与输入特征图的通道数相同out_channels=3, # 决定输出特征图的通道数kernel_size = 3, # 卷积核的大小padding=1 # 填充周边)img_c = conv(img)img_c = img_c.permute(0,2,3,1).squeeze(0)plt.imshow(img_c.detach().numpy())plt.show()def test002():input = torch.randn(10,2,5,6)# 创建卷积核conv = nn.Conv2d(in_channels=2, # 与输入特征图的通道数相同out_channels=3, # 决定输出特征图的通道数kernel_size = (3,5), # 卷积核的大小padding=0, # 填充周边stride=1,bias=True)output = conv(input) # n = (w-f+2p)/s+1 --> H: (5-3+2*0)/1+1=3 W: (6-5+2*0)/1+1=2# w 通道大小# f 卷积核大小# p 填充大小# s 步长大小print(output.shape)if __name__ == '__main__':test001()
3、卷积计算的底层表示
4、padding 边缘填充
每次卷积都会对图像矩阵的行列数降低,若想要保持图像大小不变,则需要填充边缘,一般设置padding值为 (图像矩阵大小 - 卷积核大小)/2
如卷积计算的动图,就是padding设置为1 也就是图像矩阵大小减去卷积核大小(5-3)/2 的值
5、stride 步长
stride太小:重复计算较多,计算量大,训练效率降低;
stride太大:会造成信息遗漏,无法有效提炼数据背后的特征;
步长为1:
步长为2:
6、多通道计算
输入通道多时(图片一般为三通道或四通道),需要卷积核的 in_channels 等于输入通道数(卷积核的通道数与输入通道数一致 ;卷积核的个数与输出通道数一致);
7、多卷积核计算
从不同到的视角、不同的角度对图像特征进行提取。
8、特征图大小
计算方式:
若行列并不相等(图像、卷积核等),那么就需要单独计算:
9、参数共享
若数据为 32*32*3 的图像,使用了10*5*5的卷积核进行卷积操作(只需要考虑图像的通道了,图像大小不重要,因为参数共享),那么其需要的权重参数为
- 5*5*3 =75 表示每一个卷积核所需要的参数
- 10*75=750 表示全部卷积核所需要的参数
- 若考虑偏置系数,则需要加上每个卷积核一个偏置系数,总共为760个参数
若是选择使用全连接,那么所有的连接都需要使用权重参数(图像大小):32*32 * 3* 10*5*5 +10*5*5 = 768,250
三、池化层 Pooling
1、意义
降低数据维度,减小模型,提高计算速度;主要用于对卷积层处理后的特征图进行下采样操作。
2、计算方式
分为了 最大池化 maxpolling 和 平均池化 avgpooling
2.1、最大池化
选取映射内容中最大的数值
2.2、平均池化
所有映射值的平均值
3、步长 stride
步长为1和步长为2 的对比
4、边缘填充 padding
5、多通道计算
对每个输入通道分别池化,而不是像卷积层那样将各个通道的输入相加。
池化层的输出和输入的通道数保持相等。
6、API
nn.MaxPool2d
参数:kernel_size = int 或 tuple 池化核,于卷积核一样
stride= int 或 tuple ,步长
padding= int 或 tuple ,填充
dilation= int 或 tuple ,膨胀
return_indices= 默认false,不返回取值对于下标
ceil_mode= 默认false,向上取整
import torch
import torch.nn as nndef test01():torch.manual_seed(1)# 输入数据input = torch.randint(0,255,(1,64,224,224))print("输入数据:\n",input[0][0][:6,:6])# 池化核pool = nn.MaxPool2d(kernel_size=2,# 池化核大小stride=2,return_indices=True)# 对数据池化out,return_indices = pool(input)print("下标:\n",return_indices[0][0][:6,:6])print("输出结果:\n",out.shape)if __name__ == '__main__':test01()
四、卷积扩展
1、反卷积
因为一般情况下,使用卷积会造成缩小,所以需要使用填充对图像大小调整,称为反卷积
2、空洞卷积(膨胀)
使用参数 dilation 控制膨胀程度,1表示不膨胀,2表示膨胀一格距离。
import torch
import torch.nn as nndef test003():torch.manual_seed(1)# 输入数据x = torch.randn(1,1,7,7)# 创建一个卷积核conv = nn.Conv2d(in_channels=1,out_channels=1, kernel_size=3, stride=1,dilation=2,)out = conv(x)print(out.shape)print(out)if __name__ == '__main__':test003()
3、可分离卷积
3.1、空间可分离卷积
将卷积核拆分为两个独立的核计算(3*3 --> 3*1 + 1*3 ),拆分后计算量比标准卷积更少。
如图:5*5 的数据矩阵需要使用3*3的卷积核计算,先使用3*1的卷积核计算得到3*5得数据,在使用1*3得卷积和得到3*3得数据结果。
import torch
import torch.nn as nn# def test004():
class nornalModel(nn.Module):def __init__(self):super(nornalModel, 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):self.conv1.weight.data.fill_(1)x = self.conv1(x)return xclass waveModel(nn.Module):def __init__(self):super(waveModel, self).__init__()self.conv1 = nn.Conv2d(in_channels=8, out_channels=8, kernel_size=(3,1),stride=1,padding=0,bias=False)self.conv2 = nn.Conv2d(in_channels=8, out_channels=8, kernel_size=(1,3),stride=1,padding=0,bias=False)def forward(self,x):self.conv1.weight.data.fill_(1)self.conv2.weight.data.fill_(1)x = self.conv1(x)x = self.conv2(x)return xif __name__ == '__main__':torch.manual_seed(1)input = torch.randn(1,8,5,5)model1 = nornalModel()for name, param in model1.named_parameters():print(name, param.shape)torch.manual_seed(1)input = torch.randn(1,8,5,5)model2 = waveModel()for name, param in model2.named_parameters():print(name, param.shape)# conv1.weight torch.Size([8, 8, 3, 3])
# conv1.weight torch.Size([8, 8, 3, 1])
# conv2.weight torch.Size([8, 8, 1, 3])
3.2、深度可分离卷积
在空间分离基础上加入通道分离,使用参数 groups进行划分(要求输入通道和输出通道都能被groups设定整数值整除);也就是使用卷积核得不同通道处理输入输出得不同通道。
import torch
import torch.nn as nnclass Net1(nn.Module):def __init__(self):super(Net1, self).__init__()self.conv1 = nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3,stride=1,bias=False)def forward(self, x):return self.conv1(x)class deepmovemodel(nn.Module):def __init__(self):super(deepmovemodel, self).__init__()self.conv1 = nn.Conv2d(in_channels=8,out_channels=8,kernel_size=3,stride=1,bias=False,groups=8 # 卷积核数量等于通道数)self.conv2 = nn.Conv2d(in_channels=8,out_channels=8,kernel_size=1,stride=1,bias=False)def forward(self, x):x = self.conv1(x)torch.ones_like(self.conv2.weight.data)x = self.conv2(x)return xif __name__ == '__main__':torch.manual_seed(1)input = torch.randn(1,8,5,5)model1 = Net1()for name, param in model1.named_parameters():print(name,param.size())model2 = deepmovemodel()for name, param in model2.named_parameters():print(name,param.size())# conv1.weight torch.Size([8, 8, 3, 3])
# conv1.weight torch.Size([8, 1, 3, 3])
# conv2.weight torch.Size([8, 8, 1, 1])
3.3、扁平卷积
等同空间可分离卷积,如3*3得卷积核被拆分为3个1*1得卷积核,分别计算通道、宽度、高度三个方面内容。
3.4、分组卷积
等同深度可分离卷积。
AlexNet论文中最先提出来的概念,当时主要为了解决GPU显存不足问题。
卷积核被分成不同的组,每组负责对相应的输入层进行卷积计算,最后再进行合并。
3.5、感受野
理解为视野范围。
卷积操作从左到右为5*5矩阵经过3*3的卷积核卷积后得到3*3的矩阵,在经过3*3的卷积核卷积后得到1*1的矩阵,效果等同于5*5矩阵直接经过5*5的卷积核卷积操作。
感受野就是逆向的结果,两个3*3的卷积核且步长为1,感受野为5*5;同理,三个3*3的卷积核,感受野就为7*7,四个3*3为9*9(步长为1)
感受野的作用:假设原本输入大小为 h × w × C,并且使用了C个卷积核,那么标准的一个7*7卷积核就需要 c* (h*w*c) = 49 ,使用三个3*3的卷积核,那么其感受野也还是7*7,但是参数就变成了 3*C*(3*3*C) = 27
五、卷积神经网络案例
1、模型结构
输入:(1,32,32)通道为1,宽高为32的数据
卷积层1:输入1 个通道(等于输入数据的通道数),输出6个通道(卷积核个数),卷积核大小为3*3;
特征图1:数据32*32,卷积核3*3,步长1,填充0:(32-3+2*0)/1 +1 =30,所以为6个30*30的特征图
池化层1:使用6个2*2的池化核进行处理
特征图2:30*30池化后(2*2,步长为2)结果为其一半 15*15
卷积层2:输入6个通道,输出16个通道,卷积核为3*3
特征图3:15*15卷积后得到13*13 的大小; 16个13*13
池化层2:使用16个2*2的池化核进行处理
特征图4:13*13池化后(2*2,步长为2)结果为其一半(向下取整,因为步长为2,所以取不到最右边和最下边的数据); 16个6*6
全连接1:输入需要16*6*6=576 维,输出为 120维
全连接2:输入120维,输出为 84维
全连接3:输入84维,输出为 10维
2、使用代码展现网络模型
import torch
import torch.nn as nnclass numberModee(nn.Module):def __init__(self):super(numberModee, self).__init__()self.C1 = nn.Sequential(nn.Conv2d(in_channels=1, # 输入通道out_channels=6, # 输出通道kernel_size=3, # 卷积核大小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=3, stride=1, padding=0),nn.ReLU())self.S4 = nn.MaxPool2d(kernel_size=2,stride=2,padding=0)self.C5 = nn.Sequential(nn.Linear(16*6*6, 120),nn.ReLU())self.F6 = nn.Sequential(nn.Linear(120, 84),nn.ReLU())self.OUTPUT = nn.Sequential(nn.Linear(84, 10),nn.Softmax(dim=1))def forward(self, x):x = self.C1(x)x = self.S2(x)x = self.C3(x)x = self.S4(x)x = x.view(x.size(0),-1)x = self.C5(x)x = self.F6(x)x = self.OUTPUT(x)return xif __name__ == '__main__':input = torch.randn(1, 1, 32, 32)print(input)print(input.shape)net = numberModee()out = net(input) # 6 @ 30*30 # 6 @ 15*15# 16 @ 13*13# 16 @ 6*6# 120# 84# 10print(out)print(out.shape)
相关文章:

经典视觉神经网络1 CNN
一、概述 输入的图像都很大,使用全连接网络的话,计算的代价较高,图像也很难保留原本特征。 卷积神经网络(Convolutional Neural Network,CNN)是一种专门用于处理具有网格状结构数据的深度学习模型。主要应用…...

一些硬件知识【2024/12/6】
MP6924A: 正点原子加热台拆解: PMOS 相比 NMOS 的缺点: 缺点描述迁移率低PMOS 中的空穴迁移率约为电子迁移率的 1/3 到 1/2,导致导通电流较低。开关速度慢由于迁移率较低,PMOS 的开关速度比 NMOS 慢,不适合高速数字电…...
网络安全法-网络安全支持与促进
第二章 网络安全支持与促进 第十五条 国家建立和完善网络安全标准体系。国务院标准化行政主管部门和国务院其他有关部门根据各自的职责,组织制定并适时修订有关网络安全管理以及网络产品、服务和运行安全的国家标准、行业标准。 国家支持企业、研究机构、高等学…...

【Docker】如何在Docker中配置防火墙规则?
Docker本身并不直接管理防火墙规则;它依赖于主机系统的防火墙设置。不过,Docker在启动容器时会自动配置一些iptables规则来管理容器网络流量。如果你需要更细粒度地控制进出容器的流量,你需要在主机系统上配置防火墙规则。以下是如何在Linux主…...

Cesium 问题: 添加billboard后移动或缩放地球,标记点位置会左右偏移
文章目录 问题分析原先的:添加属性——解决漂移移动问题产生新的问题:所选的经纬度坐标和应放置的位置有偏差解决坐标位置偏差的问题完整代码问题 添加 billboard 后, 分析 原先的: // 图标加载 function addStation ({lon, lat, el, testName...
使用Python3 连接操作 OceanBase数据库
注:使用Python3 连接 OceanBase数据库,可通过安装 PyMySQL驱动包来实现。 本次测试是在一台安装部署OBD的OceanBase 测试linux服务器上,通过python来远程操作OceanBase数据库。 一、Linux服务器通过Python3连接OceanBase数据库 1.1 安装pyth…...

SpringBoot该怎么使用Neo4j - 优化篇
文章目录 前言实体工具使用 前言 上一篇中,我们的Cypher都用的是字符串,字符串拼接简单,但存在写错的风险,对于一些比较懒的开发者,甚至觉得之间写字符串还更自在快速,也确实,但如果在后期需要…...

Flutter如何调用java接口如何导入java包
文章目录 1. Flutter 能直接调用 Java 的接口吗?如何调用 Java 接口? 2. Flutter 能导入 Java 的包吗?步骤: 总结 在 Flutter 中,虽然 Dart 是主要的开发语言,但你可以通过**平台通道(Platform …...

Redis 数据结构(一)—字符串、哈希表、列表
Redis(版本7.0)的数据结构主要包括字符串(String)、哈希表(Hash)、列表(List)、集合(Set)、有序集合(Sorted Set)、超日志(…...

day1:ansible
ansible-doc <module_name>(如果没有网,那这个超级有用) 这个很有用,用来查单个模块的文档。 ansible-doc -l 列出所有模块 ansible-doc -s <module_name> 查看更详细的模块文档。 ansible-doc --help 使用 --help …...
如何设置Java爬虫的异常处理?
在Java爬虫中设置异常处理是非常重要的,因为网络请求可能会遇到各种问题,如连接超时、服务器错误、网络中断等。通过合理的异常处理,可以确保爬虫的稳定性和健壮性。以下是如何在Java爬虫中设置异常处理的步骤和最佳实践: 1. 使用…...
阿里云盘permission denied
问题是执行 ./aliyunpan 时遇到了 Permission denied 的错误。这通常是因为文件没有执行权限。以下是解决问题的步骤: 检查文件权限 运行以下命令检查文件的权限: ls -l aliyunpan输出中会看到类似以下内容: -rw-r--r-- 1 user group 123…...
在 Ubuntu 24 上安装 Redis 7.0.15 并配置允许所有 IP 访问
前提条件 一台运行 Ubuntu 24 的服务器拥有 sudo 权限的用户 步骤一:更新系统包 首先,确保系统包是最新的,以避免潜在的依赖问题。 sudo apt update sudo apt upgrade -y步骤二:安装编译 Redis 所需的依赖 Redis 需要一些编译…...
构建高效可靠的分布式推理系统:深入解析控制器与模型服务的协同工作
在现代互联网应用中,随着用户需求的增长和技术的进步,单一服务器已经难以满足大规模并发请求的需求。为了提升系统的性能和可靠性,开发者们越来越多地采用分布式架构。本文将结合具体的代码示例,深入浅出地探讨如何构建一个高效的分布式推理系统,并详细解析其中的关键组件…...

springboot394疫情居家办公系统(论文+源码)_kaic
摘 要 如今社会上各行各业,都喜欢用自己行业的专属软件工作,互联网发展到这个时候,人们已经发现离不开了互联网。新技术的产生,往往能解决一些老技术的弊端问题。因为传统疫情居家办公系统信息管理难度大,容错率低&a…...

共筑数字安全防线,2024开源和软件安全沙龙即将启幕
随着数字化转型进程的加快以及开源代码的广泛应用,开源凭借平等、开放、协作、共享的优秀创作模式,逐渐成为推动数字技术创新、加速传统行业转型升级的重要模式。但随着软件供应链日趋复杂多元,使得其安全风险不断加剧,针对软件供…...
后端报错: message: “For input string: \“\““
这个错误信息表明后端尝试将一个空字符串 "" 转换为某种数值类型(如整数、长整型等),但转换失败了。在许多编程语言中,如果你试图解析一个非数字的字符串(在这个情况下是一个空字符串)为数值类型…...

39 矩阵置零
39 矩阵置零 39.1 矩阵置零解决方案 解题思路: 利用第一行和第一列标记: 使用两个标记变量,rowZero和colZero,来判断第一行和第一列是否需要置零。遍历矩阵从(1,1)开始,如果某个元素是0,则标记该行和该列…...

使用伪装IP地址和MAC地址进行Nmap扫描
使用伪装IP地址和MAC地址进行Nmap扫描 在某些网络设置中,攻击者可以使用伪装的IP地址甚至伪装的MAC地址进行系统扫描。这种扫描方式只有在可以保证捕获响应的情况下才有意义。如果从某个随机的网络尝试使用伪装的IP地址进行扫描,很可能无法接收到任何响…...

linux安装docker和mysql
1.下载安装doker 1. 更新系统,确保系统是最新的 sudo yum update -y2.安装 Docker 所需的依赖包: sudo yum install -y yum-utils 2. 设置 Docker 仓库 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 3. 安装 Dock…...

Flask RESTful 示例
目录 1. 环境准备2. 安装依赖3. 修改main.py4. 运行应用5. API使用示例获取所有任务获取单个任务创建新任务更新任务删除任务 中文乱码问题: 下面创建一个简单的Flask RESTful API示例。首先,我们需要创建环境,安装必要的依赖,然后…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
数据库分批入库
今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容
目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法,当前调用一个医疗行业的AI识别算法后返回…...

mac 安装homebrew (nvm 及git)
mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...
人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent
安全大模型训练计划:基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标:为安全大模型创建高质量、去偏、符合伦理的训练数据集,涵盖安全相关任务(如有害内容检测、隐私保护、道德推理等)。 1.1 数据收集 描…...

【版本控制】GitHub Desktop 入门教程与开源协作全流程解析
目录 0 引言1 GitHub Desktop 入门教程1.1 安装与基础配置1.2 核心功能使用指南仓库管理日常开发流程分支管理 2 GitHub 开源协作流程详解2.1 Fork & Pull Request 模型2.2 完整协作流程步骤步骤 1: Fork(创建个人副本)步骤 2: Clone(克隆…...
深入解析 ReentrantLock:原理、公平锁与非公平锁的较量
ReentrantLock 是 Java 中 java.util.concurrent.locks 包下的一个重要类,用于实现线程同步,支持可重入性,并且可以选择公平锁或非公平锁的实现方式。下面将详细介绍 ReentrantLock 的实现原理以及公平锁和非公平锁的区别。 ReentrantLock 实现原理 基本架构 ReentrantLo…...
Go爬虫开发学习记录
Go爬虫开发学习记录 基础篇:使用net/http库 Go的标准库net/http提供了完善的HTTP客户端功能,是构建爬虫的基石: package mainimport ("fmt""io""net/http" )func fetchPage(url string) string {// 创建自定…...

【电路笔记】-变压器电压调节
变压器电压调节 文章目录 变压器电压调节1、概述2、变压器电压调节3、变压器电压调节示例14、变压器电压调节示例25、变压器电压调节示例36、总结变压器电压调节是变压器输出端电压因连接负载电流的变化而从其空载值向上或向下变化的比率或百分比值。 1、概述 电压调节是衡量变…...