PyTorch Conv2d 前向传递中发生了什么?


在这里插入图片描述
💝💝💝欢迎莅临我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。
在这里插入图片描述

  • 推荐:「stormsha的主页」👈,持续学习,不断总结,共同进步,为了踏实,做好当下事儿~
  • 专栏导航
    • Python面试合集系列:Python面试题合集,剑指大厂
    • GO基础学习笔记系列:记录博主学习GO语言的笔记,该笔记专栏尽量写的试用所有入门GO语言的初学者
    • 数据库系列:详细总结了常用数据库 mysql 技术点,以及工作中遇到的 mysql 问题等
    • 运维系列:总结好用的命令,高效开发
    • 算法与数据结构系列:总结数据结构和算法,不同类型针对性训练,提升编程思维

非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。💝💝💝 ✨✨ 欢迎订阅本专栏 ✨✨

💖The Start💖点点关注,收藏不迷路💖

📒文章目录

  • 1、概述
  • 2、Conv2d 核心参数
    • 2.1、什么是卷积核(kernel)?
    • 2.2、可训练参数(Trainable Parameters)和偏置(Bias)
    • 2.3、输入通道和输出通道的数量(Number of Input and Output Channels)
    • 2.4、卷积核大小(Kernel size)
    • 2.5、步长(Strides)
    • 2.6、填充(Padding)
    • 2.7、膨胀(Dilation)
    • 2.8、组(Groups)
    • 2.9、输出通道大小(Output Channel Size)
  • 3、总结


1、概述

随着人功智能的发展,涌现出了很多深度学习的库和平台,如Tensorflow、Keras、Pytorch、Caffe或Theano,在我们的日常开发中为我们提供很多帮助,基于这些深度学习库的应用程序层出不穷也让我们感到惊叹。每个开发者都有自己最喜欢的框架,它们的共同点是易于使用且可根据需要进行配置使我们的工作变得简单。但我们还是需要了解这些工具可用的论据是什么,以便更好地利用这些框架赋予我们的所有功能。

在这篇文章中,我将尝试列出所有这些参数。如果你想了解它们对计算时间、可训练参数的数量以及卷积输出通道大小的影响,那么这篇文章适合你。
Input Shape : (3, 7, 7) — Output Shape : (2, 3, 3) — K : (3, 3) — P : (1, 1) — S : (2, 2) — D : (2, 2) — G : 1

Input Shape : (3, 7, 7) — Output Shape : (2, 3, 3) — K : (3, 3) — P : (1, 1) — S : (2, 2) — D : (2, 2) — G : 1

2、Conv2d 核心参数

这篇文章的部分内容将根据以下参数进行讲解。这些参数可以在 Pytorch Conv2d 模块的文档中找到

  • in_channels(int)- 输入图像的通道数
  • out_channels(int)- 卷积生成的通道数
  • kernel_size(int 或 tuple)- 卷积核的大小
  • stride(int 或 tuple,可选)- 卷积的步长。默认:1
  • padding(int 或 tuple,可选)- 添加到输入两侧的零填充。默认:0
  • dilation(int 或 tuple,可选)- 核元素之间的间距。默认:1
  • groups(int,可选)- 从输入通道到输出通道的块连接数。默认:1
  • bias(bool,可选)- 如果为 True,则在输出中添加可学习的偏置。默认:True

最后,我们将掌握根据参数和输入通道大小计算输出通道大小的所有关键点。

2.1、什么是卷积核(kernel)?

输入图像和内核之间的卷积过程

输入图像和kernel之间的卷积过程

先介绍一下 kernel(或卷积矩阵)是什么。 kernel 描述了我们将要在一个输入图像上进行卷积操作的滤波器。简单来说, kernel 会在整个图像上移动,从左到右,从上到下,通过应用卷积运算。这个操作的输出被称为过滤图像。

卷积积

卷积积(Convolution product)

在这里插入图片描述

Input shape : (1, 9, 9) — Output Shape : (1, 7, 7) — K : (3, 3) — P : (0, 0) — S : (1, 1) — D : (1, 1) — G : 1

举一个非常基本的例子,让我们想象一个3乘3的卷积核对一个9乘9的图像进行过滤。然后,这个卷积核(Convolution Kernel)会在整个图像上移动,以捕捉图像中所有相同大小的方块(3乘3)。卷积积(Convolution product)是一种元素级(或点积)的乘法。这个结果的总和就是输出(或过滤后)图像上的像素值。

如果你对滤波器和卷积矩阵还不熟悉,那么我强烈建议你花更多的时间来理解卷积核(Convolution Kernel)。它们是二维卷积层的核心。

2.2、可训练参数(Trainable Parameters)和偏置(Bias)

可训练参数,也被称为“参数”,是在网络训练过程中将被更新的所有参数。在Conv2d中,可训练的元素是构成卷积核的值。所以对于我们的3乘3卷积核,我们有3*3=9个可训练参数。
卷积积(Convolution Product)与偏置(Bias)

卷积积(Convolution Product)与偏置(Bias)

为了更完整,我们可以包括偏置或不包含。偏置的作用是被添加到卷积积的总和中。这个偏置也是一个可训练参数,这使得我们3乘3卷积核的可训练参数数量上升到10个。

2.3、输入通道和输出通道的数量(Number of Input and Output Channels)

请添加图片描述

Input Shape: (1, 7, 7) — Output Shape : (4, 5, 5) — K : (3, 3) — P : (0, 0) — S : (1, 1) — D : (1, 1) — G : 1

使用层级结构的优势在于能够同时执行类似的操作。换句话说,如果我们想对一个输入通道应用4个相同大小的不同滤波器,那么我们将得到4个输出通道。这些通道是4个不同滤波器的结果。所以来自于4个不同的卷积核

在这里插入图片描述
随着卷积核数量的增加,参数的数量也会线性增加。因此,它也与所需的输出通道数量成线性关系。同样需要注意的是,计算时间也与输入通道的大小和卷积核的数量成正比。

在这里插入图片描述

参数图中的曲线是相同的

同样的原则也适用于输入通道的数量。让我们考虑一个使用RGB编码的图像的情况。这个图像有3个通道:红、蓝和绿。我们可以决定使用相同大小的滤波器在这三个通道上提取信息,以获得四个新的通道。因此,这个操作在三个通道上是相同的,用于获得四个输出通道。

在这里插入图片描述

Input Shape: (3, 7, 7) — Output Shape : (4, 5, 5) — K : (3, 3) — P : (0, 0) — S : (1, 1) — D : (1, 1) — G : 1

每个输出通道是过滤后的输入通道的总和。对于4个输出通道和3个输入通道,每个输出通道是3个过滤后的输入通道的总和。换句话说,卷积层由4*3=12个卷积核组成。
在这里插入图片描述
参数的数量和计算时间与输出通道的数量成正比。这是因为每个输出通道都与与其他通道不同的卷积核相关联。对于输入通道的数量也是如此。计算时间和参数数量会按比例增长。

在这里插入图片描述

2.4、卷积核大小(Kernel size)

到目前为止,所有的例子都是使用3乘3大小的卷积核。事实上,选择它的大小完全取决于你。你可以创建一个具有11或1919大小的卷积层。

并不是必须使用正方形的卷积核。可以选择具有不同高度和宽度的卷积核。这在信号图像分析中经常出现。如果我们知道我们想要扫描一个信号或声音的图像,那么我们可能更喜欢使用5*1大小的卷积核。如下图所示:
在这里插入图片描述

Input Shape: (3, 7, 9) — Output Shape : (2, 3, 9) — K : (5, 2) — P : (0, 0) — S : (1, 1) — D : (1, 1) — G : 1

你会注意到所有大小都由奇数定义。定义一个偶数的卷积核大小也是可以接受的。但在实践中,这很少做。通常选择奇数大小的卷积核,因为在中心像素周围有对称性。
在这里插入图片描述
由于卷积层的所有(经典)可训练参数都在卷积核中,所以参数的数量随着卷积核大小的增加而线性增长。计算时间也成比例变化。

2.5、步长(Strides)

默认情况下,卷积核从左到右、从上到下逐个像素进行移动。但这种移动也可以改变。通常用于对输出通道进行降采样。例如,使用步长为(1, 3),滤波器在水平方向上每3个像素移动一次,在垂直方向上每1个像素移动一次。这将产生水平方向上降采样3倍的输出通道。
在这里插入图片描述

Input Shape: (3, 9, 9) — Output Shape : (2, 7, 3) — K : (3, 3) — P : (0, 0) — S : (1, 3) — D : (1, 1) — G : 1

在这里插入图片描述
步长对参数数量没有影响,但计算时间会随着步长的增加而线性减少。

2.6、填充(Padding)

填充是指在对输入通道进行卷积滤波之前,添加到输入通道边缘的像素数量。通常,填充像素被设置为零。输入通道被扩展。
在这里插入图片描述

Input Shape : (2, 7, 7) — Output Shape : (1, 7, 7) — K : (3, 3) — P : (1, 1) — S : (1, 1) — D : (1, 1) — G : 1

当您希望输出通道的大小等于输入通道的大小时,这非常有用。简单来说,当卷积核为3*3时,输出通道的大小在每个方向上减小一个像素。为了解决这个问题,我们可以使用1个像素的填充。

在这里插入图片描述

参数图中的曲线是相同的。

因此,填充对参数数量没有影响,但会产生与填充大小成正比的额外计算时间。但通常来说,填充相对于输入通道的大小来说通常足够小,可以认为对计算时间没有影响。

2.7、膨胀(Dilation)

膨胀可以看作是卷积核的宽度。默认情况下等于1,它对应于卷积过程中卷积核在输入通道上的每个像素之间的偏移量。
在这里插入图片描述

Input Shape: (2, 7, 7) — Output Shape : (1, 1, 5) — K : (3, 3) — P : (1, 1) — S : (1, 1) — D : (4, 2) — G : 1

在GIF图中有点夸张,但如果我们以(4, 2)的膨胀为例,那么卷积核在输入通道上的感受野在垂直方向上会扩大4 * (3 -1)=8个像素,在水平方向上会扩大2 * (3-1)=4个像素(对于一个3乘3的卷积核)。

在这里插入图片描述

参数图中的曲线是相同的。

就像填充一样,膨胀对参数数量没有影响,对计算时间的影响也非常有限。

2.8、组(Groups)

在某些特定情况下,组可以非常有用。例如,如果我们有多个连接的数据源。当没有必要将它们相互依赖地处理时,输入通道可以分组并独立处理。最后,输出通道在结束时连接在一起。

如果有2个输入通道和4个输出通道,并且有2个组。那么这就像将输入通道分成两个组(每个组中有1个输入通道),并通过一个输出通道数量减半的卷积层。然后输出通道被连接在一起。
请添加图片描述

Input Shape : (2, 7, 7) — Output Shape : (4, 5, 5) — K : (3, 3) — P : (2, 2) — S : (2, 2) — D : (1, 1) — G : 2

需要注意的是,组的数量必须能够整除输入通道的数量和输出通道的数量(公因数)。
在这里插入图片描述
因此,参数的数量被组的数量所除。至于使用Pytorch的计算时间,算法针对组进行了优化,因此应该减少计算时间。然而,也应该考虑到必须将组的形成和输出通道的连接的计算时间相加。

2.9、输出通道大小(Output Channel Size)

有了所有参数的知识,就可以根据输入通道的大小计算输出通道的大小。
在这里插入图片描述

3、总结

所有计算时间测试都是使用Pytorch在我的GPU(GeForce GTX 960M)上进行的,如果你想自己运行它们或进行其他测试,Gitee仓库地址:https://gitee.com/stormsha/conv2d_demo

以上所有的GIF图像都是由Python生成,源码地址:Gitee仓库地址:https://gitee.com/stormsha/conv2d_demo

参考

Deep Learning Tutorial, Y. LeCun

Documentation torch.nn, Pytorch

Convolutional Neural Networks, cs231n

Convolutional Layers, Keras


❤️❤️❤️本人水平有限,如有纰漏,欢迎各位大佬评论批评指正!😄😄😄

💘💘💘如果觉得这篇文对你有帮助的话,也请给个点赞、收藏、分享下吧,非常感谢!👍 👍 👍

🔥🔥🔥道阻且长,行则将至,让我们一起加油吧!🌙🌙🌙

💖The End💖点点关注,收藏不迷路💖

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

决策大模型专题(一)

决策智能不应该停留在以前的思维中了,现在开一个专题来学习一下决策论坛的老师们的精彩的内容。本内容来自决策大模型论坛,张伟楠老师的内容整理。 决策大模型 是新一代人工智能的底层技术,它可以去赋能,智能体也就是AI agent&a…

C++进阶:map与set容器的使用

目录 1. 关联式容器map与set2. set与multiset的接口与使用2.1 set的接口与使用2.1.1 成员函数2.1.2 迭代器2.1.3 容量相关2.1.4 修改相关 2.1.5 查找,计数与补充2.2 multiset的接口与使用 3. map与multimap的接口与使用3.1 map的接口与使用3.1.1 map的使用补充3.1.2…

小孩子不懂事,写着玩的

目录 Web攻防 特有漏洞 ASP安全 ASPX(.NET)安全 PHP安全 JavaWeb安全 JS,Node.js安全 Java安全 Python安全 通用漏洞 SQL注入 MySQL-root高权限读写注入 PostgreSQL-高权限读写注入 MSSQL-sa高权限读写执行注入 SQL注入体系 o…

QWidget 类

QWidget 类中包括框架的属性 QWidget 类中不包括框架的属性 总结:可使用以下两种方法设置部件的位置和大小 ①、通常使用 move()设置部件的位置,使用 resize()设置部件的大小。 ②、使用 setGeometry()函数同时设置部件的位置和大小。 ③、无法为部件指定包含边框在内的大…

C语言操作符和关键字

文章目录 操作符单目操作符sizeof(类型)强制类型转换 关系操作符、逻辑操作符、条件操作符逗号表达式 常见关键字typedefstaticstatic修饰局部变量static修饰全局变量static修饰函数 register寄存器关键词define定义常量和宏 操作符 单目操作符 C语言中…

echarts bar图表实现多个label显示

2024.0.23今天我学习了使用bar组件,可以渲染多个label显示的效果,如: 当我们有一个这样的图表时,根据需求需要在 这上面的顶部再显示一个空置床位数占用床位数的合计总值,如果直接添加一个label肯定是不行,…

深度学习-线性代数

目录 标量向量矩阵特殊矩阵特征向量和特征值 标量由只有一个元素的张量表示将向量视为标量值组成的列表通过张量的索引来访问任一元素访问张量的长度只有一个轴的张量,形状只有一个元素通过指定两个分量m和n来创建一个形状为mn的矩阵矩阵的转置对称矩阵的转置逻辑运…

[MYSQL索引优化] 分页查询优化

这里一共介绍两种常见的分页索引优化技巧,let go! 示例表: CREATE TABLE t_product (id int(0) NOT NULL,pname varchar(200) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,price double(7, 2) NULL DEFAULT 0.00,promoteSales varchar(200) CHARA…

Linux进程详解三:进程状态

文章目录 进程状态Linux下的进程状态运行态-R阻塞态浅度休眠-S深度睡眠-D暂停状态-T暂停状态-t 终止态僵尸-Z死亡-X 孤儿进程 进程状态 进程的状态,本质上就是一个整型变量,在task_struct中的一个整型变量。 状态的存在决定了你的后续行为动作。 Linu…

DRF: 序列化器、View、APIView、GenericAPIView、Mixin、ViewSet、ModelViewSet的源码解析

前言:还没有整理,后续有时间再整理,目前只是个人思路,文章较乱。 注意路径匹配的“/” 我们的url里面加了“/”,但是用apifox等非浏览器的工具发起请求时没有加“/”,而且还不是get请求,那么这…

C++字符串中单词的提取以及按符号分隔

句子中的单词提取利用stringstream即可 如果要分割需配合getline使用 两者前提都是要先转化为字符串流。

Linux套接字编程详解

Linux套接字编程 预备知识IP地址和MAC地址套接字结构网络字节序 UDP套接字编程服务端代码客服端代码 TCP 套接字守护进程 计算器模块1 日志头文件序列化和反序列化 预备知识 IP地址和MAC地址 MAC地址用来在局域网中标识唯一主机 Ip地址用于在广域网中标识唯一主机 &#xff0…

李廉洋:4.24-4.25现货黄金,WTI原油区间震荡,走势分析。

黄金消息面分析:金银近日回调。随着伊朗方面淡化以色列最新反击,中东地区局势没有进一步发酵下,风险溢价下降金银出现较大幅度调整。由于近期高于预期的通胀数据,降息预期持续降温。昨日疲软的美国PMI以及以色列在加沙攻击的加剧支…

【Unity】AssetBundle加载与卸载

unity官方apiAssetBundle-LoadFromFileAsync - Unity 脚本 API 异步加载AB包 using UnityEngine; using System.Collections; using System.IO;public class LoadFromFileAsyncExample : MonoBehaviour {IEnumerator Start(){var bundleLoadRequest AssetBundle.LoadFromFil…

消息服务应用1——java项目使用websocket

在当前微服务项目中,由于业务模块众多,消息服务的使用场景变得异常活跃。而WebSocket由于其自身的可靠性强,实时性好,带宽占用更小的优势,在实时通讯应用场景中独占鳌头,加上HTML5标准的普及流行&#xff0…

OpenCompass 大模型评测实战——笔记

OpenCompass 大模型评测实战——笔记 一、评测1.1、为什么要做评测1.2、如何通过能力评测促进模型发展1.2.1、面向未来拓展能力维度1.2.2、扎根通用能力1.2.3、高质量1.2.4、性能评测 1.3、评测的挑战1.3.1、全面性1.3.2、评测成本1.3.3、数据污染1.3.4、鲁棒性 二、OpenCompas…

java-junit单元测试

问题 Junit框架 代码 工具类 // 工具类 public class StringUtils {// 获取字符串的最大下标public static int getMaxIndex(String str){// 这个地方是有问题的,应该是str.length() - 1 也没有进行str是否为空的判断return str.length() ;} }测试类 测试类类名&…

vcontact2:病毒聚类(失败)

Bitbucket 安装 mamba create --name vContact2 biopython1.78 mamba install -c bioconda vcontact20.11.3vim ~/envs/vContact2/lib/python3.9/site-packages/vcontact2/exports/summaries.py 把 np.warnings.filterwarnings(ignore) 改成 import warnings warnings.filte…

递归、搜索与回溯算法:FloodFill 算法

例题一 算法思路: 可以利⽤「深搜」或者「宽搜」,遍历到与该点相连的所有「像素相同的点」,然后将其修改成指定的像素即可。 全局变量: int dx[4] { 0,0,1,-1 }, dy[4] { 1,-1,0,0 }; int m, n; int precolor;//记录原先的颜色…

【Linux】日志分析与管理

作为一个运维,如果不会看日志,就好比是冬天刚刚用热水泡完了脚,接着就立马让人把水喝掉。 目录 一、Inode介绍 1.1 什么是inode 1.2 inode表内容 1.3 查看inode号的方式 二、日志分析 2.1 日志的用途 2.2 日志的分类 2.3 日志级别 2…