动手学深度学习6.3 填充和步幅-笔记练习(PyTorch)

以下内容为结合李沐老师的课程和教材补充的学习笔记,以及对课后练习的一些思考,自留回顾,也供同学之人交流参考。

本节课程地址:填充和步幅_哔哩哔哩_bilibili 代码实现_哔哩哔哩_bilibili

本节教材地址:6.3. 填充和步幅 — 动手学深度学习 2.0.0 documentation (d2l.ai)

本节开源代码:...>d2l-zh>pytorch>chapter_multilayer-perceptrons>padding-and-strides.ipynb


填充和步幅

在前面的例子 图6.2.1 中,输入的高度和宽度都为3,卷积核的高度和宽度都为2,生成的输出表征的维数为2×2。 正如我们在 6.2节 中所概括的那样,假设输入形状为 n_h\times n_w ,卷积核形状为 k_h\times k_w ,那么输出形状将是 (n_h-k_h+1) \times (n_w-k_w+1) 。 因此,卷积的输出形状取决于输入形状和卷积核的形状。

还有什么因素会影响输出的大小呢?本节我们将介绍填充(padding)和步幅(stride)。假设以下情景: 有时,在应用了连续的卷积之后,我们最终得到的输出远小于输入大小。这是由于卷积核的宽度和高度通常大于1所导致的。比如,一个240 × 240像素的图像,经过10层5 × 5的卷积后,将减少到200 × 200像素。如此一来,原始图像的边界丢失了许多有用信息。而填充是解决此问题最有效的方法; 有时,我们可能希望大幅降低图像的宽度和高度。例如,如果我们发现原始的输入分辨率十分冗余。步幅则可以在这类情况下提供帮助。

填充

如上所述,在应用多层卷积时,我们常常丢失边缘像素。 由于我们通常使用小卷积核,因此对于任何单个卷积,我们可能只会丢失几个像素。 但随着我们应用许多连续卷积层,累积丢失的像素数就多了。 解决这个问题的简单方法即为填充(padding):在输入图像的边界填充元素(通常填充元素是0)。 例如,在 图6.3.1 中,我们将3 × 3输入填充到5 × 5,那么它的输出就增加为4 × 4。阴影部分是第一个输出元素以及用于输出计算的输入和核张量元素: 0\times0+0\times1+0\times2+0\times3=0 。

通常,如果我们添加 p_h 行填充(大约一半在顶部,一半在底部)和 p_w 列填充(左侧大约一半,右侧一半),则输出形状将为

(n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1).

这意味着输出的高度和宽度将分别增加 p_h 和 p_w 。

在许多情况下,我们需要设置 p_h=k_h-1 和 p_w=k_w-1 ,使输入和输出具有相同的高度和宽度。 这样可以在构建网络时更容易地预测每个图层的输出形状。假设 k_h 是奇数,我们将在高度的两侧填充 p_h/2 行。 如果 k_h 是偶数,则一种可能性是在输入顶部填充 \lceil p_h/2\rceil 行(向上取整),在底部填充 \lfloor p_h/2\rfloor 行(向下取整)。同理,我们填充宽度的两侧。

卷积神经网络中卷积核的高度和宽度通常为奇数,例如1、3、5或7。 选择奇数的好处是,保持空间维度的同时,我们可以在顶部和底部填充相同数量的行,在左侧和右侧填充相同数量的列。

此外,使用奇数的核大小和填充大小也提供了书写上的便利。对于任何二维张量X,当满足: 1. 卷积核的大小是奇数; 2. 所有边的填充行数和列数相同; 3. 输出与输入具有相同高度和宽度 则可以得出:输出Y[i, j]是通过以输入X[i, j]为中心,与卷积核进行互相关计算得到的。

比如,在下面的例子中,我们创建一个高度和宽度为3的二维卷积层,并(在所有侧边填充1个像素)。给定高度和宽度为8的输入,则输出的高度和宽度也是8。

import torch
from torch import nn# 为了方便起见,我们定义了一个计算卷积层的函数。
# 此函数初始化卷积层权重,并对输入和输出提高和缩减相应的维数
def comp_conv2d(conv2d, X):# 这里的(1,1)表示批量大小和通道数都是1X = X.reshape((1, 1) + X.shape)Y = conv2d(X)# 省略前两个维度:批量大小和通道return Y.reshape(Y.shape[2:])# 请注意,这里每边都填充了1行或1列,因此总共添加了2行或2列
conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1)
X = torch.rand(size=(8, 8))
comp_conv2d(conv2d, X).shape

输出结果:
torch.Size([8, 8])

当卷积核的高度和宽度不同时,我们可以[填充不同的高度和宽度],使输出和输入具有相同的高度和宽度。在如下示例中,我们使用高度为5,宽度为3的卷积核,高度和宽度两边的填充分别为2和1。

conv2d = nn.Conv2d(1, 1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape

输出结果:
torch.Size([8, 8])

步幅

在计算互相关时,卷积窗口从输入张量的左上角开始,向下、向右滑动。 在前面的例子中,我们默认每次滑动一个元素。 但是,有时候为了高效计算或是缩减采样次数,卷积窗口可以跳过中间位置,每次滑动多个元素。

我们将每次滑动元素的数量称为步幅(stride)。到目前为止,我们只使用过高度或宽度为1的步幅,那么如何使用较大的步幅呢? 图6.3.2 是垂直步幅为3,水平步幅为2的二维互相关运算。 着色部分是输出元素以及用于输出计算的输入和内核张量元素:

0\times0+0\times1+1\times2+2\times3=8 、

0\times0+6\times1+0\times2+0\times3=6 。

可以看到,为了计算输出中第一列的第二个元素和第一行的第二个元素,卷积窗口分别向下滑动三行和向右滑动两列。但是,当卷积窗口继续向右滑动两列时,没有输出,因为输入元素无法填充窗口(除非我们添加另一列填充)。

通常,当垂直步幅为 s_h 、水平步幅为 s_w 时,输出形状为

\lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor.

如果我们设置了 p_h=k_h-1 和 p_w=k_w-1 ,则输出形状将简化为 \lfloor(n_h+s_h-1)/s_h\rfloor \times \lfloor(n_w+s_w-1)/s_w\rfloor 。 更进一步,如果输入的高度和宽度可以被垂直和水平步幅整除,则输出形状将为 (n_h/s_h) \times (n_w/s_w) (通常步幅取2)。

下面,我们[将高度和宽度的步幅设置为2],从而将输入的高度和宽度减半。

conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)
comp_conv2d(conv2d, X).shape

输出结果:
torch.Size([4, 4])

接下来,看(一个稍微复杂的例子)。

conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))
comp_conv2d(conv2d, X).shape

输出结果:
torch.Size([2, 2])

为了简洁起见,当输入高度和宽度两侧的填充数量分别为 p_h 和 p_w 时,我们称之为填充 (p_h, p_w) 。当 (p_h, p_w) 时,填充是 p 。同理,当高度和宽度上的步幅分别为 s_h 和 s_w 时,我们称之为步幅 (s_h, s_w) 。特别地,当 s_h = s_w = s 时,我们称步幅为 s 。默认情况下,填充为0,步幅为1。在实践中,我们很少使用不一致的步幅或填充,也就是说,我们通常 p_h = p_w 和 s_h = s_w 。

小结

  • 填充可以增加输出的高度和宽度。这常用来使输出与输入具有相同的高和宽。
  • 步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的1/n(n是一个大于1的整数)。
  • 填充和步幅可用于有效地调整数据的维度,均为卷积层的超参数。

练习

1. 对于本节中的最后一个示例,计算其输出形状,以查看它是否与实验结果一致。
解:
根据 \lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor,

可计算得出输出形状为: \lfloor(8-3+0+3)/3\rfloor \times \lfloor(8-5+2+4)/4\rfloor ,

取整为 2×2 ,与实验结果一致。

2. 在本节中的实验中,试一试其他填充和步幅组合。
解:
比如,设置卷积核尺寸为3×5,高度两侧填充为2,宽度两侧填充为1,高度步幅为4,宽度步幅为1;当输入尺寸为8×8时,输出尺寸应为3×6。
代码如下:

conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(2, 1), stride=(4, 1))
comp_conv2d(conv2d, X).shape

输出结果:
torch.Size([3, 6])

3. 对于音频信号,步幅2说明什么?
解:
说明在时间轴上每隔一个样本进行一次卷积,这么做可以提高计算效率和频率分辨率,但可能会牺牲一些时间分辨率和信号细节。

4. 步幅大于1的计算优势是什么?
解:
当步幅>1时,可以在卷积核尺寸较小的情况下,以更少的计算量和层数,实现输入到输出尺寸的快速降维,这种做法可以显著降低模型复杂度、减少内存使用。

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

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

相关文章

Linux下Qt程序打包

文章目录 一、前言二、linuxdeployqt下载安装三、Qt环境变量配置四、准备Qt可执行文件五、打包六、封装成deb安装包 一、前言 在Windows下进行Qt开发,软件开发好之后可以使用windeployqt进行打包,然后程序就可以移动到其它电脑上运行了 在Linux下同样可…

浅析stm32启动文件

浅析stm32启动文件 文章目录 浅析stm32启动文件1.什么是启动文件?2.启动文件的命名规则3.stm32芯片的命名规则 1.什么是启动文件? 我们来看gpt给出的答案: STM32的启动文件是一个关键的汇编语言源文件,它负责在微控制器上电或复位…

开箱即用的AI!九州未来亓绚AI教培一体机全新发布

以大模型、生成式人工智能为代表的人工智能技术在全球引起广泛关注,亦成为催生教育变革的重要力量。 中小学人工智能教育逐步推进,但实施过程中仍然面对诸多挑战。如何更广泛、高质量地开展中小学人工智能教育,成为当下我国教育改革创新的重…

CentOS7 虚谷数据库 单机版部署

单机版最低配置: 安装环境配置 1.CPU设置 关闭 CPU 超线程 查看当前CPU超线程状态: cat /sys/devices/system/cpu/smt/active 如果是0,表示超线程已关闭;返回值是1,表示超线程已开启。 切换超线程状态: &a…

景区客流统计系统提升服务精准度

在当今旅游业蓬勃发展的时代,景区面临着越来越多的挑战和机遇。如何在保障游客良好体验的同时,实现景区的高效管理和可持续发展,成为了摆在景区管理者面前的重要课题。景区客流统计系统的出现,为解决这一问题提供了有力的支持&…

vscode 打开远程bug vscode Failed to parse remote port from server output

vscode 打开远程bug vscode Failed to parse remote port from server output 原因如图: 解决:

Redis实战—附近商铺、用户签到、UV统计

本博客为个人学习笔记,学习网站与详细见:黑马程序员Redis入门到实战 P88 - P95 目录 附近商铺 数据导入 功能实现 用户签到 签到功能 连续签到统计 UV统计 附近商铺 利用Redis中的GEO数据结构实现附近商铺功能,常见命令如下图所示。…

Monsters Pack 04(游戏卡通可爱怪兽怪物战士模型)

以下模型有3种进化形态: 捕手战士 鱼卫战士 骑士战士 小鬼战士 猴东战士 无鼻战士 坑娃战士 刺头战士 树斯特战士 楔形战士 这些模型是为您的主要角色设计的敌人。进化的每个阶段都会使他变得更加强大,因此您可以用它来增强对手的实力,并作为敌人的boss。 它适用于不同类型的…

算法实验3:贪心算法的应用

实验内容 &#xff08;1&#xff09;活动安排问题 设有n个活动的集合E{1, 2, …, n}&#xff0c;其中每个活动都要求使用同一资源&#xff0c;而在同一时间内只有一个活动能使用这一资源。每个活动i都有一个要求使用该资源的起始时间si和一个结束时间fi&#xff0c;且si <f…

厂家置换电费如何达到最大化收益

新能源行业知识体系-------主目录-----持续更新https://blog.csdn.net/grd_java/article/details/140004020 文章目录 一、电能电费二、同时刻不同厂家置换&#xff0c;不会影响最终电能电费结果三、风险防范补偿和回收机制四、我们的数据如何考虑补偿和回收五、如何利用补偿和…

java.lang.IllegalArgumentException: Illegal character in path at index 40解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…

RFID涉密载体管控系统|DW-S402功能介绍

文件载体管控系统DW-S402是用于对各种载体进行有效管理的智能柜&#xff08;智能管理系统&#xff09;&#xff0c;实现对载体的智能化、规范化、标准化管理&#xff0c;广泛应用于保密、机要单位以及企事业单位等有载体保管需求的行业。 区域监控管理 主要是通过在需要监控的…

Mysql缓存调优的基本知识(附Demo)

目录 前言1. 配置2. 缓存3. 策略 前言 基本的知识推荐阅读&#xff1a; java框架 零基础从入门到精通的学习路线 附开源项目面经等&#xff08;超全&#xff09;Mysql优化高级篇&#xff08;全&#xff09;Mysql底层原理详细剖析常见面试题&#xff08;全&#xff09; MySQL…

视图库对接系列(GA-T 1400)十九、视图库对接系列(级联)注册

背景 在上一章视图库对接系列(GA-T 1400)十八、视图库对接系列(级联)代码生成中我们已经把代码生成了,那怎么实现级联? 我们可以抓包看设备是怎么注册到我们平台的, 那我们就怎么实现就可以了。 实现 先看设备注册到我们服务端的包 步骤 注册我们可以参考视图库对接系列(…

【贪心算法】贪心算法30题

一、贪心算法简介 证明贪心策略正确性的常用方法&#xff1a;直接证明、交换论证法、反证法、分类讨论… 二、相关编程题 2.1 柠檬水找零 题目链接 860. 柠檬水找零 - 力扣&#xff08;LeetCode&#xff09; 题目描述 算法原理 提示&#xff1a;最优解和贪心解唯一可能不同…

学习大数据DAY17 PLSQL基础语法6和Git的基本操作

目录 包 存储过程调试功能 作业 阶段复习作业 Git课程目录 什么是版本控制 没有版本控制的缺点 常见的版本工具 版本控制分类 1. 本地版本控制 2. 集中版本控制 3. 分布式版本控制 Git与SVN主要区别 Git软件安装及配置 Windows系统安装Git 安装Tortoise Git(乌龟…

鸿蒙开发:Universal Keystore Kit(密钥管理服务)【获取密钥属性(C/C++)】

获取密钥属性(C/C) HUKS提供了接口供业务获取指定密钥的相关属性。在获取指定密钥属性前&#xff0c;需要确保已在HUKS中生成或导入持久化存储的密钥。 在CMake脚本中链接相关动态库 target_link_libraries(entry PUBLIC libhuks_ndk.z.so)开发步骤 构造对应参数。 keyAlias&…

生成树(STP)协议

一、生成树的技术背景 1、交换机单线路上链,存在单点故障,上行线路及设备都不具备冗余性,一旦链路或上行设备发生故障,网络将面临断网。 总结:以下网络不够健壮,不具备冗余性。 2、因此引入如下网络拓扑结构: 上述冗余拓扑能够解决单点故障问题,但同时冗拓扑也带来了…

【PB案例学习笔记】-32制作一个简单记事本程序

大家好&#xff0c;我是晓凡。 写在前面 这是PB案例学习笔记系列文章的第32篇&#xff0c;该系列文章适合具有一定PB基础的读者。 通过一个个由浅入深的编程实战案例学习&#xff0c;提高编程技巧&#xff0c;以保证小伙伴们能应付公司的各种开发需求。 文章中设计到的源码…

【信息系统项目管理师】高项论文通用加分素材

文章目录 输入I工具与技术TT输出O 写一些增加项目真实性的问题&#xff0c;如变更、进度&#xff08;范围蔓延、进度延后怎么处理、好几个项目并行资源协调&#xff09;||成本、沟通&#xff08;跨部门沟通&#xff09; 在保障真实性的同时选的项目紧跟潮流 要能看出实际经验 …