一些经典的神经网络(第18天)

news2024/12/23 17:18:49

1. 经典神经网络LeNet

LeNet是早期成功的神经网络;
先使用卷积层来学习图片空间信息
然后使用全连接层来转到到类别空间
在这里插入图片描述

【通过在卷积层后加入激活函数,可以引入非线性、增加模型的表达能力、增强稀疏性和解决梯度消失等问题,从而提高卷积神经网络的性能和效果】

LeNet由两部分组成:卷积编码器和全连接层密集块

import torch
from torch import nn
from d2l import torch as d2l

class Reshape(torch.nn.Module):
    def forward(self, x):
        return x.view(-1, 1, 28, 28) # 批量数不变,通道数=1,h=28, w=28

net = torch.nn.Sequential(Reshape(), 
                          nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.Sigmoid(), # 在卷积后加激活函数,填充是因为原始处理数据是32*32
                          nn.AvgPool2d(kernel_size=2, stride=2), # 池化层
                          nn.Conv2d(6, 16, kernel_size=5), nn.Sigmoid(),
                          nn.AvgPool2d(kernel_size=2, stride=2), 
                          nn.Flatten(), # 将4D结果拉成向量
                          # 相当于两个隐藏层的MLP
                          nn.Linear(16 * 5 * 5, 120), nn.Sigmoid(),
                          nn.Linear(120, 84), nn.Sigmoid(), 
                          nn.Linear(84, 10))

检查模型

X = torch.rand(size=(1, 1, 28, 28), dtype=torch.float32)
for layer in net:
    X = layer(X) 
    """
    对神经网络 net 中的每一层进行迭代,并打印每一层的输出形状
    layer.__class__.__name__ 是获取当前层的类名,即层的类型
    """
    print(layer.__class__.__name__, 'output shape: \t', X.shape)

在这里插入图片描述
LeNet在Fashion-MNIST数据集上的表现

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

# 对evaluate_accuarcy函数进行轻微的修改
def evaluate_accuracy_gpu(net, data_iter, device=None):  
    """使用GPU计算模型在数据集上的精度。"""
    if isinstance(net, torch.nn.Module):
        net.eval()
        if not device:
            device = next(iter(net.parameters())).device
    metric = d2l.Accumulator(2)
    for X, y in data_iter:
        if isinstance(X, list):
            X = [x.to(device) for x in X]
        else:
            X = X.to(device)
        y = y.to(device)
        metric.add(d2l.accuracy(net(X), y), y.numel())
    return metric[0] / metric[1]  # 分类正确的个数 / 总个数


net.to(device) 是将神经网络 net 中的所有参数和缓冲区移动到指定的设备上进行计算的操作。

net 是一个神经网络模型。device 是指定的设备,可以是 torch.device 对象,如 torch.device(‘cuda’) 表示将模型移动到 GPU 上进行计算,或者是字符串,如 ‘cuda:0’ 表示将模型移动到指定编号的 GPU 上进行计算,也可以是 ‘cpu’ 表示将模型移动到 CPU 上进行计算。
通过调用 net.to(device),模型中的所有参数和缓冲区将被复制到指定的设备上,并且之后的计算将在该设备上进行。这样可以利用 GPU 的并行计算能力来加速模型训练和推断过程。
注意,仅仅调用 net.to(device) 并不会对输入数据进行迁移,需要手动将输入数据也移动到相同的设备上才能与模型进行计算。例如,可以使用 input = input.to(device) 将输入数据 input 移动到指定设备上。】

# 为了使用 GPU,我们还需要一点小改动
def train_ch6(net, train_iter, test_iter, num_epochs, lr, device):
    """用GPU训练模型(在第六章定义)。"""
    def init_weights(m): # 初始化权重
        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) # 将神经网络 net 中的所有参数和缓冲区移动到指定的设备上进行计算的操作
    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) # metric被初始化为存储3个指标值的累加器
        net.train()
        for i, (X, y) in enumerate(train_iter):
            timer.start()
            optimizer.zero_grad()
            # 将输入输出数据也移动到相同的设备
            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]
            # 动画效果
            if (i + 1) % (num_batches // 5) == 0 or i == num_batches - 1:
                animator.add(epoch + (i + 1) / num_batches,
                             (train_l, train_acc, None))
        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())

在这里插入图片描述

2. 深度卷积神经网络(AlexNet)

在这里插入图片描述
在这里插入图片描述
AlexNet架构 VS LeNet:
更大的核窗口和步长,因为图片更大了
更大的池化窗口,使用maxpooling
更多的输出通道
添加了3层卷积层
更多的输出

更多细节:

  • 激活函数从sigmod变成了Rel(减缓梯度消失)
  • 隐藏全连接层后加入了丢弃层dropout
  • 数据增强

总结:

  • AlexNet是更大更深的LeNet,处理的参数个数和计算复杂度大幅度提升
  • 新加入了丢弃法,ReLU激活函数,最大池化层和数据增强

代码实现:

import torch
from torch import nn
from d2l import torch as d2l

net = nn.Sequential(
    nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(), # 在MNIST输入通道是1,在ImageNet测试集上输入为3
    nn.MaxPool2d(kernel_size=3, stride=2),
    nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.ReLU(), # 相比于LeNet将激活函数改为ReLU
    nn.MaxPool2d(kernel_size=3, stride=2),
    nn.Conv2d(256, 384, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(384, 384, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(384, 256, kernel_size=3, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2), 
    nn.Flatten(), # 将4D->2D
    nn.Linear(6400, 4096), nn.ReLU(), nn.Dropout(p=0.5), # 添加丢弃
    nn.Linear(4096, 4096), nn.ReLU(), nn.Dropout(p=0.5),
    nn.Linear(4096, 10)) # 在Fashion-MNIST上做测试所以输出为10
# 构造一个单通道数据,来观察每一层输出的形状
X = torch.randn(1, 1, 224, 224)
for layer in net:
    X = layer(X)
    print(layer.__class__.__name__, 'Output shape:\t', X.shape)

在这里插入图片描述

# Fashion-MNIST图像的分辨率低于ImageNet图像,所以将其增加到224x224
batch_size = 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)
# 训练AlexNet
lr, num_epochs = 0.01, 10
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())

3. 使用块的网络(VGG)

3.1 VGG相关

在这里插入图片描述
VGG的引出:

  • AlexNet比LeNet更深更大,取得了更好的精度
  • 能不能更深更大?
    • 更多的全连接层(太贵)
    • 更多的卷积层
    • 将卷积层组合成块 -> VGG

VGG块:

  • 深VS宽

    • 在同样的计算开销下,堆多一点的3x3的卷积层(模型更深但是窗口更窄)相比于5x5的Conv效果更好
  • 3x3卷积(填充1【保持输入输出大小不变】)(n层【Conv层数】,m通道【Conv输入输出通道数】)

  • 2x2 Maxpooling(步幅2)

核心:用大量3x3conv+池化 -> 堆成块,大量的块 -> 网络

VGG架构:

  • 多个VGG块后连接全连接层
  • 不同次数的重复块得到不同的架构:VGG-16, VGG-19
  • 实际上就是把AlexNet的卷积层架构替换成了VGG块的串联

在这里插入图片描述

网络发展的进度:

  • LeNet(1995)

    • 2卷积 + 池化
    • 2 全连接层
  • AlexNet

    • 更大更深
    • ReLU,Dropout,数据增强
    • 快 / 精度不高
  • VGG

    • 更大更深更规整的AlexNet(重复的VGG块)
    • 慢 / 精度高 / 占用内存高 / 可通过调节块的数量改变

VGG总结:

  • VGG使用可重复使用的卷积块来构建深度卷积神经网络
  • 不同的卷积块个数和超参数可以得到不同复杂度的变种

3.2 代码实现

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

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

相关文章

信息时代下,法律行业如何进行互联网推广

随着数字化时代的来临,法律行业也逐渐意识到互联网营销的优势,也有不少律所来找媒介盒子进行推广,那么今天媒介盒子就来跟大家聊聊,信息时代下,法律行业如何进行互联网营销。 一、 定位目标受众 定位目标受众是法律行…

拥抱国产信创化,思迈特与云和恩墨完成产品兼容认证

近日,思迈特软件与云和恩墨(北京)信息技术有限公司(简称“云和恩墨“)进行了联合测试,并顺利完成产品兼容互认证。 经评测,思迈特商 业智能与数据分析软件 Smartbi 系列 产品与云和恩墨 自主…

【vue3】注册全局组件

//main.tsimport CardVue from ./components/Card.vueconst app createApp(App) app.component(Card,CardVue)

coreldraw2024版本有哪些新增功能?

有小伙伴在用电脑查找软件程序的时候,看到了一款叫cdr软件的应用,自己之前没接触过,不知道cdr是什么软件?cdr软件是干什么的?十分好奇。其实它是一款平面设计软件,下面就给大家介绍下相关的cdr软件的知识。…

【java】【重构一】分模块开发设计实战

目录 一、创建项目 1、先创建一个空项目 2、设置项目SDK等 二、创建父模块 选择springboot 1、创建父模块parent 2、删除多余文件,只保留pom.xml 3、修改pom.xml 4、将部分公共依赖加入到pom 三、创建实体类子模块entity 1、创建实体类子模块entity 2、…

STM32CubeMX和Keil uVision5软件

目录 关系定位:合作关系STM32CubeMXKeil uVision5综上所述Q1:STM32CubeMX生成的初始化代码和配置文件为什么还需要Keil uVision5进行进一步的开发和调试Q2:二者如何配合最后生成可执行文件 关系定位:合作关系 STM32CubeMX和Keil uVision5是两…

【C++特殊类的设计】

目录 一、请设计一个类,不能被拷贝二、请设计一个类,只能在堆上创建对象三、请设计一个类,只能在栈上创建对象四、请设计一个类,不能被继承五、请设计一个类,只能创建一个对象(单例模式)5.1饿汉模式5.2懒汉模式 一、请…

那里可以自学C语言?

那里可以自学C语言? 我个人的习惯,学一门新的编程语言一定是需要目的的。 也就是学这个语言是干什么? 单纯的上学学习C语言一般都是 工科的专业作为专业课而开设的学科,这种很多都是使用谭浩强最近很多小伙伴找我,说想要一些c语言资料&…

数字化体系如何帮助企业拓展裂变增长渠道?数字化营销体系构建?

在当前的商业环境中,数字不仅仅是数据,还代表着技术和资产。企业数字化正是将数据转化为资产的过程。从信息化时代到数字化时代,企业逐渐将业务和组织、管理和创收都朝着在线化和数据化的方向发展,特别是企业的业务板块。数字化营…

图纸管理系统作用包括哪些?图纸管理系统有何作用?

图纸管理系统在设计制造行业中起着重要的作用,让企业的图纸管理变得更加便捷、更加高效,实现无纸化运作,提高工作效率。 彩虹图纸管理系统 集中管理和存储:图纸管理系统可以集中管理和存储所有图纸文件,包括2D图、3D图…

找出字符串中第一个匹配项的下标

题目链接 找出字符串中第一个匹配项的下标 题目描述 注意点 haystack 和 needle 仅由小写英文字符组成 解答思路 使用KMP算法,相比于普通地将整个字符串分成多块大小为needle.length()的子串找到第一个与needle匹配的子串,其可以在判断出任意一个子…

“当当平台关键字搜索API:轻松实现高效购物,获取海量商品信息!“

当当平台关键字搜索API可以让开发者通过API接口在当当平台上进行关键字搜索,从而获得商品列表。以下是使用当当平台关键字搜索API的一般步骤: 在当当开放平台注册账号,创建应用,获取API使用的App Key。根据当当开放平台的文档&am…

Linux系统的特点以及年轻人如何获取第一个Linux系统

由新闻想到的 新闻一:政府机构 5000 万台电脑将替换为国产 Linux ! 由这个新闻想到的,如果中国的所有个人、企业、政府把电脑系统都换成linux或者是国产操作系统,那将是怎样的一种景象!? 新闻二&#xf…

Spring Cloud 之 GateWay简介及简单DEMO的搭建

(1)Filter(过滤器): 和Zuul的过滤器在概念上类似,可以使用它拦截和修改请求,并且对上游的响应,进行二次处理。过滤器为org.springframework.cloud.gateway.filter.GatewayFilter类的…

竞赛选题 深度学习人体语义分割在弹幕防遮挡上的实现 - python

文章目录 1 前言1 课题背景2 技术原理和方法2.1基本原理2.2 技术选型和方法 3 实例分割4 实现效果5 最后 1 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 深度学习人体语义分割在弹幕防遮挡上的应用 该项目较为新颖,适合作为竞…

究竟如何?深入研究在缺少main.go文件时如何运行Go代码

是否可以在没有main.go文件的情况下运行Go代码? 😀 在Go语言中,包(package)是代码组织的基本单元,而可执行程序则需要一个特殊的main包和一个main函数。本篇博客将帮助您理解Go语言中包和可执行程序的概念,以及main.go…

【单片机毕业设计】【hj-006-7】CO、有害混合气体检测 | 空气质量检测 | 有害气体检测

一、基本介绍 项目名: 基于单片机的CO、有害混合气体检测系统设计 基于单片机的空气质量检测系统设计 基于单片机的有害气体检测系统设计 项目编号:mcuclub-hj-006-7 单片机类型:STC89C52 具体功能: 1、通过MQ-7检测CO值&#x…

hbase操作学习

1.namespace list_namespace 展示数据库 create_namespace 可以带属性名 属性值 create_namespace mydb,{author>hjp,ctime>2023-10-18}describe_namespace ‘库名’ 查看库的详细信息 alter_namespace ‘库名’ 修改表的详细信息 删除就是把method设置为unset dr…

STM32 __attribute__((section(“***“)))

1.在参考例程做STM32 IAP升级时遇到了关于__attribute__((section("***")))的问题,例程使用的是 uint8_t USART_RX_BUF[USART_REC_LEN] __attribute__ ((at(0X20001000))); 例程在使用CUBEIDE编译时提示warning: at attribute directive ignored [-Watt…

长钢管每米直线度检测 在线直线度测量仪轻松搞定!

钢管是一种常见的建筑材料,广泛应用于各种建筑和工程领域。钢管的直线度对于其使用性能和使用寿命具有重要影响,因此需要对钢管的直线度进行检测。传统的钢管直线度检测方法是通过测量多段钢管的直线度和弯头的角度来实现,这种方法不仅效率低…