深度学习------------------卷积神经网络(LeNet)

目录

  • LeNet网络
    • 手写的数字识别
    • MNIST
    • 总结
    • 卷积神经网络(LeNet)
  • 问题

LeNet网络

在这里插入图片描述


手写的数字识别

在这里插入图片描述



MNIST

在这里插入图片描述




在这里插入图片描述

①输入的是:32×32的image
②放到一个5×5的卷积层里面(为什么是5?因为32-x+1=28,∴x=5),然后它的输出通道是6,6个通道数,高宽是28的输出。
③用一个Pooling层,2×2的Pooling层,就把28×28变成14×14了,通道数没变还是6。
④接下来又是一个卷积层,这个卷积层仍然是一个5×5的,(14-x+1=10,∴x=5),然后通道数由6变成16。
⑤之后再接一个Pooling层,高宽减半,通道数不变。
⑥然后把它拉成一个向量,输入到一个全连接层,第一个全连接是一个120,第二个是84,最后一个是高斯层。得到10个数字。

两个卷积层,两个池化层,两个全连接层,最后一个输出层




总结

    ①LeNet是早期成功的神经网络

    ②先使用卷积层来学习图片空间信息

    ③然后使用全连接层来转换到类别空间




卷积神经网络(LeNet)

LeNet(LeNet-5)由两个部分组成:卷积编码器全连接层密集块

import torch
from torch import nnclass Reshape(torch.nn.Module):def forward(self, x):return x.view(-1, 1, 28, 28)  # 批量数自适应得到,通道数为1,图片为28X28net = torch.nn.Sequential(# 将1×28×28的图片放到第一个卷积层里面,输入通道是1,输出通道是6,卷积核的尺寸是5×5,填充是2×2# 为了得到非线性,在卷积后面加了sigmoid激活函数Reshape(), nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(),# 用均值池化层,步长为2nn.AvgPool2d(2, stride=2),# 卷积层输入是6,输出是16,kernel不变,然后在使用激活函数nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),# 在使用一个均值池化层,因为卷积层出来是一个4D的,把最后的通道数、高和宽变为一个一维的向量输入到多层感知机nn.AvgPool2d(kernel_size=2, stride=2), nn.Flatten(),nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),nn.Linear(120, 84), nn.Sigmoid(),nn.Linear(84, 10))# 从区间 [0, 1) 上的均匀分布中随机抽取的浮点数。参数分别代表批量大小、通道数、高度和宽度
X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
# 对每一层进行迭代
for layer in net:X = layer(X)print(layer.__class__.__name__, 'output shape:\t', X.shape)  # 上一层的输出为这一层的输入

结果:
在这里插入图片描述

经过卷积层和激活函数以及平均池化层为什么高度和宽度减半?

在卷积神经网络中,池化层(如AvgPool2d)用于减少数据的空间维度(即高度和宽度),从而减少计算量和参数数量,同时帮助网络学习到空间层次上的抽象特征。

AvgPool2d层的kernel_size(池化窗口大小)和stride(步长)都被设置为2。这意味着在每个2x2的区域内,池化操作会计算这四个值的平均值,并将结果作为该区域的输出。由于步长也是2,这意味着在水平和垂直方向上,每次池化操作都会跳过两个像素(或特征),因此输出特征图的高度和宽度都会减半。

例:有一个4x4的输入特征图

在这里插入图片描述

应用一个AvgPool2d(kernel_size=2, stride=2)层后,输出特征图将会是:

(1+2+5+6)/ 4 = 3.5
(3+4+7+8)/ 4 = 5.5
(9+10+13+14)/ 4 = 11.5
(11+12+15+16)/ 4 = 13.5

即:
3 5
11 13

输出特征图的大小从4x4变为了2x2,高度和宽度都减半了。故上述减半同理。



LeNet在Fashion-MNIST数据集上的表现

batch_size = 256
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size=batch_size)




要用GPU(CPU也是能跑的,LeNet的是CPU唯一能跑的网络)

# 接受三个参数:net(模型),data_iter(数据集迭代器),以及可选的device(设备,默认为None)
def evaluate_accuracy_gpu(net, data_iter, device=None): #@save"""使用GPU计算模型在数据集上的精度"""# 检查net是否是nn.Module的实例if isinstance(net, nn.Module):net.eval()  # 设置为评估模式# 如果device参数没有被明确指定(即None),则通过获取模型参数的第一个元素的设备来确定device。#这确保了模型和数据将被发送到相同的设备上(CPU或GPU)。if not device:device = next(iter(net.parameters())).device# 创捷累加器,两个参数分别代表正确预测的数量,总预测的数量metric = d2l.Accumulator(2)# 使用torch.no_grad()上下文管理器来关闭梯度计算。在评估模型时,我们不需要计算梯度,这可以节省内存和计算资源。with torch.no_grad():# 每次迭代获取一批数据X和对应的标签y。for X, y in data_iter:# 检查X是否是列表。if isinstance(X, list):# BERT微调所需的(之后将介绍)# 如果是列表,则将列表中的每个元素都发送到device上。X = [x.to(device) for x in X]# 如果不是列表,则直接将X发送到device上。else:X = X.to(device)# 将标签y也发送到device上,以确保模型输入和标签都在同一设备上。y = y.to(device)# 计算当前批次数据的准确率,并将该准确率和当前批次的总样本数(y.numel())累加到metric中metric.add(d2l.accuracy(net(X), y), y.numel())return metric[0] / metric[1]



为了使用GPU,我们还需要一点小改动。与之前不同,在进行正向和反向传播之前,我们需要将每一小批量数据移动到我们指定的设备(例如GPU)上。

训练函数train_ch6将实现多层神经网络,因此我们将主要使用高级API。以下训练函数假定从高级API创建的模型作为输入,并进行相应的优化。使用Xavier随机初始化模型参数。与全连接层一样,我们使用交叉熵损失函数小批量随机梯度下降

#@save
def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):"""用GPU训练模型(在第六章定义)"""def init_weights(m):# 如果是全连接层和卷积层的话,就使用Xavier均匀初始化if type(m) == nn.Linear or type(m) == nn.Conv2d:nn.init.xavier_uniform_(m.weight)# 应用初始化权重到模型的所有层  net.apply(init_weights)# 打印训练设备print('training on', device)# 将模型移至指定设备 net.to(device)# 设置优化器,使用SGD(随机梯度下降)optimizer = torch.optim.SGD(net.parameters(), lr=lr)# 设置损失函数为交叉熵损失loss = nn.CrossEntropyLoss()# 初始化动画器,用于可视化训练过程animator = d2l.Animator(xlabel='epoch', xlim=[1, num_epochs],legend=['train loss', 'train acc', 'test acc'])# 初始化计时器和获取训练迭代器的长度(即总批次数) timer, num_batches = d2l.Timer(), len(train_iter)# 训练循环for epoch in range(num_epochs):# 初始化用于训练损失之和,训练准确率之和,样本数metric = d2l.Accumulator(3)# 设置模型为训练模式 net.train()# 遍历训练迭代器中的每个批次for i, (X, y) in enumerate(train_iter):timer.start()optimizer.zero_grad()# 将数据和标签移至指定设备 (GPU)X, y = X.to(device), y.to(device)# 前向传播 y_hat = net(X)# 计算损失  l = loss(y_hat, y)# 反向传播l.backward()# 迭代更新参数optimizer.step()# 在不计算梯度的情况下计算准确率和累积损失、准确率、样本数with torch.no_grad():metric.add(l * X.shape[0], d2l.accuracy(y_hat, y), X.shape[0])timer.stop()# 计算当前批次的训练损失和准确率train_l = metric[0] / metric[2]train_acc = metric[1] / metric[2]# 如果当前批次是每5个批次的最后一个或最后一个批次,则更新动画器if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:animator.add(epoch + (i + 1) / num_batches,(train_l, train_acc, None))# 在每个epoch结束时,评估测试集上的准确率test_acc = evaluate_accuracy_gpu(net, test_iter)# 更新动画器以显示测试集准确率animator.add(epoch + 1, (None, None, test_acc))# 打印训练结束时的训练损失、训练准确率和测试准确率  print(f'loss {train_l:.3f}, train acc {train_acc:.3f}, 'f'test acc {test_acc:.3f}')# 打印每秒处理的样本数和训练设备print(f'{metric[2] * num_epochs / timer.sum():.1f} examples/sec 'f'on {str(device)}')

训练和评估LeNet-5模型

lr, num_epochs = 0.9, 10
train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

结果:

在这里插入图片描述




问题

为什么view而不用reshape呢?
本质上没什么区别,唯一不一样的是view对数据的构造不会发生变化,reshape可以对数据进行一些copy

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

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

相关文章

计算机毕业设计PySpark+Flask bilibili弹幕情感分析 B站视频数据可视化 B站爬虫 机器学习 深度学习 NLP自然语言处理 大数据毕业设计

### 开题报告:基于PySpark和Flask的B站弹幕情感分析系统 #### 一、研究背景 在网络视频平台的用户互动中,弹幕(Danmaku)作为一种实时评论的形式,已经成为观众表达观点和情感的重要方式。尤其是在B站(哔哩…

MySQL 数据库管理

在 MySQL 中,数据库管理是非常基础但又至关重要的技能。无论是创建新的数据库、选择当前使用的数据库,还是查看数据库的相关信息,这些操作都是日常数据库管理中不可或缺的一部分。本文将详细介绍 MySQL 数据库管理的基本操作,包括…

Go Roadmap-Basics中文笔记

Go Roadmap-Basics 地址:https://roadmap.sh/golang 简介:Github star No.6 学习路线 Go 中译版 Learn the Basics Go特点:静态类型,运行速度快,编译语言,编译速度快,自动垃圾回收&#xff…

【GH】【EXCEL】P4: Chart

文章目录 data and chartdonut chart (radial chart)Radial Chart bar chartBar Chart line chartLine Chart Scatter ChartScatter Chart Surface ChartSurface Chart Chart DecoratorsChart Decorators Chart GraphicsChart Graphics data and chart donut chart (radial cha…

C语言04--数组超详解

1.基本概念 逻辑:一次性定义多个相同类型的变量,并存储到一片连续的内存中语法: 数据类型 数组名字 [ 数据的量 ] ; 示例: int a[5]; int Num ; 语法释义: a 是数组名,即这片连续内存的名称[5] …

一文入门:使用 Python的requests 库

简介 requests 是 Python 中一个简单易用的 HTTP 库,用于发送各种 HTTP 请求。它建立在 Python 标准库 urllib 之上,提供了更人性化的接口。 安装 requests 库 在开始之前,确保你已经安装了 requests 库。如果还没有安装,可以通…

基于WEB的旅游推荐系统设计与实现

TOC springboot280基于WEB的旅游推荐系统设计与实现 第1章 绪论 1.1选题动因 当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔…

(七)Flink Watermark

Flink 的 Watermark 是用来标识数据流中的一个时间点。Watermark 的设计是为了解决乱序数据处理的问题,尤其是涉及到多个分区的 Kafka 消费者时。在 Watermark 的作用下,即使某些数据出现了延迟到达的情况,也不会导致整个处理流程的中断。此外,Watermark 还能防止过期的数据…

五、2 移位操作符赋值操作符

1、移位操作符 2、赋值操作符 “ ”赋值,“ ”判断是否相等 1)连续赋值 2)复合赋值符

驾驭时间之舟:SQL中时序数据处理的深度探索

标题:驾驭时间之舟:SQL中时序数据处理的深度探索 在数据的长河中,时间序列数据以其独特的流动性和连续性,记录着世界的每一次脉动。SQL作为数据查询的通用语言,在处理时序数据时,也展现出了其独特的魅力和…

VS Code开发C#(.NET)之快速入门

本篇快速介绍在VS Code中开发C#的完整说明和示例: 环境准备 安装VS Code: 前往Visual Studio Code官网 下载并安装VS Code。 安装.NET SDK: C#是基于.NET框架的,因此需要安装 .NET SDK。 前往 .NET官网 下载并安装适用于操…

每天一个数据分析题(四百九十一)- 主成分分析与因子分析

因子载荷矩阵是主成分载荷矩阵()的结果 A. 最小方差斜交旋转 B. 最大方差斜交旋转 C. 最小方差正交旋转 D. 最大方差正交旋转 数据分析认证考试介绍:点击进入 题目来源于CDA模拟题库 点击此处获取答案 数据分析专项练习题库 内容涵盖…

成为Python砖家(4): 装饰器的简单理解

第一次理解 Python 中的装饰器(decorator),是Python中一个非常强大的工具,它是一个返回函数的函数。 上面这个定义很简洁,但是没说清楚。 第二次理解 装饰器,是一个接收函数 func、返回封装后的函数 wr…

编译器揭秘

从上世纪50年代开始,编程语言五花八门,编译器和解释器层出不穷。此处只列出常见编程语言的编译器和解释器信息,不常见的编程语言有单独文章介绍。 C/C cc 此处代表Unix C编译器,其他平台可能借用cc软链接到真正的C编译器。MSVC 微…

【生日视频制作】路虎劳斯莱斯中控改名字AE模板修改文字软件生成器教程特效素材【AE模板】

路虎劳斯莱斯中控改名字生日视频制作教程AE模板改文字软件特效 怎么如何做的【生日视频制作】路虎劳斯莱斯中控改名字AE模板修改文字软件生成器教程特效素材【AE模板】 生日视频制作步骤: 安装AE软件下载AE模板把AE模板导入AE软件修改图片或文字渲染出视频

Element-UI Table实现列表筛选数据及列表嵌套选择框

VUE 框架在 Element UI 的基础上,Table 组件中实现了列表数据的修改功能,支持单选和多选功能,并且列表具备筛选功能。样式如图所示。 功能介绍 点击table列名实现筛选查询功能相关性判断点击列表中的正方形实现选择框功能,同时修…

Qt5 编译 Qt creator 源码中的 designer 模块

文章目录 下载 Qt Creator 源码 下载 Qt Creator 源码 Github: https://github.com/qt/qttools 笔记打算用 Qt 5.12.12 来编译 qt creator-designer 所以笔者下载的是 tag - 5.12.12 ,解压后如下,先删除多余的文件,后续还要删除更多文件方便…

Rivian暂停亚马逊送货车生产,特斯拉Roadster再引关注

Rivian遭遇供应链挑战,暂停亚马逊送货车生产 电动汽车制造商Rivian近期宣布,由于零部件短缺,已暂停为零售巨头亚马逊生产商业送货车。这一决定标志着Rivian在应对供应链挑战方面遭遇了最新挫折。作为Rivian的最大投资者,亚马逊持有…

anaconda学习笔记:复制anaconda的base环境

在anaconda的图形界面中,新建环境,可以看到,默认的包只有几个(这里是10个),像常用的numpy、pandas等等都没有,在使用过程中还需要再次安装。 而base环境有几百个(325个)这…

【Java 数据结构】PriorityQueue介绍

优先级队列 回顾二叉树堆堆是什么堆的实现初始化堆的创建向下调整建堆复杂度插入向上调整建堆复杂度删除 PriorityQueue类介绍PriorityQueue是什么PriorityQueue使用构造方法常用方法 PriorityQueue源码介绍Top-K问题 回顾二叉树 上一次我们简单的了解了二叉树这个数据结构, 但…