神经网络---卷积神经网络CNN

一、从前馈神经网络到CNN

前馈神经网络(Feedforward Neural Networks)是最基础的神经网络模型,也被称为多层感知机(MLP)。

它由多个神经元组成,每个神经元与前一层的所有神经元相,形成一个“全连接”的结构。每个神经元会对其输入数据进行线性变换(通过权重矩阵),然后通过一个非线性函数(如ReLU或Sigmoid)进行激活。这就是前馈神经网络的基本操作。

然而前馈神经网络也会产生问题:如果加深网络层,全连接神经网络随着隐藏层和隐藏节点的增加,参数的增加量是十分巨大的。正是因为这些大量的参数,使得神经网络模型有着极强的学习能力,导致计算困难。

很大程度上,是CNN的基本组成部分与前馈神经网络有很紧密的关联,甚至可以说,CNN就是一种特殊的前馈神经网络。

这两者的主要区别在于,CNN在前馈神经网络的基础上加入了卷积层和池化层(下边会讲到),以便更好地处理图像等具有空间结构的数据。

CNN在前馈神经网络的基础上加入了卷积层和池化层

所谓深度学习,不就是层数比较多的神经网络嘛,那为什么不能使用一种几十层的前馈神经网络,而要设计一个所谓的卷积神经网络呢?接下来我们来学习卷积神经网络模型。

二、卷积神经网络(CNN)介绍

卷积神经网络(CNN)是一种高效的深度学习架构,用于图像和视频识别、分类等任务。CNN通过局部连接权重共享自动特征提取等特点减少模型复杂度并提高计算效率。它在商业领域有广泛应用,如图像识别、医学图像分析、人脸识别等。Python中的深度学习框架如TensorFlow、Keras等.

CNN的网络结构分为3部分:输入层,隐藏层与输出层CNN的输入层是直接输入二维图像信息,这一点与传统的神经网络输入层需要输入一维向量有所不同。

隐藏层由三种网络构成 —— 卷积层(包含激活函数),池化层,全连接层

      卷积层:主要作用是提取特征,使用滤波器(卷积核),通过设定步长、深度等参数,对输入进行不同层次的特征提取。滤波器中的参数可以通过反向传播算法进行学习。

      激活函数层:主要是将卷积层的输出做一个非线性映射。常见的激活函数包括sigmoid,tanh,Relu等

      池化层:对卷积层提取的特征进行降维,主要是用于参数量压缩。可以减轻过拟合情况。常见的有平均池化和最大池化,不包含需要学习的参数。

     全连接层:主要是指两层网络,所有神经元之间都有权重连接。常见用于网络的最后一层,用于计算类别得分。

     输出层:输出层位于全连接层之后,对从全连接层得到的特征进行分类输出。

1、卷积层

卷积本质来说就是通过卷积核滑动遍历一幅图像像素矩阵,其权重w与对应位置像素相乘再相加的操作这里就涉及到几个概念:卷积核、步长、填充。

举个例子说明:比如有一张猫的图像,这里猫眼睛、猫脚、猫尾巴之间的距离是很大的,看猫眼睛的时候并不会影响到猫尾巴,所以图像具有局部相关性,在特征提取的时候专门设计找猫眼睛的卷积核在这个图像中找猫眼睛,专门找猫脚的卷积核来找猫脚,专门找猫尾巴的卷积核来找猫尾巴。

 (1)卷积核(Kernel) 

卷积核也称作滤波器,是用来滑动的窗口,卷积核尺寸通常为3×3×c,3×3是卷积核的大小,c是卷积核的通道数。注意,这里的c和这层的输出的通道是一样的,比如224×224×3的图像,用3×3×c的卷积,那么这里的c就是3。卷积核的每个小方格上都有一个权重w,这些权重是可学习参数,训练就是要找到最优的参数.

接下来我们以灰度图像为例(通道c=1):

左边矩阵容易被理解为一张图片,中间的这个被理解为卷积核,右边的图片我们可以理解为另一张图片。

第一步计算:

第二步计算:

第一行计算完成:

接下来为了得到下一行的元素,现在把蓝色块下移:

最后我们得到一个卷积计算结果为:

下图展示了使用两个三通道滤波器从三通道(RGB)图像中生成两个卷积输出的详细过程。

以上就是三维卷积计算方法。这里面体现了局部连接权值共享:每层神经元只和上一层部分神经元相连(卷积计算规则),且filter的权值对于上一层所有神经元都是一样的。对于包含两个3*3*3的fitler的卷积层来说,其参数数量仅有(3*3*3+1)*2=56个,且参数数量与上一层神经元个数无关。与全连接神经网络相比,其参数数量大大减少了。

2、步长

步长(stride)是卷积操作中的一个重要参数,它决定了卷积核在输入数据上移动的间隔。步长的选择直接影响卷积操作后输出特征图的大小和信息保留程度,是神经网络卷积操作的关键参数。步长的大小可以是正整数,通常为1、2、3等。

3、填充(padding)

在标准卷积中,存在两问题(1)每次卷积都会缩小图像的尺寸,图像会失去原来的形状;(2)在滑动时位于中间的像素会被重复滑动到,而位于边缘的像素就只被滑动一次,这意味着卷积过程丢掉了图像边缘的许多信息,因此,要解决这些问题,可以使用padding零填充,这样,在滑动时的卷积核可以允许原始边缘像素位于其中心,边缘有值的像素也能被计算到。如下图是padding=1的零填充。

图像填充操作

图像填充后卷积操作图

图像经过卷积得到的特征图大小是由卷积核大小、步长、padding共同决定的,其计算公式为 

2、池化层 (Pooling )

随着模型网络不断加深,卷积核越来越多,要训练的参数还是很多,而且直接拿卷积核提取的特征直接训练也容易出现过拟合的现象。CNN使用的另一个有效的工具被称为“池化(Pooling)”出现并解决了上面这些问题,为了有效地减少计算量,池化就是将输入图像进行缩小,减少像素信息,只保留重要信息;为了有效地解决过拟合问题,池化可以减少数据,但特征的统计属性仍能够描述图像,而由于降低了数据维度,可以有效地避免过拟合。

池化的定义:对不同位置区域提取出有代表性的特征(进行聚合统计,例如最大值、平均值等),这种聚合的操作就叫做 池化,池化的过程通常也被称为 特征映射 的过程(特征降维)。听起来很高深,其实简单地说就是下采样。

池化主要有两种, 最大值池化(Max Pooling)和 平均值池化(Average pooling),最大池化是对局部窗口的值取最大,平均池化是对局部窗口的值取平均。

详细的池化过如下:

池化核的大小:3×3

池化步长:1

池化类型 : 最大值池化(Max Pooling)

池化层的主要作用就是对非线性激活函数后的结果进行降采样,以减少参数的数量,避免过拟合,并提高模型的处理速度。

3、Flatten层&全连接层(Full Connected Layer)

Flatten:将最后的二维特征图打平成一维。

全连接层:对提取的特征进行非线性组合以得到输出。

到这一步,其实我们的一个完整的“卷积部分”就算完成了,如果想要叠加层数,一般也是叠加“Conv-MaxPooing",通过不断的设计卷积核的尺寸,数量,提取更多的特征,最后识别不同类别的物体。做完Max Pooling后,我们就会把这些数据“拍平”,丢到Flatten层,然后把Flatten层的output放到full connected Layer里,采用softmax对其进行分类。

一个完整的CNN结构

4、CNN网络的实战

import torch
import torch.nn as nn
from torchvision import transforms
from torchvision import datasets #torchvision计算机视觉库
from torch.utils.data import DataLoader
import torch.nn.functional as f   #使用functional中的ReLu激活函数
import torch.optim as optim
import matplotlib.pyplot as plt# 准备数据集
batch_size = 64
#神经网络希望输入的数值较小,最好在0-1之间,所以需要先将原始图像(0-255的灰度值)转化为图像张量(值为0-1)
#仅有灰度值->单通道   RGB -> 三通道 读入的图像张量一般为W*H*C (宽、高、通道数) 在pytorch中要转化为C*W*H
transform = transforms.Compose([#将数据转化为图像张量transforms.ToTensor(),# 进行归一化处理,切换到0-1分布 (均值, 标准差)transforms.Normalize(mean=[0.1307,],std=[0.3081,])
])
train_dataset = datasets.MNIST(root="../mnist_data/",train=True,transform=transform,download=True)
test_dataset = datasets.MNIST(root="../mnist_data/",train=False,transform=transform,download=True)
"""
for step,(b_x,b_y) in enumerate (train_dataset):if step>0:break
batch_x=b_x.squeeze(1).numpy();#将思维张量移除第一维度,并转化为numpy数组
batch_y=b_y.numpy()
class_label=train_dataset.classes;
print(class_label.classes)
"""#将自定义的dataset根据batch size的大小、是否shuffle等选项封装成一个batch size大小的tensor,后续就只需要在包装成variable即可作为模型的输入进行训练。
train_dataloader = DataLoader(dataset=train_dataset,batch_size=batch_size,shuffle=True)
test_dataloader = DataLoader(dataset=test_dataset,batch_size=batch_size,shuffle=True)# 网络模型
class Model(nn.Module):#构造函数,用于初始化对象的属性def __init__(self):super(Model, self).__init__()# 两个卷积层self.conv1 = nn.Conv2d(1,10,kernel_size=5) #1为in_channels 10为out_channels,卷积核大小是5X5的self.conv2 = nn.Conv2d(10,20,kernel_size=5)# 池化层self.pooling = nn.MaxPool2d(2)#2为最大池化窗口的大小# 全连接层 320 = 20 * 4 * 4self.fc = nn.Linear(320,10)def forward(self,x):# 先从x数据维度中得到batch_sizebatch_size = x.size(0)# 卷积层->池化层->激活函数x = f.relu(self.pooling(self.conv1(x)))x = f.relu(self.pooling(self.conv2(x)))x = x.view(batch_size, -1)  # 将数据展开,为输入全连接层做准备x = self.fc(x)return x# x = f.relu(self.pooling(self.conv1(x)))# x = f.relu(self.pooling(self.conv2(x)))# x = x.view(x.size(0), -1)# x = self.fc(x)# return xmodel = Model()
#在这里加入两行代码,将数据送入GPU中计算!!!
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
model.to(device) #将模型的所有内容放入cuda中
# 优化器和损失函数
criterion = nn.CrossEntropyLoss()
#神经网络已经逐渐变大,需要设置冲量momentum=0.5
optimizer = optim.SGD(model.parameters(),lr = 0.01,momentum=0.5)# 训练
epoch_list = []
def train(epoch):running_loss = 0.0epoch_list.append(epoch+1)# for epoch in range(10):for i, data in enumerate(train_dataloader, 0):input, target = datainput, target = input.to(device),target.to(device)y_pred = model(input)   #前向传播loss = criterion(y_pred, target)  #计算损失# print(i+1,epoch+1,loss.item())optimizer.zero_grad()loss.backward() #反向传播,计算梯度optimizer.step() #更新权重running_loss += loss.item()if i % 300 == 299:print("{} {} loss:{:.3f}".format(epoch + 1, i + 1, running_loss / 300))running_loss = 0.0
# 测试
accuracy_list = []
def test():total = 0correct = 0#表明当前计算不需要反向传播,使用之后,强制后边的内容不进行计算图的构建with torch.no_grad():for i,data in enumerate(test_dataloader,0):input,target = datainput, target = input.to(device), target.to(device)y_pred = model(input)predicted = torch.argmax(y_pred.data,dim=1)  #找打最大概率的类别total += target.size(0)correct += (predicted==target).sum().item()accuracy = correct/totalaccuracy_list.append(accuracy)print("Accuracy on test set:{:.2f} %".format(100*correct/total))if __name__ == '__main__':for epoch in range(10):train(epoch)test()
#画图
plt.plot(epoch_list,accuracy_list)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.grid()
plt.show()

如果大家对神经网络知识感兴趣可以关注我的微信公众号,里面会分享一些知识干货。

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

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

相关文章

Ubuntu24.04 LTS安装中文输入法

前言 最近,windows玩没了,一怒之下决定换一个操作系统,当然就是最新的Ubuntu24.04 LTS.,其中魔法和咒语(汉语)是inux遇到的第一大难关,我权限不够教不了魔法,但我可以教你咒语(๑•…

大模型之路,从菜鸟到模型大师只需要一步

前言: 在这个数据爆炸的时代,大模型技术正以前所未有的速度发展。从自然语言处理到计算机视觉,从智能推荐到自动驾驶,大模型正逐渐渗透到我们生活的方方面面。那么,如何从菜鸟成长为模型大师呢?本文将为你…

1.8k Star!RAGApp:在任何企业中使用 Agentic RAG 的最简单方法!

原文链接:(更好排版、视频播放、社群交流、最新AI开源项目、AI工具分享都在这个公众号!) 1.8k Star!RAGApp:在任何企业中使用 Agentic RAG 的最简单方法! 🌟在任何企业中使用 Agent…

9.Halcon3D点云力矩求解-平面拟合用法

1.实现效果 我们在使用3d相机对产品进行扫描生成点云的时候,由于安装问题,所以我们不可能保证每次产品扫描出来都在坐标系中位置和姿态非常标准。 上述算法描述的就是在某一个维度或者某几个维度上将点云数据和坐标系对齐; 至于怎么对齐,如何实现就是今天的内容。 本人能…

如何评价GPT-4o?GPT-4o和ChatGPT4.0的区别是啥呢?

如何评价GPT-4o? GPT-4o代表了人工智能领域的一个重要里程碑,它不仅继承了GPT-4的强大智能,还在多模态交互方面取得了显著进步。以下是几个方面的分析: 技术特点 多模态交互能力:GPT-4o支持文本、音频和图像的任意组合输入与输出…

vue3组件通信与props

title: vue3组件通信与props date: 2024/5/31 下午9:00:57 updated: 2024/5/31 下午9:00:57 categories: 前端开发 tags: Vue3组件Props详解生命周期数据通信模板语法Composition API单向数据流 Vue 3 组件基础 在 Vue 3 中,组件是构建用户界面的基本单位&#…

判断自守数-第13届蓝桥杯选拔赛Python真题精选

[导读]:超平老师的Scratch蓝桥杯真题解读系列在推出之后,受到了广大老师和家长的好评,非常感谢各位的认可和厚爱。作为回馈,超平老师计划推出《Python蓝桥杯真题解析100讲》,这是解读系列的第75讲。 判断自守数&#…

蓝桥杯高频考点-与日期相关的题目

文章目录 前言1. 如何枚举合法日期1.1 预存每个月的天数1.2 封装一个判断日期是否合法的函数1.3 枚举日期并判断日期是否合法 2. 判断日期是否为回文日期2.1 将日期当作字符串进行处理2.2 将日期当作一个8位数进行处理 3. 给定初始日期,计算经过n天后对应的日期3.1 …

职场中,那些35岁以上的测试猿到底去哪了?

🔥 交流讨论:欢迎加入我们一起学习! 🔥 资源分享:耗时200小时精选的「软件测试」资料包 🔥 教程推荐:火遍全网的《软件测试》教程 📢欢迎点赞 👍 收藏 ⭐留言 &#x1…

使用KEPServer连接欧姆龙PLC获取对应标签数据(标签值类型改为字符串型)

1.创建通道(通道),(选择对应的驱动,跟当前型号PLC型号对应)。 2.创建设备,(填入IP地址以及欧姆龙的默认端口号:44818) 3.创建对应的标签。这里关键讲诉下字…

AI 网页解锁器,用于网页抓取一切 | 最快的验证码解决服务

想象一下,解锁互联网的全部潜力,数据自由流动,没有任何障碍阻挡你获取所需信息。在网络爬虫的世界里,这个梦想常常会遇到障碍:CAPTCHA和反机器人措施,这些措施旨在保护网站免受自动化访问的侵害。但如果有一…

【VSCode】快捷方式log去掉分号

文章目录 一、引入二、解决办法 一、引入 我们使用 log 快速生成的 console.log() 都是带分号的 但是我们的编程习惯都是不带分号,每次自动生成后还需要手动删掉分号,太麻烦了! 那有没有办法能够生成的时候就不带分号呢?自然是有…

uni-app的网络请求库封装及使用(同时支持微信小程序)

其实uni-app中内置的uni.request()已经很强大了,简单且好用。为了让其更好用,同时支持拦截器,支持Promise 写法,特对其进行封装。同时支持H5和小程序环境,更好用啦。文中给出使用示例,可以看到使用变得如此…

【C++】——string模拟实现

前言 string的模拟实现其实就是增删改查,只不过加入了类的概念。 为了防止与std里面的string冲突,所以这里统一用String。 目录 前言 一 初始化和销毁 1.1 构造函数 1.2 析构函数 二 迭代器实现 三 容量大小及操作 四 运算符重载 4.1 bool…

Unity【入门】脚本基础

Unity脚本基础 文章目录 1、脚本基本规则1、创建规则2、MonoBehavior基类3、不继承MonoBehavior的类4、执行的先后顺序5、默认脚本内容 2、生命周期函数1、概念2、生命周期函数有哪些3、生命周期函数支持继承多态 3、Inspector窗口可编辑的变量4、Mono中的重要内容1、重要成员2…

冯喜运:5.31晚间黄金原油行情分析及尾盘操作策略

【黄金消息面分析】:周五(5月31日),最新发布的数据显示,美国4月核心PCE物价指数月率录得0.2%,低于预期(0.3%),经济学家认为,核心指数比整体指数更能反映通胀。除此之外,美…

HackTheBox-Machines--Sense

Popcorn 测试过程 1 信息收集 服务器开启80、443端口 80端口 访问 80 跳转到 443 – https://10.129.196.51/ ,该页面是 pfSense 登录界面,默认密码是: admin/pfSense,使用默认账号密码登录失败 目录扫描 ./gobuster dir -u htt…

深度神经网络——什么是线性回归?

线性回归是一种用于预测或可视化的算法 两个不同特征/变量之间的关系。 在线性回归任务中,要检查两种变量: 因变量和自变量。 自变量是独立的变量,不受其他变量的影响。 随着自变量的调整,因变量的水平将会波动。 因变量是正在研究…

三体中的冯诺依曼

你叫冯诺依曼,是一位科学家。你无法形容眼前的现态,你不知道下一次自己葬身火海会是多久,你也不知道会不会下一秒就会被冰封,你唯一知道的,就是自己那寥寥无几的科学知识,你可能会抱着他们终身,…

《QT实用小工具·六十九》基于QT开发的五子棋AI游戏

1、概述 源码放在文章末尾 该项目实现了五子棋对战AI,可以享受和AI下棋的快乐,项目实现思路如下: 博弈树 ●Alpha-Beta剪枝(性能提高较大) ●启发式搜索(性能提高较大) ●落子区域限制(性能提高较大) ●Zobrist哈希(性能小幅提升) ●Qt…