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

news2025/1/11 8:19:09

目录

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

LeNet网络

在这里插入图片描述


手写的数字识别

在这里插入图片描述



MNIST

在这里插入图片描述




在这里插入图片描述

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

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




总结

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

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

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




卷积神经网络(LeNet)

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

import torch
from torch import nn


class Reshape(torch.nn.Module):
    def forward(self, x):
        return x.view(-1, 1, 28, 28)  # 批量数自适应得到,通道数为1,图片为28X28


net = 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(),
    # 用均值池化层,步长为2
    nn.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)层后,输出特征图将会是:
在这里插入图片描述
即:

在这里插入图片描述

输出特征图的大小从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.coloradmin.cn/o/2040495.html

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

相关文章

【rh】rh项目部署

【fastadmin】 1、项目先clone到本地,其中web为h5前端使用(gitclone后,把web内容放进去再提交),其余为项目后端使用 2、安装本地环境,项目跑起来,步骤如下: 1)查春.git 和 composer,json 版本信…

servlet基础操作(get)

1,首先创建一个javaweb的项目 简历一般的java项目选中项目,双击shift出现搜索栏 找到这个框架,选择里面的javaweb,注意选择右侧版本显示为4.0的javaweb 之后部署Tomcat 我这里是本地,所以在本地选的是local 第一步实…

Python 类的使用

目录 1、类的基本概念 1.1、类的定义 1.2、类的使用 2、类的公有属性和私有属性 2.1、为什么子类不能访问父类的私有属性/方法? 3、实例方法、类方法、静态方法 3.1、实例方法 3.2、类方法 3.3、静态方法 4、property 、XXX.setter和XXX.deleter的使用 4…

20240814确认RK3588S接USB摄像头录像+预览出现异常

20240814确认RK3588S接USB摄像头录像预览出现异常 2024/8/14 21:03 缘起,使用荣品RK3588S-AHD开发板接USB摄像头预览【几分钟】正常。 但是只要一开始录像预览就异常。 于是,上Rockchip的官方RK3588S开发板。预览52分钟还是出错了。 录像预览也异常。 但…

【IO day8】

第一题: 由于共享内存没有同步,想办法搞定共享内存的同步问题 p1.c p2.c 第二题: 使用第一题作用已经实现的共享内存,去做2个终端之间的互相聊天 t1.c t2.c

C语言 | Leetcode C语言题解之第335题路径交叉

题目&#xff1a; 题解&#xff1a; bool isSelfCrossing(int* distance, int distanceSize){if (distance NULL || distanceSize < 4) {return false;}for (int i 3; i < distanceSize; i) {if ((distance[i] > distance[i - 2]) && (distance[i - 1] &l…

临床数据科学和金融数据科学,选择R语言吧!

学习R语言不仅能够增强数据分析能力&#xff0c;还能开拓解决复杂问题的新方法。然而&#xff0c;在学习R语言的过程中&#xff0c;许多初学者会遇到各种陷阱&#xff0c;这些陷阱不仅会延缓学习进度&#xff0c;还可能导致学习动机的丧失。 下面内容摘录自《R 语言与数据科学的…

814的学习

共享内存实现

【谷粒商城学习笔记】项目介绍+分布式基础概念

文章目录 电商模式项目技术特色项目前置要求分布式基础概念微服务集群/分布式/节点远程调用负载均衡服务发现、注册中心配置中心服务熔断、降级网关 微服务架构图微服务划分图文章说明 电商模式 市面上有 5 种常见的电商模式 B2B、B2C、C2B、C2C、O2O。 B2B 模式&#xff1a;…

SAP与网易大数据系统集成案例

一、项目环境 江西某药业有限公司是一家以医药产业为主营、资本经营为平台的大型民营企业集团。公司成立迄今&#xff0c;企业经营一直呈现稳健、快速发展的态势集团总销售额超40亿元。 为了帮助企业更有效的进行分配和管理&#xff0c;包括人力、物资、时间和预算等资源&a…

Redis的简单介绍

一、Redis简介 1.NOSQL NoSQL( Not Only SQL)&#xff0c;意即“不仅仅是SQL”&#xff0c;泛指非关系型的数据库。随着互联网web2.0网站的兴起&#xff0c;传统的关系数据库在应付web2.0网站&#xff0c;纯动态网站已经显得力不从心&#xff0c;暴露了很多难以克服的问题&am…

DNS的反向解析

反向解析 DNS的反向解析&#xff08;Reverse DNS Lookup&#xff0c;通常缩写为rDNS&#xff09;是指通过IP地址查找与之对应的域名的过程。与正向解析&#xff08;通过域名查找IP地址&#xff09;相对&#xff0c;反向解析的主要用途是验证IP地址与域名的关联性&#xff0c;常…

调用本地大模型API 以ollama为例子 技术栈node.js koa2 vite

首先在官方下载ollama大模型 https://ollama.com/ 在cmd中查看版本 ollama -v 看到有版本号&#xff0c;说明安装完成。 下载合适的大模型 运行内存16g 建议 7b 左右的大模型&#xff0c;16g以上自己合理安排 点击官网模型下载合适的大模型 复制粘贴到cmd中 下载完成后 ollama …

学习嵌入式入门(十一)电容触摸实验及OLED 显示实验

一、电容触摸实验 1.电容触摸按键简介 电容式触摸按键已经广泛应用在家用电器、消费电子市场&#xff0c;其主要优势有&#xff1a;无机械装置&#xff0c; 使用寿命长&#xff1b;非接触式感应&#xff0c;面板不需要开孔&#xff1b;产品更加美观简洁&#xff1b;防水可以做…

【教程】Ubuntu给pycharm添加侧边栏快捷方式

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhagn.cn] 如果本文帮助到了你&#xff0c;欢迎[点赞、收藏、关注]哦~ 以下教程不仅限于pycharm&#xff0c;其他软件也是一样操作 1、进入到pycharm的目录&#xff0c;先通过命令行打开pycharm&#xff1a; ./bin/pycharm…

Vscode——如何实现 Ctrl+鼠标左键 跳转函数内部的方法

一、对于Python代码 安装python插件即可实现 二、对于C/C代码 安装C/C插件即可实现

LATTICE进阶篇DDR2--(4)DDR2 IP核总结

一、IP核的时钟框架 1片DDR2的接口是16位&#xff0c;且DDR2是双边沿读取的&#xff0c; 故当DDR2芯片的时钟为200M时&#xff0c;右侧DDR2芯片上的数据吞吐率为200M*2*16b&#xff0c;左侧数据吞吐率为200M*32b&#xff0c;左右两侧数据吞吐量相等。 根据上规律可知&#xf…

Java Spring|day2.SpringMVC

Spring MVC 定义 MVC是一种设计模式&#xff0c;在这种模式下软件被分为三层&#xff0c;即Model&#xff08;模型&#xff09;、View&#xff08;视图&#xff09;、Controller&#xff08;控制器&#xff09;。 MVC是一种软件架构思想&#xff0c;把软件按照模型&#xff…

CSS设置文本超出显示省略号

一、单行文本显示省略号 <div class"box"><p>测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本测试文本…

用于不平衡医疗数据分类的主动SMOTE

一、主动学习如何应用于不平衡数据的处理 首先&#xff0c;主动SMOTE不是像经典的SMOTE那样从训练集中随机选择一个样本作为生成合成样本的轴心点&#xff0c;而是通过不确定性和多样性采样来智能地进行样本选择&#xff0c;这是主动学习的两种技术。 在数据不平衡的情况下&…