《动手学深度学习 Pytorch版》 7.1 深度卷积神经网络(LeNet)

news2024/11/29 10:41:01

7.1.1 学习表征

深度卷积神经网络的突破出现在2012年。突破可归因于以下两个关键因素:

  • 缺少的成分:数据
    数据集紧缺的情况在 2010 年前后兴起的大数据浪潮中得到改善。ImageNet 挑战赛中,ImageNet数据集由斯坦福大学教授李飞飞小组的研究人员开发,利用谷歌图像搜索对分类图片进行预筛选,并利用亚马逊众包标注每张图片的类别。这种数据规模是前所未有的。
  • 缺少的成分:硬件
    2012年,Alex Krizhevsky和Ilya Sutskever使用两个显存为3GB的NVIDIA GTX580 GPU实现了快速卷积运算,推动了深度学习热潮。

7.1.2 AlexNet

2012年横空出世的 AlexNet 首次证明了学习到的特征可以超越手动设计的特征。

AlexNet 和 LeNet 的架构非常相似(此书对模型稍微精简了一下,取出来需要两个小GPU同时运算的设计特点):

全连接层(1000)

↑ \uparrow

全连接层(4096)

↑ \uparrow

全连接层(4096)

↑ \uparrow

3 × 3 3\times3 3×3最大汇聚层,步幅2

↑ \uparrow

3 × 3 3\times3 3×3卷积层(384),填充1

↑ \uparrow

3 × 3 3\times3 3×3卷积层(384),填充1

↑ \uparrow

3 × 3 3\times3 3×3卷积层(384),填充1

↑ \uparrow

3 × 3 3\times3 3×3最大汇聚层,步幅2

↑ \uparrow

5 × 5 5\times5 5×5卷积层(256),填充2

↑ \uparrow

3 × 3 3\times3 3×3最大汇聚层,步幅2

↑ \uparrow

11 × 11 11\times11 11×11卷积层(96),步幅4

↑ \uparrow

输入图像( 3 × 224 × 224 3\times224\times224 3×224×224

AlexNet 和 LeNet 的差异:

- AlexNet 比 LeNet 深的多
- AlexNet 使用 ReLU 而非 sigmoid 作为激活函数

以下为 AlexNet 的细节。

  1. 模型设计

    由于 ImageNet 中的图像大多较大,因此第一层采用了 11 × 11 11\times11 11×11 的超大卷积核。后续再一步一步缩减到 3 × 3 3\times3 3×3。而且 AlexNet 的卷积通道数是 LeNet 的十倍。

    最后两个巨大的全连接层分别各有4096个输出,近 1G 的模型参数。因早期 GPU 显存有限,原始的 AlexNet 采取了双数据流设计。

  2. 激活函数

    ReLU 激活函数是训练模型更加容易。它在正区间的梯度总为1,而 sigmoid 函数可能在正区间内得到几乎为 0 的梯度。

  3. 容量控制和预处理

    AlexNet 通过暂退法控制全连接层的复杂度。此外,为了扩充数据,AlexNet 在训练时增加了大量的图像增强数据(如翻转、裁切和变色),这也使得模型更健壮,并减少了过拟合。

import torch
from torch import nn
from d2l import torch as d2l
net = nn.Sequential(
    # 这里使用一个11*11的更大窗口来捕捉对象。
    # 同时,步幅为4,以减少输出的高度和宽度。
    # 另外,输出通道的数目远大于LeNet
    nn.Conv2d(1, 96, kernel_size=11, stride=4, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    # 减小卷积窗口,使用填充为2来使得输入与输出的高和宽一致,且增大输出通道数
    nn.Conv2d(96, 256, kernel_size=5, padding=2), nn.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(),
    # 这里,全连接层的输出数量是LeNet中的好几倍。使用dropout层来减轻过拟合
    nn.Linear(6400, 4096), nn.ReLU(),
    nn.Dropout(p=0.5),
    nn.Linear(4096, 4096), nn.ReLU(),
    nn.Dropout(p=0.5),
    # 最后是输出层。由于这里使用Fashion-MNIST,所以用类别数为10,而非论文中的1000
    nn.Linear(4096, 10))
X = torch.randn(1, 1, 224, 224)
for layer in net:
    X=layer(X)
    print(layer.__class__.__name__,'output shape:\t',X.shape)
Conv2d output shape:	 torch.Size([1, 96, 54, 54])
ReLU output shape:	 torch.Size([1, 96, 54, 54])
MaxPool2d output shape:	 torch.Size([1, 96, 26, 26])
Conv2d output shape:	 torch.Size([1, 256, 26, 26])
ReLU output shape:	 torch.Size([1, 256, 26, 26])
MaxPool2d output shape:	 torch.Size([1, 256, 12, 12])
Conv2d output shape:	 torch.Size([1, 384, 12, 12])
ReLU output shape:	 torch.Size([1, 384, 12, 12])
Conv2d output shape:	 torch.Size([1, 384, 12, 12])
ReLU output shape:	 torch.Size([1, 384, 12, 12])
Conv2d output shape:	 torch.Size([1, 256, 12, 12])
ReLU output shape:	 torch.Size([1, 256, 12, 12])
MaxPool2d output shape:	 torch.Size([1, 256, 5, 5])
Flatten output shape:	 torch.Size([1, 6400])
Linear output shape:	 torch.Size([1, 4096])
ReLU output shape:	 torch.Size([1, 4096])
Dropout output shape:	 torch.Size([1, 4096])
Linear output shape:	 torch.Size([1, 4096])
ReLU output shape:	 torch.Size([1, 4096])
Dropout output shape:	 torch.Size([1, 4096])
Linear output shape:	 torch.Size([1, 10])

7.1.3 读取数据集

如果真用 ImageNet 训练,即使是现在的 GPU 也需要数小时或数天的时间。在此仅作演示,仍使用 Fashion-MNIST 数据集,故在此需要解决图像分辨率的问题。

batch_size = 128
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size, resize=224)

7.1.4 训练 AlexNet

lr, num_epochs = 0.01, 10
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())  # 大约需要二十分钟,慎跑
loss 0.330, train acc 0.879, test acc 0.878
592.4 examples/sec on cuda:0

在这里插入图片描述

练习

(1)尝试增加轮数。对比 LeNet 的结果有什么不同?为什么?

lr, num_epochs = 0.01, 15
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())  # 大约需要三十分钟,慎跑
loss 0.284, train acc 0.896, test acc 0.887
589.3 examples/sec on cuda:0

在这里插入图片描述

相较于 LeNet 的增加轮次反而导致精度下降,AlexNet 具有更好的抗过拟合能力,增加轮次精度就会上升。


(2) AlexNet 模型对 Fashion-MNIST 可能太复杂了。

a. 尝试简化模型以加快训练速度,同时确保准确性不会显著下降。

b. 设计一个更好的模型,可以直接在 $28\times28$ 像素的图像上工作。
net_Better = nn.Sequential(
    nn.Conv2d(1, 64, kernel_size=5, stride=2, padding=2), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=1),
    nn.Conv2d(64, 128, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(128, 128, kernel_size=3, padding=1), nn.ReLU(),
    nn.Conv2d(128, 64, kernel_size=3, padding=1), nn.ReLU(),
    nn.MaxPool2d(kernel_size=3, stride=2),
    nn.Flatten(),
    nn.Linear(64 * 5 * 5, 1024), nn.ReLU(),
    nn.Dropout(p=0.3), 
    nn.Linear(1024, 512), nn.ReLU(),
    nn.Dropout(p=0.3),
    nn.Linear(512, 10)
)

X = torch.randn(1, 1, 28, 28)
for layer in net_Better:
    X=layer(X)
    print(layer.__class__.__name__,'output shape:\t',X.shape)
Conv2d output shape:	 torch.Size([1, 64, 14, 14])
ReLU output shape:	 torch.Size([1, 64, 14, 14])
MaxPool2d output shape:	 torch.Size([1, 64, 12, 12])
Conv2d output shape:	 torch.Size([1, 128, 12, 12])
ReLU output shape:	 torch.Size([1, 128, 12, 12])
Conv2d output shape:	 torch.Size([1, 128, 12, 12])
ReLU output shape:	 torch.Size([1, 128, 12, 12])
Conv2d output shape:	 torch.Size([1, 64, 12, 12])
ReLU output shape:	 torch.Size([1, 64, 12, 12])
MaxPool2d output shape:	 torch.Size([1, 64, 5, 5])
Flatten output shape:	 torch.Size([1, 1600])
Linear output shape:	 torch.Size([1, 1024])
ReLU output shape:	 torch.Size([1, 1024])
Dropout output shape:	 torch.Size([1, 1024])
Linear output shape:	 torch.Size([1, 512])
ReLU output shape:	 torch.Size([1, 512])
Dropout output shape:	 torch.Size([1, 512])
Linear output shape:	 torch.Size([1, 10])
batch_size = 128
train_iter28, test_iter28 = d2l.load_data_fashion_mnist(batch_size=batch_size)
lr, num_epochs = 0.01, 10
d2l.train_ch6(net_Better, train_iter28, test_iter28, num_epochs, lr, d2l.try_gpu())  # 快多了
loss 0.429, train acc 0.841, test acc 0.843
6650.9 examples/sec on cuda:0

在这里插入图片描述


(3)修改批量大小,并观察模型精度和GPU显存变化。

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

lr, num_epochs = 0.01, 10
d2l.train_ch6(net, train_iter, test_iter, num_epochs, lr, d2l.try_gpu())  # 大约需要二十分钟,慎跑
loss 0.407, train acc 0.850, test acc 0.855
587.8 examples/sec on cuda:0

在这里插入图片描述

4G 显存基本拉满,精度略微下降,过拟合貌似严重了。


(4)分析 AlexNet 的计算性能。

a. 在 AlexNet 中主要是哪一部分占用显存?

b. 在AlexNet中主要是哪部分需要更多的计算?

c. 计算结果时显存带宽如何?

a. 第一个全连接层占用显存最多

b. 倒数第二个卷积层需要更多的计算


(5)将dropout和ReLU应用于LeNet-5,效果有提升吗?再试试预处理会怎么样?

net_try = nn.Sequential(
    nn.Conv2d(1, 6, kernel_size=5, padding=2), nn.ReLU(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Conv2d(6, 16, kernel_size=5), nn.ReLU(),
    nn.AvgPool2d(kernel_size=2, stride=2),
    nn.Flatten(),
    nn.Linear(16 * 5 * 5, 120), nn.ReLU(),
    nn.Dropout(p=0.2), 
    nn.Linear(120, 84), nn.ReLU(),
    nn.Dropout(p=0.2), 
    nn.Linear(84, 10))

lr, num_epochs = 0.6, 10
d2l.train_ch6(net_try, train_iter28, test_iter28, num_epochs, lr, d2l.try_gpu())  # 浅调一下还挺好
loss 0.306, train acc 0.887, test acc 0.883
26121.2 examples/sec on cuda:0

在这里插入图片描述

浅浅调一下,效果挺好,精度有所提升。

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

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

相关文章

OpenCV中的HoughLines函数和HoughLinesP函数到底有什么区别?

一、简述 基于OpenCV进行直线检测可以使用HoughLines和HoughLinesP函数完成的。这两个函数之间的唯一区别在于,第一个函数使用标准霍夫变换,第二个函数使用概率霍夫变换(因此名称为 P)。概率版本之所以如此,是因为它仅分析点的子集并估计这些点都属于同一条线的概率。此实…

威胁的数量、复杂程度和扩散程度不断上升

Integrity360 宣布了针对所面临的网络安全威胁、数量以及事件响应挑战的独立研究结果。 数据盗窃、网络钓鱼、勒索软件和 APT 是最令人担忧的问题 这项调查于 2023 年 8 月 9 日至 14 日期间对 205 名 IT 安全决策者进行了调查,强调了他们的主要网络安全威胁和担忧…

评价指标分类

声明 本文是学习GB-T 42874-2023 城市公共设施服务 城市家具 系统建设实施评价规范. 而整理的学习笔记,分享出来希望更多人受益,如果存在侵权请及时联系我们 1 范围 本文件确立了城市家具系统建设实施的评价原则、评价流程,给出了评价指标,描述了 方…

nodejs定时任务

项目需求: 每5秒执行一次,多个定时任务错开,即cron表达式中斜杆前带数字,例如 ‘1/5 * * * * *’定时任务准时,延误低 搜索了nodejs的定时任务,其实不多,找到了以下三个常用的: n…

无涯教程-JavaScript - BETA.INV函数

描述 BETA.INV函数返回beta累积概率密度函数(BETA.DIST)的反函数。如果概率 BETA.DIST(x ... TRUE),则BETA.INV(概率...) x。 在预期的完成时间和可变性的情况下,可以在项目计划中使用beta分布来建模可能的完成时间。 语法 BETA.INV (probability,alpha,beta,[A],[B])争论 …

Linux中使用selenium截图的文字变为方框的解决方案

一、前言 最近在Linux中使用selenium截图时,发现文字都变为了方框: 虽然不影响selenium的使用,但有点影响调试,也不好看,后面发现是因为Linux缺少中文字体的缘故,需要安装中文字体就能解决。 二、安装中文…

安卓Android_手机安装burp的https_CA证书

安卓Android_手机安装burp的https_CA证书 文章目录 安卓Android_手机安装burp的https_CA证书1 打卡电脑wif热点,手机连上电脑的热点2 burp点击 --》 Proxy settings3 点击add ---》新增代理地址和端口4 设置好-展示5 手机连上电脑的wifi热点6 点击查看ip地址与burp …

这些英国学校接受ChatGPT帮助写作

自从ChatGPT展现了其高超的AI技术,全球年轻人纷纷对其表示喜爱,尤其是学生们,将其视为一个优化版的网络搜索引擎,可以用来提高学习效率。 ChatGPT具有多样化的功能,可以节省研究复杂文献的时间,编写简单的…

stm32学习-芯片系列/选型

【03】STM32HAL库开发-初识STM32 | STM概念、芯片分类、命名规则、选型 | STM32原理图设计、看数据手册、最小系统的组成 、STM32IO分配_小浪宝宝的博客-CSDN博客  STM32:ST是意法半导体,M是MCU/MPU,32是32位。  ST累计推出了&#xff1a…

AIGC生成式代码——Code Llama 简介、部署、测试、应用、本地化

导读: 本文介绍了CodeLlama的简介、本地化部署、测试和应用实战方案,帮助学习大语言模型的同学们更好地应用CodeLlama。我们详细讲解了如何将CodeLlama部署到实际应用场景中,并通过实例演示了如何使用CodeLlama进行代码生成和优化。最后,总结了CodeLlama的应用实战经验和注…

9.4.2servlet基础2

一.SmartTomcat 1.第一次使用需要进行配置. 二.异常处理 1.404:浏览器访问的资源,在服务器上不存在. a.检查请求的路径和服务器配置的是否一致(大小写,空格,标点符号). b. 确认webapp是否被正确加载(检查web.xml没有/目录错误/内容错误/名字拼写错误)(多多关注日志信息). 2…

typeof的作用

typeof 是 JavaScript 中的一种运算符,用于获取给定值的数据类型。 它的作用是返回一个字符串,表示目标值的数据类型。通过使用 typeof 运算符,我们可以在运行时确定一个值的类型,从而进行相应的处理或逻辑判断。 常见的数据类型…

slam 点云退化

Lidar Slam退化问题分析报告 摘要:激光雷达在空旷区域存在点云采集数据较少,特征无法对机器人的位置起到约束的作用,考虑LIW融合对最终定位的影响。当错误的LIW即发生退化,位姿输出不准存在较大误差,如果未检测到退化…

MyBatis 插件机制

文章目录 前言自定义插件创建拦截器配置拦截器效果验证 插件实现原理初始化操作如何创建代理对象ExecutorStatementHandlerParameterHandlerResultSetHandler 执行流程 前言 插件是一种常见的扩展方式,大多数开源框架也都支持用户通过添加自定义插件的方式来扩展或…

Element树形控件使用过程中遇到的问题及解决方法

1.需求1点击编辑按钮&#xff0c;出现修改组织弹窗&#xff0c;且将点击时的组织名称返现在输入框中。 思路是点击编辑按钮&#xff0c;取到节点点击时返回的data信息中的label进行赋值即可。 <el-treestyle"margin-top: 20px":data"organizationTreeData…

vuex的state,getters,mutations,actions,modules

目录 Vuex核心概念&#xff1a;1、State1&#xff09;全局state2&#xff09;使用modules中的state 2、Getters1&#xff09;全局Getters2&#xff09;使用modules中的getters 3、Mutations1&#xff09;全局Mutations2&#xff09;使用modules中的mutations&#xff08;namesp…

自由职业者的福音来啦!人工智能带你智能规划,做你所擅长的事情

原创 | 文 BFT机器人 大多数人选择自由职业者是因为他们追求自由。你想一想&#xff0c;自雇或“为自己工作”伴随着选择客户和管理日程安排的诱惑。所以&#xff0c;自由职业者的数量正在增长也就不足为奇了。 这是经济与政策研究中心报告的&#xff0c;该中心在一项研究中发…

DT卡通学习二

相交线查找 轮廊线 和笔刷结合使用 材质

springboot实现监听

1、新建ApplicationEvent 在Spring Boot中实现监听器&#xff08;Listener&#xff09;的一种常见方式是使用Spring Boot的事件监听机制。 下面是一个简单的步骤说明&#xff0c;帮助你实现一个自定义的监听器&#xff1a; 创建事件&#xff1a;首先&#xff0c;你需要创建一…

CMake:测试的其他补充(重要)

CMake:测试的其他补充&#xff08;重要&#xff09; 导言预期测试失败项目结构CMakeLists.txt相关源码输出结果 使用超时测试运行时间过长的测试项目结构CMakeLists.txt相关源码输出结果 并行测试项目结构CMakeLists.txt相关源码输出结果 运行测试子集项目结构CMakeLists.txt相…