CNN神经网络

CNN

    • 一 基本概述
    • 二 基础知识
    • 三 经典案例

今天和大家聊聊人工智能中的神经网络模型相关内容。神经网络内容庞大,篇幅有限本文主要讲述其中的CNN神经网络模型和一些基本的神经网络概念。

一 基本概述

深度学习(Deep Learning)特指基于深层神经网络模型和方法的机器学习。它是在统计机器学习、人工神经网络等算法模型基础上,结合当代大数据和大算力的发展而发展出来的。深度学习最重要的技术特点是具有自动提取特征的能力,所提取的特征也称为深度特征或深度特征表示,相比于人工设计的特征,深度特征的表示能力更强、更稳健。

人工神经网络(Artificial Neural Network,即ANN ),是20世纪80 年代以来人工智能领域兴起的研究热点。它从信息处理角度对人脑神经元网络进行抽象, 建立某种简单模型,按不同的连接方式组成不同的网络。

二 基础知识

卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络。是深度学习代表算法之一。

基本概念 :输入图通过卷积核得到特征图。

特征图计算公式如下,计算结果特征图是 N*N 的。
特征图计算公式

池化层:主要对特征数据降维处理,即数据稀疏化。从而减小模型,简化计算。

池化层分类

# 框架Pytorch
# kernel_size=2池化窗口大小
# stride=1步长 每次移动的像素
# padding=0 四周填充0  填充1 就代表1像素填充一圈# 最大池化层
polling1 = nn.MaxPool2d(kernel_size=2,stride=1,padding=0)
# 平均池化层
polling2 = nn.AvgPool2d(kernel_size=2,stride=1,padding=0)

三 经典案例

案例介绍:通过CNN神经网络实现图像分类.

数据集:CIFAR10

框架:Pytorch

# 测试环境
# import torch
# # 打印出正在使用的PyTorch和CUDA版本
# print(torch.__version__)
# print(torch.version.cuda)
# # 测试GPU是否生效
# print(torch.cuda.is_available())# 0.导包
# import numpy as np
import torch
import torch.nn as nn
from torchvision.datasets import CIFAR10
from torchvision.transforms import ToTensor,Compose # 数据集转化和数据增强组合
import torch.optim as optim
from torch.utils.data import DataLoader
import time
# from torchsummary import summary
# import matplotlib.pyplot as plt
# 1.构建数据集
def create_dataset():# 起初没有数据集download=True# root 最好与项目文件在同目录下# train = CIFAR10(root=r'E:\dataset\cifar10',train=True,transform=Compose([ToTensor()]),download=True)train = CIFAR10(root=r'E:\dataset\cifar10',train=True,transform=Compose([ToTensor()]),download=False)# valid = CIFAR10(root=r'E:\dataset\cifar10',train=False,transform=Compose([ToTensor()]),download=True)valid = CIFAR10(root=r'E:\dataset\cifar10',train=False,transform=Compose([ToTensor()]),download=False)# 返回数据集return train,valid
# 2.搭建卷积神经网络 (一个继承两个方法)
class ImageClassificationModel(nn.Module):# 定义网络结构def __init__(self):super(ImageClassificationModel,self).__init__()# 定义网络层:卷积层+池化层+全连接层# 第一层卷积层输入通道3和样本通道一致 ,输出通道卷积个数6可以自定义,卷积核大小3,步长1self.conv1 = nn.Conv2d(3,6,kernel_size=3,stride=1)# 优化1 加入BN层 参数等于上层的输出通道数self.bn1 = nn.BatchNorm2d(6)# 池化窗口大小2,步长2  如果是用固定的池化层,可以定义一个多次调用self.pool1 = nn.MaxPool2d(kernel_size=2,stride=2)self.conv2 = nn.Conv2d(6,16,kernel_size=3,stride=1)self.bn2 = nn.BatchNorm2d(16)self.pool2 = nn.MaxPool2d(kernel_size=2,stride=2)# 优化3 增加卷积层和核数self.conv3 = nn.Conv2d(16, 32, kernel_size=3, stride=1)self.bn3 = nn.BatchNorm2d(32)self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2, padding=1)# 全连接层# # 输入576,输出120# self.linear1 = nn.Linear(576,120)# self.linear2 = nn.Linear(120,84)# 优化3 后# mat1 (抻平层)的形状是 (16, 288),而 mat2(第1个隐藏层) 的形状是 (128, 64) 报错# 注意满足矩阵乘法要求 第二个矩阵的行等于第一个矩阵的列# 在调用 self.linear1 之前,打印 x 的形状,确保它符合预期 确保使其输入特征数与输入数据的特征数匹配。# 输入288,输出128self.linear1 = nn.Linear(288, 128)# 优化8 加入Dropout(随机失活)self.dropout1 = nn.Dropout(p=0.5)self.linear2 = nn.Linear(128, 64)self.dropout2 = nn.Dropout(p=0.5)# 优化3 增加第三个全连接隐藏层self.linear3 = nn.Linear(64, 32)self.dropout3 = nn.Dropout(p=0.5)# 输出层self.out = nn.Linear(32,10)# 定义前向传播def forward(self,x):# 优化前 卷积1+relu+池化1# 优化后 卷积1+BN+relu+池化1x = torch.relu(self.bn1(self.conv1(x)))x = self.dropout1(x)x = self.pool1(x)# 卷积2+BN+relu+池化2x = torch.relu(self.bn2(self.conv2(x)))x = self.dropout2(x)x = self.pool2(x)# 优化3 增加卷积层和核数x = torch.relu(self.bn3(self.conv3(x)))x = self.dropout3(x)x = self.pool3(x)# print(x.shape) torch.Size([2, 16, 6, 6])# [2, 16, 6, 6]即[B,C,H,w]# x.size(0) 是一个batch的大小默认为2# 展平 将特征图转成16X6X6行 1列的形式 相当于特征向量x = x.reshape(x.size(0),-1)# 全连接层# 全连接隐藏层x = torch.relu(self.linear1(x))x = torch.relu(self.linear2(x))# 优化3 增加第三个全连接隐藏层x = torch.relu(self.linear3(x))# 全连接输出层output = self.out(x)# 优化2 输出层使用softmax()激活函数# dim=1 使得softmax函数在通道(分类任务常用)这个维度上对每个元素进行归一化,使其变为概率分布,因为每个通道可以代表一个类别.# dim具体取值根据输入数据的维度来决定.注意-1表示最后一个维度,-2表示倒数第二个维度......# 例如,如果输入是一个四维张量(batch_size, channels, height, width)# dim = 0:沿着批次维度进行softmax操作。这意味着每个通道、高度和宽度上的所有批次样本会被归一化为概率分布。# dim = 1:沿着通道维度进行softmax操作。这意味着每个批次、高度和宽度上的所有通道会被归一化为概率分布。# dim = 2:沿着高度维度进行softmax操作。这意味着每个批次、通道和宽度上的所有高度会被归一化为概率分布。# dim = 3:沿着宽度维度进行softmax操作。这意味着每个批次、通道和高度上的所有宽度会被归一化为概率分布。# output = torch.softmax(self.out(x),dim=1)return output
# 3.训练函数
def train(model,train_dataset):# 构建损失函数 多分类交叉熵损失也叫做softmax损失criterion = nn.CrossEntropyLoss()# 优化器 Adamoptimizer = optim.Adam(model.parameters(),lr=0.001)# # 优化4 修改优化器为 SGD# optimizer = optim.SGD(model.parameters(),lr=0.01)# 定义训练轮数num_epoch = 25# 遍历每个轮次for epoch_idx in range(num_epoch):# 初始化数据加载器 批量 多线程的 加载管理数据 支持数据打乱# 32为每个batch的样本数量train_loader = DataLoader(train_dataset,batch_size=32,shuffle=True)# 样本数量sam_num = 0# 初始化损失值total_loss = 0.0# 第一轮训练开始时间点start_time = time.time()# 遍历测试数据集 即数据加载器 train_loader 中的每个批次数据 即每个batchfor x,y in train_loader:x = x.to(cuda)y = y.to(cuda)# 前向传播 将数据送入网络模型训练(预测)# output 对当前批次数据 x 的预测结果,形状通常是 [batch_size, num_classes]output = model(x).to(cuda)# 计算损失值# y: 当前批次数据的真实标签,形状通常是 [batch_size]# 损失函数使用的是 nn.CrossEntropyLoss(),它会计算每个样本的损失值,然后对这些损失值求平均.# loos得到一批数据(当前批次)的平均损失值,不是单个样本的损失值.loss = criterion(output,y)# 梯度归零optimizer.zero_grad()# 反向传播loss.backward()# 更新参数optimizer.step()# 每批次的平均损失值累加 获得 当前轮所有批次的平均损失值和# loss.item() 通过.item()方法取出当前批次平均损失值total_loss += loss.item()# 每批次的样本数量累加 获得 当前轮所有批次样本数和sam_num += 1# 通过每轮迭代 查看损失值下降 越接近0 说明预测值与真实值越接近 表示模型训练效果更好# total_loss/sam_num 表示当前轮所有批次的平均损失值和/当前轮所有批次样本数 得到 某1轮所有batch的平均损失值# 通过每轮耗时(单位:s)估计迭代周期# 走到这说明第一轮所有批次执行完毕 跳出内循环 开始下一轮训练print(f'epoch:第{epoch_idx +1}轮,loss:平均损失值{total_loss/sam_num},time:该轮耗时{time.time()-start_time}')# 所有轮次执行完毕 保存模型torch.save(model.state_dict(),r'E:\model\cifar10_model.pth')
# 4.模型预测函数
def test(model,valid_dataset):# 构建数据加载器dataloader = DataLoader(valid_dataset,batch_size=32,shuffle=False)# 加载模型和训练好的网络参数# 使用 torch.load 函数从指定路径加载预训练的模型参数# weights_only=True 表示只加载模型的权重参数,不加载优化器等的参数# 将加载的参数通过 load_state_dict 方法加载到当前模型中(上面训练的模型)# 完成参数加载后,模型已经准备好进行验证或测试。model.load_state_dict(torch.load(r'E:\model\cifar10_model.pth',weights_only=True))# 计算精确率# 初始化预测正确的数量total_correct = 0# 初始化样本总数量total_samples = 0# 遍历数据加载器中的每个批次batchfor x,y in dataloader:# 输入特征移动到GPUx = x.to(cuda)# 标签移动到GPUy = y.to(cuda)# 前向传播 模型预测output = model(x).to(cuda)# 获取累加的预测正确的数量# torch.argmax(output, dim=-1) 获取模型输出 output 在最后一个维度上的最大值索引,即模型对每个样本的预测类别# == y 比较预测类别与真实标签 y 是否相等,返回一个布尔张量# .sum() 对布尔张量求和,将 True 视为1,False 视为0,从而得到当前批次中预测正确的样本数量# 最后将当前批次的正确预测数量累加到total_correct 获取总数量total_correct += (torch.argmax(output,dim=-1)==y).sum()# 累加当前批次的样本数量获取总数量total_samples += len(y)# 所有批次遍历完毕 计算打印总体精确率(并保留小数点后两位)# 精确率(Precision)是分类模型性能评估的一个重要指标,用于衡量模型在所有被预测为正类的样本中,实际为正类的比例# 本代码中,total_correct 是所有类别中预测正确的样本总数,total_samples 是所有样本的总数,因此计算的是整体的精确率# 优化(未做):这个计算方式适用于二分类和多分类任务,但在多分类任务中,通常会计算每个类别的精确率,然后取平均值# 未优化精确率为0.61# 优化1:加入BN层优化精确率为0.64# 优化2:输出层加入softmax()激活函数精确率为0.61   (失败)# 优化3 增加卷积层数 卷积核数和第三层全连接隐藏层精确率为0.66  (有所提高)# 优化4 修改优化器为 SGD精确率为0.66# 优化5 轮次20修改成25精确率为0.68  (测试的最高精准率值--算是一个起点 要搞到0.80以上)# 优化6 batch_size=16 改成 batch_size=32 精确率为0.67 (下降)# 优化7 优化器SGD改回Adam精确率为0.67# 优化8 加入dropout随机失活 精确率为0.56 (下降)print(f'精确率为{total_correct/total_samples:.2f}')
# 5.main函数测试
if __name__ == '__main__':# 指定训练设备 GPU 上 cuda0cuda = torch.device('cuda:0')# 加载数据集train_dataset,valid_dataset = create_dataset()# 查看数据集类别 Pytorch封装的固定写法.class_to_idx# 数据集所有类别:{'airplane': 0, 'automobile': 1, 'bird': 2, 'cat': 3, 'deer': 4, 'dog': 5, 'frog': 6, 'horse': 7, 'ship': 8, 'truck': 9}# print(f'数据集所有类别:{train_dataset.class_to_idx}')# 数据集中图像数据# 训练集数据集:(50000, 32, 32, 3)# print(f'训练集数据集:{train_dataset.data.shape}')# 测试集数据集: (10000, 32, 32, 3)# print(f'测试集数据集:{valid_dataset.data.shape}')# 查看数据集类别数量# 把训练集的标签转化为numpy 去重 再求长度# 10# print(len(np.unique(train_dataset.targets)))# 画图# figsize=(2, 2)画布大小# dpi=200 分辨率# plt.figure(figsize=(2, 2),dpi=200)# plt.imshow(train_dataset.data[1])# plt.title(train_dataset.targets[1])# plt.show()# 实例化模型 注意把模型放到GPU上MyModel = ImageClassificationModel().to(cuda)# summary(MyModel,input_size=(3,32,32),batch_size=1) # Total params: 81,302# 训练模型# 未优化loss平均值是0.6428983346247673# 优化1 加入BN层优化loss平均值是0.5965962741136551# 优化2 输出层加入softmax()激活优化loss平均值是1.8043147380065918  (损失值升高 优化失败)# 优化3 增加卷积层数 卷积核数和第三层全连接隐藏层优化loss平均值是0.6324231018376351# 优化4 修改优化器为 SGD loss平均值是0.6910492655086518# 优化5 轮次20改成25 loss平均值是0.627374342212677# 优化6 batch_size=16 改成 batch_size=32  loss平均值是0.6959678105871722# 优化7 把优化器SGD改回Adam loss平均值是0.5132057572800192 (本次初始loss平均值是 1.4839402317848254)# 优化8 加入dropout随机失活 loss平均值是1.1519099183747652  初始值1.673698478834185train(MyModel,train_dataset)# 预测模型test(MyModel,valid_dataset)

​ 好了,以上就是今天和大家分享的内容,喜欢的小伙伴可以点赞加关注,后面会持续分享相关技术…案例介绍比较详细,如果你现在正准备学习图像识别处理相关的知识,希望对屏幕前的你有所帮助。我们下期见!

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

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

相关文章

React中事件绑定和Vue有什么区别?

1. 绑定方式 React:使用jsx语法,通过属性绑定事件。Vue:使用指令(如v-on)在模板中直接绑定事件。 2. 事件处理 React:通过合成事件系统封装原生事件,提供统一的API。Vue:直接使用…

MySQL —— MySQL基础概念与常用功能介绍

文章目录 基本概念数据类型数据类型分类 约束主键约束(PRIMARY KEY)外键约束(FOREIGN KEY)使用非空约束(not null)使用唯一性约束(UNIQUE)使用默认约束(DEFAULT&#xff…

如何在react中使用react-monaco-editor渲染出一个编辑器

一、效果展示 二、基于vite配置 1.首先安装react-monaco-editor和monaco-editor包 npm add react-monaco-editor npm i monaco-editor 2.其次创建一个单独的文件(此处是tsx、直接用app或者jsx也行) import { useState, useEffect } from react impo…

MySQL面试之底层架构与库表设计

华子目录 mysql的底层架构客户端连接服务端连接的本质,连接用完会立马丢弃吗解析器和优化器的作用sql执行前会发生什么客户端的连接池和服务端的连接池数据库的三范式 mysql的底层架构 客户端连接服务端 连接的本质,连接用完会立马丢弃吗 解析器和优化器…

【开源免费】基于Vue和SpringBoot的私人健身与教练预约管理系统(附论文)

本文项目编号 T 618 ,文末自助获取源码 \color{red}{T618,文末自助获取源码} T618,文末自助获取源码 随着信息技术和网络技术的飞速发展,人类已进入全新信息化时代,传统管理技术已无法高效,便捷地管理信息…

JVM--内存结构

目录 1. PC Register(程序计数器) 1.1 定义 1.2 工作原理 1.3 特点 1.4 应用 2.虚拟机栈 2.1定义与特性 2.2内存模型 2.3工作原理 2.4异常处理 2.5应用场景 2.6 Slot 复用 2.7 动态链接详解 1. 栈帧与动态链接 动态链接的作用&#xff1a…

Python 第三方库 PyQt5 的安装

目录 前言 PyQt5安装 不同操作系统PyQt5安装 一、Windows 系统 二、macOS 系统 三、Linux 系统(以 Ubuntu 为例) 安装 PyQt5 可能会遇到的问题 一、环境相关问题 二、依赖问题 三、网络问题 四、安装工具问题 五、运行时问题 六、环境配置问…

手机直连卫星NTN通信初步研究

目录 1、手机直连卫星之序幕 2、卫星NTN及其网络架构 2.1 NTN 2.2 NTN网络架构 3、NTN的3GPP标准化进程 3.1 NTN需要适应的特性 3.2 NTN频段 3.3 NTN的3GPP标准化进程概况 3.4 NTN的3GPP标准化进程的详情 3.4.1 NR-NTN 3.4.1.1 NTN 的无线相关 SI/WI 3.4.1.2…

【SpringBoot】什么是Maven,以及如何配置国内源实现自动获取jar包

前言 🌟🌟本期讲解关于Maven的了解和如何进行国内源的配置~~~ 🌈感兴趣的小伙伴看一看小编主页:GGBondlctrl-CSDN博客 🔥 你的点赞就是小编不断更新的最大动力 &#x1f3…

阿里斑马智行 2025届秋招 NLP算法工程师

文章目录 个人情况一面/技术面 1h二面/技术面 1h三面/HR面 20min 个人情况 先说一下个人情况: 学校情况:211本中9硕,本硕学校都一般,本硕都是计算机科班,但研究方向并不是NLP,而是图表示学习论文情况&…

力扣第 55 题 跳跃游戏

力扣第 55 题 跳跃游戏(Jump Game)。题目要求判断一个非负整数数组中,是否能够从第一个位置跳跃到最后一个位置。每个元素表示从当前位置最多可以跳跃的步数。 解题思路 我们可以用 贪心算法 来解决这个问题。贪心的核心思想是始终维护当前…

富士施乐DocuContre S2520报打开盖子A,取出纸张。代码077-900故障检修

故障描述: 一台富士施乐DocuContre S2520复印机开机报错:打开盖子A,取出纸张。代码077-900故障,用户之前经常卡纸,卡着、卡着就一直提示打开盖子A,取出纸张了;复印机屏幕提示如下图: 故障检修: 富士施乐DocuContre S2520复印机报打开盖子A,取出纸张。077-900的错误代…

【jvm】方法区常用参数有哪些

目录 1. -XX:PermSize2. -XX:MaxPermSize3. -XX:MetaspaceSize(Java 8及以后)4. -XX:MaxMetaspaceSize(Java 8及以后)5. -Xnoclassgc6. -XX:TraceClassLoading7.-XX:TraceClassUnLoading 1. -XX:PermSize 1.设置JVM初始分配的永久…

哈佛商业评论 | 项目经济的到来:组织变革与管理革新的关键

在21世纪,项目经济(Project Economy)逐步取代传统运营,成为全球经济增长的核心动力。项目已不再是辅助工具,而是推动创新和变革的重要载体。然而,只有35%的项目能够成功,显示出项目管理领域存在巨大的改进空间。本文将详细探讨项目经济的背景、项目管理的挑战,以及适应…

ES6的Iterator 和 for...of 循环

写在前面 在JavaScript中,Iterator(遍历器)是一种接口,用于遍历数据结构(如数组、对象等)中的元素。它提供了一种统一的方式来访问集合中的每个项,包括值和位置。 默认 Iterator 接口 许多内…

大数据CDP集群中ImpalaHive常见使用语法

1. SQL中设置常量 set var:pi_sysdate 20241114; Variable PI_SYSDATE set to 202411142. CDP中impala 创建内外表 #hive3.0 默认不创建事务表的配置参数 set default_transactional_typenone; create external table stg.hd_aml_mac_ip_ext (machinedate string,vc_fundacc…

【Ubuntu24.04】VirtualBox安装ubuntu-live-server24.04

目录 0 背景1 下载镜像2 安装虚拟机3 安装UbuntuServer24.044 配置基本环境5 总结0 背景 有了远程连接工具之后,似乎作为服务器的Ubuntu24.04桌面版有点备受冷落了,桌面版的Ubuntu24.04的优势是图形化桌面,是作为一个日常工作的系统来用的,就像Windows,如果要作为服务器来…

01.防火墙概述

防火墙概述 防火墙概述1. 防火墙的分类2. Linux 防火墙的基本认识3. netfilter 中五个勾子函数和报文流向 防火墙概述 防火墙( FireWall ):隔离功能,工作在网络或主机边缘,对进出网络或主机的数据包基于一定的 规则检…

STM32设计井下瓦斯检测联网WIFI加Zigbee多路节点协调器传输

目录 目录 前言 一、本设计主要实现哪些很“开门”功能? 二、电路设计原理图 1.电路图采用Altium Designer进行设计: 2.实物展示图片 三、程序源代码设计 四、获取资料内容 前言 本系统基于STM32微控制器和Zigbee无线通信技术,设计了…

「Mac玩转仓颉内测版17」PTA刷题篇8 - L1-008 求整数段和

本篇将继续讲解PTA平台上的题目 L1-008 求整数段和,通过对整数区间的求和,进一步提升Cangjie编程语言的循环操作与数学计算能力。 关键词 PTA刷题数字区间循环求和数学运算Cangjie语言 一、L1-008 求整数段和 题目描述:给定两个整数 A 和 B…