d2l_第八章学习_现代卷积神经网络

news2024/11/17 3:51:26

参考:

  • d2l

x.1 AlexNet

研究人员认为:

  • 更大更干净的数据集或是稍加改进的特征提取方法,比任何学习算法带来的进步大得多。
  • 认为特征本身应该被学习,即卷积核参数应该是可学习的。
  • 创新点在于GPU与更深的网络,使用ReLU激活函数,Dropout层。

请添加图片描述

可参考:

AlexNet https://blog.csdn.net/qq_43369406/article/details/127295070

CODE::AlexNet_model https://blog.csdn.net/qq_43369406/article/details/129171352

x.2 VGG

VGG引入了自定义层,能够更加快速定义层结构。VGG亮点在于,通过堆叠多个3x3卷积核来代替大尺度卷积核,以此达到减少所需参数的目的。虽然减少了参数但是具有相同的感受野。

可参考:

  • VGG 网络介绍 https://blog.csdn.net/qq_43369406/article/details/127485929
  • CODE::VGG16_model https://blog.csdn.net/qq_43369406/article/details/129174640

x.3 NiN

最后一层如果使用全连接层会放弃表征的空间结构,所以使用全卷积代替。

请添加图片描述

x.4 GoogLeNet

GoogLeNet最大的特点在于解决了多大的卷积核最适合的问题,因为以前流行的网络使用小到1x1,大到11x11的卷积核,Inception模块使用了4条并行的路径,这种Inception的输出图中height和width相同而channel不同,最终在channel方向上进行了concat短接,结构如下:

请添加图片描述

我们注意到在数字图像处理中常常使用各种尺寸的滤波器探索图像,这意味着不同尺寸的滤波器可以有效地识别不同范围的图像细节。还使用了辅助分类器,1x1卷积核降维。

参考:

  • GoogLeNet 网络简介 https://blog.csdn.net/qq_43369406/article/details/127608423
  • CODE::GoogLeNet_model https://blog.csdn.net/qq_43369406/article/details/129189694

x.5 ResNet

x.5.1 BatchNormalization

BN作为现代深度学习中浓墨重彩的一笔,它的出现能够可持续加速深层网络的收敛。回顾神经网络碰到的挑战如下:

  • 数据预处理方式会对最终结果产生巨大影响。第一步是规范化输入特征,使得全部输入特征 ~ N (0, 1)
  • 在中间隐藏层中,如果一个层的可变值是另一层的100倍,这种变量分布中的偏移会阻碍网络的收敛。通过中间隐藏层后的数据难以控制,需要BN归一化。
  • 更深层的网络复杂,容易过拟合,意味着正则化更加重要。如L2正则化,在loss中增加weight decay,通过Adam可简易实现。

在BN层中,每一个通道的数据具有四个参数,其中miu和sigma并不是learnable parameters,并不会出现在model.parameters()中;而scale parameter - lambda和shift parameter - beta是learnable parameters可学习参数,会参加梯度计算,如下:

请添加图片描述

而miu和sigma便是mini-batch小批量样本的均值和方差,

请添加图片描述

需要注意到的是BN层具有自己的处理顺序,如:Linear-BN-Activation或者Conv-BN-Act

请添加图片描述

BN同Dropout在model.eval()时候会失去活性,

建议参看BN代码实现如下:

"""

1. BN
"""
def batch_norm(X, gamma, beta, moving_mean, moving_var, eps, momentum):
    # Use is_grad_enabled to determine whether we are in training mode
    if not torch.is_grad_enabled():
        # In prediction mode, use mean and variance obtained by moving average
        X_hat = (X - moving_mean) / torch.sqrt(moving_var + eps)
    else:
        assert len(X.shape) in (2, 4)
        if len(X.shape) == 2:
            # When using a fully connected layer, calculate the mean and
            # variance on the feature dimension
            mean = X.mean(dim=0)
            var = ((X - mean) ** 2).mean(dim=0)
        else:
            # When using a two-dimensional convolutional layer, calculate the
            # mean and variance on the channel dimension (axis=1). Here we
            # need to maintain the shape of X, so that the broadcasting
            # operation can be carried out later
            mean = X.mean(dim=(0, 2, 3), keepdim=True)
            var = ((X - mean) ** 2).mean(dim=(0, 2, 3), keepdim=True)
        # In training mode, the current mean and variance are used
        X_hat = (X - mean) / torch.sqrt(var + eps)
        # Update the mean and variance using moving average
        moving_mean = (1.0 - momentum) * moving_mean + momentum * mean
        moving_var = (1.0 - momentum) * moving_var + momentum * var
    Y = gamma * X_hat + beta  # Scale and shift
    return Y, moving_mean.data, moving_var.data

class BatchNorm(nn.Module):
    # num_features: the number of outputs for a fully connected layer or the
    # number of output channels for a convolutional layer. num_dims: 2 for a
    # fully connected layer and 4 for a convolutional layer
    def __init__(self, num_features, num_dims):
        super().__init__()
        if num_dims == 2:
            shape = (1, num_features)
        else:
            shape = (1, num_features, 1, 1)
        # The scale parameter and the shift parameter (model parameters) are
        # initialized to 1 and 0, respectively
        self.gamma = nn.Parameter(torch.ones(shape))
        self.beta = nn.Parameter(torch.zeros(shape))
        # The variables that are not model parameters are initialized to 0 and
        # 1
        self.moving_mean = torch.zeros(shape)
        self.moving_var = torch.ones(shape)

    def forward(self, X):
        # If X is not on the main memory, copy moving_mean and moving_var to
        # the device where X is located
        if self.moving_mean.device != X.device:
            self.moving_mean = self.moving_mean.to(X.device)
            self.moving_var = self.moving_var.to(X.device)
        # Save the updated moving_mean and moving_var
        Y, self.moving_mean, self.moving_var = batch_norm(
            X, self.gamma, self.beta, self.moving_mean,
            self.moving_var, eps=1e-5, momentum=0.1)
        return Y

# test
temp_builtin = [i for i in torch.nn.BatchNorm2d(4).parameters()]
temp_diy = [i for i in BatchNorm(num_features=4, num_dims=4).parameters()]
# self.moving_mean() and var is not nn.Parameters(), not learnable.


"""

2. LeNet
"""
class BNLeNetScratch(d2l.Classifier):
    def __init__(self, lr=0.1, num_classes=10):
        super().__init__()
        self.save_hyperparameters()
        self.net = nn.Sequential(
            nn.LazyConv2d(6, kernel_size=5), BatchNorm(6, num_dims=4),
            nn.Sigmoid(), nn.AvgPool2d(kernel_size=2, stride=2),
            nn.LazyConv2d(16, kernel_size=5), BatchNorm(16, num_dims=4),
            nn.Sigmoid(), nn.AvgPool2d(kernel_size=2, stride=2),
            nn.Flatten(), nn.LazyLinear(120),
            BatchNorm(120, num_dims=2), nn.Sigmoid(), nn.LazyLinear(84),
            BatchNorm(84, num_dims=2), nn.Sigmoid(),
            nn.LazyLinear(num_classes))

trainer = d2l.Trainer(max_epochs=10, num_gpus=1)
data = d2l.FashionMNIST(batch_size=128)
model = BNLeNetScratch(lr=0.1)
model.apply_init([next(iter(data.get_dataloader(True)))[0]], d2l.init_cnn)  # 因为使用了Lazy init所以要先forward一个Tensor初始化模型
trainer.fit(model, data)

# learnable gamma and beta
print(model.net[1].gamma.reshape((-1,)), model.net[1].beta.reshape((-1,)))

x.5.2 ResNet

随着网络的层数加深,深刻理解新添加的层如何提升神经网络的性能变得至关重要,给定X个特征,y个标签的数据集,我们需要使得f尽量拟合f星,如下:

请添加图片描述

而为了更接近f星,我们需要尽量使用类似右侧的嵌套函数,复杂度从F1到F6依次增加。

请添加图片描述

较复杂的函数类包含较小的函数类这一思想引入,我们得到残差网络核心思想:每个附加层都应该更容易地包含原始函数作为其元素之一。

请添加图片描述

ResNet的两点在于引入了BN和残差模块,加深了网络深度,如下:

请添加图片描述

参考:

  • ResNet 简介 https://blog.csdn.net/qq_43369406/article/details/127500443
  • ResNet 代码实现 https://blog.csdn.net/qq_43369406/article/details/127508108
  • CODE::ResNet_model https://blog.csdn.net/qq_43369406/article/details/129190380

x.6 DenseNet

将ResNet更改为联系前面多层,并使用Concat拼接。

x.7 Designing Convolution Network Architectures

从AlexNet到ResNet,SENet由于加入了位置信息和注意力机制,是Transformers的前身。

NAS的大展身手的诞生了EfficientNets。

手工设计和NAS的结合诞生出了RegNets。

为了设置拟合能力更强的网络,应该使用更深的(channel更大)网络。

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

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

相关文章

问题收藏夹——使用mybatisPlusJoin报 NoSuchPropertyException错误

出现问题代码: 报错: 解决方法: MPJLambdaQueryWrapper 类有问题,应该用MPJLambdaWrapper,去看了作者官网,发现已经没有这个类的用法了,但是还能用这个类(Copilot直接给我补全这个…

SNMP 计算机网络管理 实验2(三) SNMP服务与常用网管命令之任务五:查看端口流量及实验小结

⬜⬜⬜ 🐰🟧🟨🟩🟦🟪(*^▽^*)欢迎光临 🟧🟨🟩🟦🟪🐰⬜⬜⬜ ✏️write in front✏️ 📝个人主页:陈丹宇jmu &am…

人工智能 --- 吉布斯采样

贝叶斯网络如下图所示,包含 4 个随机变量,每个变量都只有表示是否的两个值。请用吉布斯采样方法回答以下问题。 假设观察到 𝑅 𝑟, 初始化样本中其他变量的赋值为 𝐶 𝑐, 𝑆 −&#x1d460…

四、深度学习的计算

文章目录 前言一、层和块1.1 自定义块1.2 顺序块1.3 在前向传播函数中执行代码1.4 效率问题1.5 小结 二、参数管理2.1 参数访问2.1.1 目标参数2.1.2 访问所有参数2.1.3 从嵌套块中收集参数 2.2 参数初始化2.2.1 内置初始化2.2.2 自定义初始化2.2.3 参数绑定 三、延后初始化四、…

低功耗蓝牙OM6621EM 兼容Nordic 51系列2.4G私有协议

OM6621EM是一个功率优化的系统(SOC).解决蓝牙低功耗和专有的2.4 ghz应用。它集成了一个高具有蓝牙基带和丰富外设的低功耗射频收发器I0扩展。OM6621EM还集成了电源管理单元(PMU)来提供高效的电源管理。它的目标是2.4GHz低功耗蓝牙系统,专有的2.4 ghz系统&#xff0c…

easyX库其他函数(注释版)

本篇是easyX库系列正文最后一篇,依旧是有几个很有价值的函数,我不补充了几个例子,对easyX库中的部分code例子做了修改。 0.其它函数概览 函数或数据类型描述GetEasyXVer获取当前EasyX库的版本信息。BeginBatchDraw开始批量绘图。EndBatchDr…

Java Web HTMLCSS(1)23.6.29

HTML&CSS 1,HTML 1.1 介绍 HTML 是一门语言,所有的网页都是用HTML 这门语言编写出来的,也就是HTML是用来写网页的,像京东,12306等网站有很多网页。 这些都是网页展示出来的效果。而HTML也有专业的解释 HTML(Hy…

Pycharm中打开HTML文件报错:Windows 找不到文件‘chrome‘

问题现象: Pycharm中,打开HTML文件,选择chrome浏览器打开时,报错:Windows 找不到文件’chrome’。请确定文件名是否正确后,再试一次。但实际上你的电脑上是安装了Chrome浏览器的。 解决方案: 原…

【算法】状态机DP 买卖股票系列

文章目录 前期知识股票问题买卖股票的最佳时机 II最佳买卖股票时机含冷冻期买卖股票的最佳时机 IV补充:恰好k次 / 至少k次 怎么做? 相关题目练习买卖股票的最佳时机 https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/解法1——状态机DP解法…

十三、禅道登录/提交版本/编辑版本接口

十三、禅道提交版本/编辑版本接口 1. 禅道的登录接口或者叫获取tokens接口 # -*- coding: utf-8 -*- """ ------------------------------------------------------------------------------- File : zentao_login.py Time : 2023/6/29 13:55 author : …

Java读取Excel第一行数据,获取表头

目录 一、场景 二、代码实现 1、工具类 2、方法调用 3、结果 之前写过一篇关于解析Excel的博客:解析读取Excel文件(.xls .xlsx),今天再分享一下,如何获取Excel的表头数据。 一、场景 需要判断导入的Excel文件的列…

什么是AQS

AQS(Abstract Queued Synchronizer)是一个抽象的队列同步器,通过维护一个共享资源状态(Volatile Int State)和一个先进先出(FIFO)的线程等待队列来实现一个多线程访问共享资源的同步框架。 AQS…

今日份分享:三个电脑mp3转换器推荐

有一个音乐爱好者叫小艾。她对音乐充满热爱,每天都会用耳机沉浸在动听的旋律中。然而,她最近遇到了一个问题:她手头有一些喜欢的音乐文件,但格式却是不支持她的音乐播放器。这让她感到非常困扰,因为她希望随时随地欣赏…

适用于Vue 3的最佳开源分页库

从头开始实现分页可能是一项耗时的任务,需要大量的精力和资源。幸运的是,有几个伟大的开源库可以简化这个过程,提高你的效率。使用分页库可以节省你的时间和精力,使你能够专注于建立你的应用程序的其他更重要的功能。 在这篇文章…

如何选择适合自己的专业?

高考季又到了,毕业生们正忙着选填志愿。志愿填报是一个关键的决策,它将对他们未来的学习和就业产生重要影响。在这个关键的时刻,一些相关问题随之而来:如何填报志愿?是选择专业还是学校?哪些专业就业前景好…

全国农信银CTF逆向Baby8or解析

按CTRL X 跳转到main函数,按F5 生成伪代码进行分析。 发现一个加密函数,当加密后的数据和genc[i]数组中的值对比一致则表示正确flag,字符串长度为35。 双击genc[i] 找到genc[i]中的数据,转成10进制得到数组 genc[172,102,148,22…

数据结构--双链表

数据结构–双链表 单链表 VS 双链表 单链表:无法逆向检索,有时候不太方便 双链表:可进可退,存储密度更低一丢丢 双链表的定义 typedef struct DNode {ElemType data;struct DNode *prior, *next; }DNode, *DLinkList;双链表的初…

JavaWeb——2.注解

这篇文章我们来讲一下Java中的注解 其实这部分内容算是Javaweb的补充内容,其中还包括Junit测试和反射的相关内容。 Junit测试是一个比较简单的内容,这里就不写了;而反射的相关内容可以看java基础专栏,那里面有详细的叙述。 目录…

Jvm jmx_exporter Prometheus dubbo Grafana 重点看端口要对应上 单独进程和程序进程内jmx_exporter

目录 JMX Exporter 的两种用法 启动独立进程 jmx_prometheus_httpserver-0.18.0.jar 方式 下载 jmx_exporter 找地方随便一放 创建配置文件 config_jmx_exporter.yaml 增加 启动 jvm 配置 一定要是jvm参数 可别意外写成程序参数 启动jmx_exporter Prometheus yml 配置 …

使用jmap查看对象数

jmap:JVM自带的一种内存映像工具 查看jmap命令帮助 查询java进程pid # 查看堆内存中的对象 jmap -histo PID# 查看堆内存中的存活对象 jmap -histo:live PID 使用示例: jmap -histo:live 46024|grep com.kingbase8.jdbc.KbConnection 列说明 num#insta…