【入门】5分钟了解卷积神经网络CNN是什么

本文来自《老饼讲解-BP神经网络》https://www.bbbdata.com/

目录

  • 一、卷积神经网络的结构
    • 1.1.卷积与池化的作用
    • 2.2.全连接层的作用
  • 二、卷积神经网络的运算
    • 2.1.卷积层的运算
    • 2.2.池化的运算
    • 2.3.全连接层运算
  • 三、pytorch实现一个CNN例子
    • 3.1.模型的搭建
    • 3.2.CNN完整训练代码

CNN神经网络常用于图片识别,是深度学习中常用的模型。
本文简单快速了解卷积神经网络是什么东西,并展示一个简单的示例。

一、卷积神经网络的结构

一个经典的卷积神经网络的结构如下:
卷积神经网络
C代表卷积层,P代表池化层,F代表全连接层。
卷积神经网络主要的、朴素的用途是图片识别。即输入图片,然后识别图片的类别,例如输入一张图片,识别该图片是猫还是狗。

1.1.卷积与池化的作用

卷积层与池化层共同是卷积神经网络的核心,它用于将输入图片进行压缩,例如一张224x224的图片,经过卷积+池化后,可能得到的就是55x55的图片,也就是说,卷积与池化的目的就是使得输入图片变小,同时尽量不要损失太多与类别相关的信息。例如一张猫的图片经过卷积与池化之后,尽量减少图片的大小,但要尽可能地保留"猫"的信息。

2.2.全连接层的作用

全连接层主要用于预测图片的类别。全连接层实际可以看作一个BP神经网络模型, 使用"卷积+池化"之后得到的特征来拟合图片的类别。

二、卷积神经网络的运算

2.1.卷积层的运算

卷积层的运算如下:
卷积运算
卷积层中的卷积核就是一个矩阵,直观来看它就是一个窗口,卷积窗口一般为正方形,即长宽一致,
卷积运算通过从左到右,从上往下移动卷积核窗口,将窗口覆盖的每一小块输入进行加权,作为输出

2.2.池化的运算

池化层是通过一个池化窗口,对输入进行逐块扫描,每次将窗口的元素合并为一个元素,
池化层的运算如下:
池化运算
池化层一般分为均值池化与最大值池化,顾名思义,就是计算时使用均值还是最大值:
均值池化与最大值池化

2.3.全连接层运算

全连接层就相当于一个BP神经网络模型,即每一层与下一层都是全连接形式。
全连接层

假设前一层传过来的输入的是X,则当前层的输出是tanh(WX+b)

三、pytorch实现一个CNN例子

下面以手写数字识别为例,展示如何使用pytorch实现一个CNN
在这里插入图片描述

3.1.模型的搭建

如下所示,就搭建了一个CNN模型

# 卷积神经网络的结构
class ConvNet(nn.Module):def __init__(self,in_channel,num_classes):super(ConvNet, self).__init__()self.nn_stack=nn.Sequential(#--------------C1层-------------------nn.Conv2d(in_channel,6, kernel_size=5,stride=1,padding=2),nn.ReLU(inplace=True),  nn.AvgPool2d(kernel_size=2,stride=2),# 输出14*14#--------------C2层-------------------nn.Conv2d(6,16, kernel_size=5,stride=1,padding=2),nn.ReLU(inplace=True),nn.AvgPool2d(kernel_size=2,stride=2),# 输出7*7#--------------C3层-------------------nn.Conv2d(16,80,kernel_size=7,stride=1,padding=0),# 输出1*1*80#--------------全连接层F4----------nn.Flatten(),          # 对C3的结果进行展平nn.Linear(80, 120),  nn.ReLU(inplace=True),                                   #--------------全连接层F5----------                      nn.Linear(120, num_classes)                       )def forward(self, x):p = self.nn_stack(x)return p

从代码里可以看到,只需按自己所设定的结构进行随意搭建就可以了。
搭建了之后再使用数据进行训练可以了,然后就可以使用模型对样本进行预测。

3.2.CNN完整训练代码

完整的CNN训练代码示例如下:

import torch
from   torch import nn
from   torch.utils.data   import DataLoader
import torchvision
import numpy as np#--------------------模型结构--------------------------------------------
# 卷积神经网络的结构
class ConvNet(nn.Module):def __init__(self,in_channel,num_classes):super(ConvNet, self).__init__()self.nn_stack=nn.Sequential(#--------------C1层-------------------nn.Conv2d(in_channel,6, kernel_size=5,stride=1,padding=2),nn.ReLU(inplace=True),  nn.AvgPool2d(kernel_size=2,stride=2),# 输出14*14#--------------C2层-------------------nn.Conv2d(6,16, kernel_size=5,stride=1,padding=2),nn.ReLU(inplace=True),nn.AvgPool2d(kernel_size=2,stride=2),# 输出7*7#--------------C3层-------------------nn.Conv2d(16,80,kernel_size=7,stride=1,padding=0),# 输出1*1*80#--------------全连接层F4----------nn.Flatten(),          # 对C3的结果进行展平nn.Linear(80, 120),  nn.ReLU(inplace=True),                                   #--------------全连接层F5----------                      nn.Linear(120, num_classes)                       )def forward(self, x):p = self.nn_stack(x)return p#-----------------------模型训练---------------------------------------
# 参数初始化函数
def init_param(model):# 初始化权重阈值                                                                         param_list = list(model.named_parameters())                                                # 将模型的参数提取为列表                      for i in range(len(param_list)):                                                           # 逐个初始化权重、阈值is_weight = i%2==0                                                                     # 如果i是偶数,就是权重参数,i是奇数就是阈值参数if is_weight:                                                                          torch.nn.init.normal_(param_list[i][1],mean=0,std=0.01)                            # 对于权重,以N(0,0.01)进行随机初始化else:                                                                                  torch.nn.init.constant_(param_list[i][1],val=0)                                     # 阈值初始化为0# 训练函数                                                                                     
def train(dataloader,valLoader,model,epochs,goal,device):                                      for epoch in range(epochs):                                                                err_num  = 0                                                                           # 本次epoch评估错误的样本eval_num = 0                                                                           # 本次epoch已评估的样本print('-----------当前epoch:',str(epoch),'----------------')                           for batch, (imgs, labels) in enumerate(dataloader):                                    # -----训练模型-----                                                               x, y = imgs.to(device), labels.to(device)                                          # 将数据发送到设备optimizer.zero_grad()                                                              # 将优化器里的参数梯度清空py   = model(x)                                                                    # 计算模型的预测值   loss = lossFun(py, y)                                                              # 计算损失函数值loss.backward()                                                                    # 更新参数的梯度optimizer.step()                                                                   # 更新参数# ----计算错误率----                                                               idx      = torch.argmax(py,axis=1)                                                 # 模型的预测类别eval_num = eval_num + len(idx)                                                     # 更新本次epoch已评估的样本err_num  = err_num +sum(y != idx)                                                  # 更新本次epoch评估错误的样本if(batch%10==0):                                                                   # 每10批打印一次结果print('err_rate:',err_num/eval_num)                                            # 打印错误率# -----------验证数据误差---------------------------                                   model.eval()                                                                           # 将模型调整为评估状态val_acc_rate = calAcc(model,valLoader,device)                                          # 计算验证数据集的准确率model.train()                                                                          # 将模型调整回训练状态print("验证数据的准确率:",val_acc_rate)                                                # 打印准确率    if((err_num/eval_num)<=goal):                                                          # 检查退出条件break                                                                              print('训练步数',str(epoch),',最终训练误差',str(err_num/eval_num))                         # 计算数据集的准确率                                                                           
def calAcc(model,dataLoader,device):                                                           py = np.empty(0)                                                                           # 初始化预测结果y  = np.empty(0)                                                                           # 初始化真实结果for batch, (imgs, labels) in enumerate(dataLoader):                                        # 逐批预测cur_py =  model(imgs.to(device))                                                       # 计算网络的输出cur_py = torch.argmax(cur_py,axis=1)                                                   # 将最大者作为预测结果py     = np.hstack((py,cur_py.detach().cpu().numpy()))                                 # 记录本批预测的yy      = np.hstack((y,labels))                                                         # 记录本批真实的yacc_rate = sum(y==py)/len(y)                                                               # 计算测试样本的准确率return acc_rate                                                                               #--------------------------主流程脚本----------------------------------------------       
#-------------------加载数据--------------------------------
train_data = torchvision.datasets.MNIST(root       = 'D:\pytorch\data'                                                             # 路径,如果路径有,就直接从路径中加载,如果没有,就联网获取,train     = True                                                                          # 获取训练数据,transform = torchvision.transforms.ToTensor()                                             # 转换为tensor数据,download  = True                                                                          # 是否下载,选为True,就下载到root下面,target_transform= None)                                                                   
val_data = torchvision.datasets.MNIST(root       = 'D:\pytorch\data'                                                             # 路径,如果路径有,就直接从路径中加载,如果没有,就联网获取,train     = False                                                                         # 获取测试数据,transform = torchvision.transforms.ToTensor()                                             # 转换为tensor数据,download  = True                                                                          # 是否下载,选为True,就下载到root下面,target_transform= None)                                                                   #-------------------模型训练--------------------------------                                   
trainLoader = DataLoader(train_data, batch_size=1000, shuffle=True)                            # 将数据装载到DataLoader
valLoader   = DataLoader(val_data  , batch_size=100)                                           # 将验证数据装载到DataLoader 
device      = torch.device('cuda' if torch.cuda.is_available() else 'cpu')                     # 设置训练设备  
model       = ConvNet(in_channel =1,num_classes=10).to(device)                                 # 初始化模型,并发送到设备  
lossFun     = torch.nn.CrossEntropyLoss()                                                      # 定义损失函数为交叉熵损失函数
optimizer   = torch.optim.SGD(model.parameters(), lr=0.01,momentum =0.9,dampening=0.0005)      # 初始化优化器
train(trainLoader,valLoader,model,1000,0.01,device)                                            # 训练模型,训练100步,错误低于1%时停止训练# -----------模型效果评估--------------------------- 
model.eval()                                                                                   # 将模型切换到评估状态(屏蔽Dropout)
train_acc_rate = calAcc(model,trainLoader,device)                                              # 计算训练数据集的准确率
print("训练数据的准确率:",train_acc_rate)                                                      # 打印准确率
val_acc_rate = calAcc(model,valLoader,device)                                                  # 计算验证数据集的准确率
print("验证数据的准确率:",val_acc_rate)                                                        # 打印准确率

运行结果如下:

-----------当前epoch: 0 ---------------- 
err_rate: tensor(0.7000)                 
验证数据的准确率: 0.3350877192982456     
-----------当前epoch: 1 ---------------- 
err_rate: tensor(0.6400)                 
验证数据的准确率: 0.3350877192982456     
-----------当前epoch: 2 ---------------- 
.......
.......
-----------当前epoch: 77 ----------------
err_rate: tensor(0.0100)                 
验证数据的准确率: 1.0                    
-----------当前epoch: 78 ----------------
err_rate: tensor(0.)                     
验证数据的准确率: 1.0                    
-----------当前epoch: 79 ----------------
err_rate: tensor(0.0200)                 
验证数据的准确率: 1.0                    
-----------当前epoch: 80 ----------------
err_rate: tensor(0.0100)                 
验证数据的准确率: 0.9982456140350877     
-----------------------------------------
训练步数 80 ,最终训练误差 tensor(0.0088) 
训练数据的准确率: 0.9982456140350877     
验证数据的准确率: 0.9982456140350877 

可以看到,识别效果达到了99.8%。CNN模型对图片的识别是非常有效的。


相关链接:

《老饼讲解-机器学习》:老饼讲解-机器学习教程-通俗易懂
《老饼讲解-神经网络》:老饼讲解-matlab神经网络-通俗易懂
《老饼讲解-神经网络》:老饼讲解-深度学习-通俗易懂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38033.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Dison夏令营 Day 04】如何用 Python 编写简单的数字猜谜游戏代码

上个周末&#xff0c;我整理了一份可以用 Python 编写的游戏列表。但为什么呢&#xff1f; 如果您是 Python 程序员初学者&#xff0c;编写有趣的游戏可以帮助您更快更好地学习 Python 语言&#xff0c;而不会被语法之类的东西所困扰。我在学习 Python 的时候曾制作过一些这样…

Hadoop-03-Hadoop集群 免密登录 超详细 3节点公网云 分发脚本 踩坑笔记 SSH免密 服务互通 集群搭建 开启ROOT

章节内容 上一节完成&#xff1a; HDFS集群XML的配置MapReduce集群XML的配置Yarn集群XML的配置统一权限DNS统一配置 背景介绍 这里是三台公网云服务器&#xff0c;每台 2C4G&#xff0c;搭建一个Hadoop的学习环境&#xff0c;供我学习。 之前已经在 VM 虚拟机上搭建过一次&…

短视频矩阵系统搭建APP源码开发

前言 短视频矩阵系统不仅有助于提升品牌影响力和营销效率&#xff0c;还能帮助企业更精准地触达目标受众&#xff0c;增强用户互动&#xff0c;并利用数据分析来持续优化营销策略。 一、短视频矩阵系统是什么&#xff1f; 短视频矩阵系统是一种通过多个短视频平台进行内容创作…

多多代播24小时值守:电商直播时代是带货爆单的关键

在电商直播盛行的今天&#xff0c;直播带货已成为品牌与消费者沟通的关键。然而&#xff0c;流量波动大&#xff0c;竞争激烈&#xff0c;使品牌面临诸多挑战。因此&#xff0c;许多品牌寻求专业代播服务&#xff0c;并特别强调24小时值守的重要性。 流量来源的不稳定性是一个显…

Linux下安装RocketMQ:从零开始的消息中间件之旅

感谢您阅读本文&#xff0c;欢迎“一键三连”。作者定会不负众望&#xff0c;按时按量创作出更优质的内容。 ❤️ 1. 毕业设计专栏&#xff0c;毕业季咱们不慌&#xff0c;上千款毕业设计等你来选。 RocketMQ是一款分布式消息中间件&#xff0c;具有高吞吐量、低延迟、高可用性…

本末倒置!做660+880一定要避免出现这3种情况!

每年都有不少人做过660题&#xff0c;但是做过之后&#xff0c;并没有真正理解其中的题目&#xff0c;所以做过之后效果也不好&#xff01;再去做880题&#xff0c;做的也会比较吃力。 那该怎么办呢&#xff0c;不建议你继续做880题&#xff0c;先把660给吃透再说。 接下来给…

PostgreSQL使用教程

安装 PostgreSQL 您可以从 PostgreSQL 官方网站下载适合您操作系统的安装程序&#xff0c;并按照安装向导进行安装。 启动数据库服务器 安装完成后&#xff0c;根据您的操作系统&#xff0c;通过相应的方式启动数据库服务器。 连接到数据库 可以使用命令行工具&#xff08;如 p…

Objective-C使用块枚举的细节

对元素类型的要求 在 Objective-C 中&#xff0c;NSArray 只能存储对象类型&#xff0c;而不能直接存储基本类型&#xff08;例如 int&#xff09;。但是&#xff0c;可以将基本类型封装在 NSNumber 等对象中&#xff0c;然后将这些对象存储在 NSArray 中。这样&#xff0c;en…

Maven编译打包时报“PKIX path building failed”异常

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 方法11.报错信息2.InstallCert.java3.生成证书文件 jssecacerts4.复制 jssecacerts 文件5. 然后重启Jenkins 或者maven即可 方法21.下载证书2. 导入证书执行keytool…

7.优化算法之分治-快排归并

0.分治 分而治之 1.颜色分类 75. 颜色分类 - 力扣&#xff08;LeetCode&#xff09; 给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums &#xff0c;原地对它们进行排序&#xff0c;使得相同颜色的元素相邻&#xff0c;并按照红色、白色、蓝色顺序排列。 我们使用整数…

Elasticsearch (1):ES基本概念和原理简单介绍

Elasticsearch&#xff08;简称 ES&#xff09;是一款基于 Apache Lucene 的分布式搜索和分析引擎。随着业务的发展&#xff0c;系统中的数据量不断增长&#xff0c;传统的关系型数据库在处理大量模糊查询时效率低下。因此&#xff0c;ES 作为一种高效、灵活和可扩展的全文检索…

springboot系列八: springboot静态资源访问,Rest风格请求处理, 接收参数相关注解

文章目录 WEB开发-静态资源访问官方文档基本介绍快速入门注意事项和细节 Rest风格请求处理基本介绍应用实例注意事项和细节思考题 接收参数相关注解基本介绍应用实例PathVariableRequestHeaderRequestParamCookieValueRequestBodyRequestAttributeSessionAttribute ⬅️ 上一篇…

微服务-网关Gateway

个人对于网关路由的理解&#xff1a; 网关就相当于是一个项目里面的保安&#xff0c;主要作用就是做一个限制项。&#xff08;zuul和gateway两个不同的网关&#xff09; 在路由中进行配置过滤器 过滤器工厂&#xff1a;对请求或响应进行加工 其中filters&#xff1a;过滤器配置…

摸鱼大数据——Spark基础——Spark环境安装——PySpark搭建

三、PySpark环境安装 PySpark: 是Python的库, 由Spark官方提供. 专供Python语言使用. 类似Pandas一样,是一个库 Spark: 是一个独立的框架, 包含PySpark的全部功能, 除此之外, Spark框架还包含了对R语言\ Java语言\ Scala语言的支持. 功能更全. 可以认为是通用Spark。 功能 P…

Golang | Leetcode Golang题解之第199题二叉树的右视图

题目&#xff1a; 题解&#xff1a; /** 102. 二叉树的递归遍历*/ func levelOrder(root *TreeNode) [][]int {arr : [][]int{}depth : 0var order func(root *TreeNode, depth int)order func(root *TreeNode, depth int) {if root nil {return}if len(arr) depth {arr a…

线性代数--行列式1

本篇来自对线性代数第一篇的行列式的一个总结。 主要是行列式中有些关键点和注意事项&#xff0c;便于之后的考研复习使用。 首先&#xff0c;对于普通的二阶和三阶行列式&#xff0c;我们可以直接对其进行拆开&#xff0c;展开。 而对于n阶行列式 其行列式的值等于它的任意…

C++特殊类设计单例模式...

文章目录 请设计一个类&#xff0c;不能被拷贝请设计一个类&#xff0c;只能在堆上创建对象请设计一个类&#xff0c;只能在栈上创建对象请设计一个类&#xff0c;不能被继承请设计一个类&#xff0c;只能创建一个对象(单例模式)单例模式&#xff1a;饿汉模式&#xff1a;懒汉模…

代发考生战报:6月25号 南宁 HCIP-Transmission传输 H31-341考试884分通过

代发考生战报&#xff1a;6月25号 南宁 HCIP-Transmission传输 H31-341考试884分通过 &#xff0c;今天我和同事两个人去考的&#xff0c;我考试遇到1个新题&#xff0c;他遇到两个新题&#xff0c;客服提供的题库很稳定&#xff0c;全覆盖了&#xff0c;轻松通过&#xff0c;考…

【语言模型】Xinference的部署过程

一、引言 Xinference&#xff0c;也称为Xorbits Inference&#xff0c;是一个性能强大且功能全面的分布式推理框架&#xff0c;专为各种模型的推理而设计。无论是研究者、开发者还是数据科学家&#xff0c;都可以通过Xinference轻松部署自己的模型或内置的前沿开源模型。Xinfe…

pikachu靶场 利用Rce上传一句话木马案例(工具:中国蚁剑)

目录 一、准备靶场&#xff0c;进入RCE 二、测试写入文件 三、使用中国蚁剑 一、准备靶场&#xff0c;进入RCE 我这里用的是pikachu 打开pikachu靶场&#xff0c;选择 RCE > exec "ping" 测试是否存在 Rce 漏洞 因为我们猜测在这个 ping 功能是直接调用系统…