pytorch 中 nn.Conv2d 解释

news2024/12/22 18:11:01

1. pytorch nn.Con2d 中填充模式

torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True, padding_mode=‘zeros’, device=None, dtype=None)

1.1 padding 参数的含义

首先 ,padd = N, 代表的是 分别在 上下,左右 这四个方向上都填充 N 个数值;

举例, 如果 padd = N = 1, 那么代表是 在 上下左右 都填充1 个数值, 那么 此时原始的输入矩阵便会增加 2* N 行, 2* N 列, 这里便是增加了 2行2 列;

这样 我们 就会理解, 为什么 计算2维 卷积的输出的时候,

[ i + 2 ∗ p a d d i n g − k e r n e l s i z e ] 下取整 / s t r i d e + 1 ; [ i + 2*padding -kernel_{size} ]下取整 / stride + 1; [i+2paddingkernelsize]下取整/stride+1;

1.2 padding_mode 参数

该参数便是规定了, padding 的时候 如何生成这些padding 的具体数值,
即以何种方法 生成padding 数值;

PyTorch二维卷积函数 torch.nn.Conv2d() 有一个“padding_mode”的参数,可选项有4种:‘zeros’, ‘reflect’,
‘replicate’ or ‘circular’,其默认选项为’zeros’,也就是零填充。这四种填充方式到底是怎么回事呢?

padding_mode (string, optional): `'zeros'`, `'reflect'`,  
        `'replicate'` or `'circular'`. Default: `'zeros'` 

为了直观的观察这4种填充方式,我们定义一个1*1卷积,并将卷积核权重设置为1,这样在进行不同填充方式的卷积计算后,我们即可得到填充后的矩阵。本例中我们生成一个由1~16组成的4*4矩阵,对其进行不同填充方式的卷积计算。

 In [51]: x = torch.nn.Parameter(torch.reshape(torch.range(1,16),(1,1,4,4)))

In [52]: x
Out[52]:
Parameter containing:
tensor([[[[ 1.,  2.,  3.,  4.],
          [ 5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12.],
          [13., 14., 15., 16.]]]], requires_grad=True) 
1.‘zeros’

'zeros’就是最常见的零填充,即在矩阵的高、宽两个维度上用0进行填充,填充时将在一个维度的两边都进行填充。

 In [53]: conv_zeros = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=False)

In [54]: conv_zeros
Out[54]: Conv2d(1, 1, kernel_size=(1, 1), stride=(1, 1), padding=(1, 1), bias=False)

In [55]: conv_zeros.weight = torch.nn.Parameter(torch.ones(1,1,1,1))

In [56]: conv_zeros.weight
Out[56]:
Parameter containing:
tensor([[[[1.]]]], requires_grad=True)

In [57]: conv_zeros(x)
Out[57]:
tensor([[[[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  1.,  2.,  3.,  4.,  0.],
          [ 0.,  5.,  6.,  7.,  8.,  0.],
          [ 0.,  9., 10., 11., 12.,  0.],
          [ 0., 13., 14., 15., 16.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]]]], grad_fn=<ThnnConv2DBackward>) 

如果 将其中的 bias 参数设置 为 True:
在这里插入图片描述

x = torch.nn.Parameter(torch.reshape(torch.range(1,16),(1,1,4,4)))
conv_zeros = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=False)
conv_zeros_bias = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=True)
conv_zeros.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
conv_zeros(x)
tensor([[[[ 0.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  1.,  2.,  3.,  4.,  0.],
          [ 0.,  5.,  6.,  7.,  8.,  0.],
          [ 0.,  9., 10., 11., 12.,  0.],
          [ 0., 13., 14., 15., 16.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.]]]],
       grad_fn=<MkldnnConvolutionBackward>)
conv_zeros_bias(x)
tensor([[[[ 0.5259,  0.5259,  0.5259,  0.5259,  0.5259,  0.5259],
          [ 0.5259,  0.4084,  0.2909,  0.1734,  0.0559,  0.5259],
          [ 0.5259, -0.0616, -0.1791, -0.2966, -0.4141,  0.5259],
          [ 0.5259, -0.5316, -0.6492, -0.7667, -0.8842,  0.5259],
          [ 0.5259, -1.0017, -1.1192, -1.2367, -1.3542,  0.5259],
          [ 0.5259,  0.5259,  0.5259,  0.5259,  0.5259,  0.5259]]]],
       grad_fn=<MkldnnConvolutionBackward>)


在这里插入图片描述

那么问题来了, 设置 bias 是否为 True,
同样的 输入, 同样的 可学习参数权重,
只要设置 bias , 将会得到不同的 结果?

那么 bias 到底 起到什么作用呢?

2.‘reflect’

'reflect’是以矩阵边缘为对称轴,将矩阵中的元素对称的填充到最外围。

 In [58]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='reflect',bias=False)

In [59]: conv_reflect.weight = torch.nn.Parameter(torch.ones(1,1,1,1))

In [60]: conv_reflect(x)
Out[60]:
tensor([[[[ 6.,  5.,  6.,  7.,  8.,  7.],
          [ 2.,  1.,  2.,  3.,  4.,  3.],
          [ 6.,  5.,  6.,  7.,  8.,  7.],
          [10.,  9., 10., 11., 12., 11.],
          [14., 13., 14., 15., 16., 15.],
          [10.,  9., 10., 11., 12., 11.]]]], grad_fn=<ThnnConv2DBackward>) 
3.‘replicate’

'replicate’将矩阵的边缘复制并填充到矩阵的外围。

 In [61]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='replicate',bias=False)

In [62]: conv_reflect.weight = torch.nn.Parameter(torch.ones(1,1,1,1))

In [63]: conv_replicate(x)
Out[63]:
tensor([[[[ 1.,  1.,  2.,  3.,  4.,  4.],
          [ 1.,  1.,  2.,  3.,  4.,  4.],
          [ 5.,  5.,  6.,  7.,  8.,  8.],
          [ 9.,  9., 10., 11., 12., 12.],
          [13., 13., 14., 15., 16., 16.],
          [13., 13., 14., 15., 16., 16.]]]], grad_fn=<ThnnConv2DBackward>) 
4.‘circular’

顾名思义,'circular’就是循环的进行填充,怎么循环的呢?先看例子:

 In [64]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='circular',bias=False)

In [65]: conv_reflect.weight = torch.nn.Parameter(torch.ones(1,1,1,1))

In [66]: conv_circular(x)
Out[66]:
tensor([[[[16., 13., 14., 15., 16., 13.],
          [ 4.,  1.,  2.,  3.,  4.,  1.],
          [ 8.,  5.,  6.,  7.,  8.,  5.],
          [12.,  9., 10., 11., 12.,  9.],
          [16., 13., 14., 15., 16., 13.],
          [ 4.,  1.,  2.,  3.,  4.,  1.]]]], grad_fn=<ThnnConv2DBackward>) 

如果将输入矩阵从左到右,从上到下进行无限的重复延伸,即为下面这种形式:

tensor([[[[ 1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.],
          [ 5.,  6.,  7.,  8.,  5.,  6.,  7.,  8.,  5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12.,  9., 10., 11., 12.,  9., 10., 11., 12.],
          [13., 14., 15., 16., 13., 14., 15., 16., 13., 14., 15., 16.],
          [ 1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.],
          [ 5.,  6.,  7.,  8.,  5.,  6.,  7.,  8.,  5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12.,  9., 10., 11., 12.,  9., 10., 11., 12.],
          [13., 14., 15., 16., 13., 14., 15., 16., 13., 14., 15., 16.],
          [ 1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.,  1.,  2.,  3.,  4.],
          [ 5.,  6.,  7.,  8.,  5.,  6.,  7.,  8.,  5.,  6.,  7.,  8.],
          [ 9., 10., 11., 12.,  9., 10., 11., 12.,  9., 10., 11., 12.],
          [13., 14., 15., 16., 13., 14., 15., 16., 13., 14., 15., 16.]]]]) 

image.png

看出来了吗?如果无限延伸的话这样就是对原始的4*4矩阵的循环,上面的矩阵就是在高和宽维度上都填充4个单位的结果,如果只填充1个单位,那就只截取填充一个单位后的矩阵:

image.png

这就是例子中只填充1个单位的结果。

refer

https://www.jianshu.com/p/a6da4ad8e8e7

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

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

相关文章

阿里云安全恶意程序检测

阿里云安全恶意程序检测 赛题理解赛题介绍赛题说明数据说明评测指标 赛题分析数据特征解题思路 数据探索数据特征类型数据分布箱型图 变量取值分布缺失值异常值分析训练集的tid特征标签分布测试集数据探索同上 数据集联合分析file_id分析API分析 特征工程与基线模型构造特征与特…

driver.find_element()用法

driver.find_element()用于在Web页面中定位单个元素。它是Selenium WebDriver库中的 一种方法。该方法接受一个定位器&#xff08;locator&#xff09;和一个值作为参数&#xff0c;用于指定要查找的元素 位置。下面是具体的用法和一些例子&#xff1a; 通过ID定位元素&#x…

AI神助攻,购物更省心:我即将上线一套企业数据高度契合的智能导购APP来开创这一新纪元

将要做什么事的介绍 近期博客写了少了&#xff0c;是因为近小半年来我正在打造一款可私布在企业内部并结合企业自有领域&#xff08;零售商超先行&#xff09;数据的智能导购引擎。截止目前为止还算顺利&#xff0c;并且我将很快将在中国本土的一家生鲜百货超市上线这一款生成…

[iOS开发]iOS中TabBar中间按钮凸起的实现

在日常使用app的过程中&#xff0c;经常能看到人家实现了底部分栏控制器的中间按钮凸起的效果&#xff0c;那么这是怎么实现的呢&#xff1f; 效果演示&#xff1a; 实现原理&#xff1a; 创建按钮 创建一个UITabBar的子类&#xff0c;重写它的layoutSubviews方法&#xff1…

redis源码分析之IO多路复用

文章目录 1、简述2、多路复用的三个函数3、创建epoll实例4、绑定端口、监听端口5、向epoll实例注册连接事件6、从epoll实例中获取就绪的事件 1、简述 众所周知&#xff0c;redis是一款抗高并发的利器&#xff0c;据官方压测&#xff0c;单机可达10万qps。但背后实际处理命令的…

字典与数组第八讲:工作表数据计算时为什么要采用数组公式(二)

《VBA数组与字典方案》教程&#xff08;10144533&#xff09;是我推出的第三套教程&#xff0c;目前已经是第二版修订了。这套教程定位于中级&#xff0c;字典是VBA的精华&#xff0c;我要求学员必学。7.1.3.9教程和手册掌握后&#xff0c;可以解决大多数工作中遇到的实际问题。…

具有自主产权的SaaS门店收银系统全套源码输出

PHPMysql前后端分离&#xff0c; 小程序线上商城&#xff1b; 进销存管理库存盘点&#xff0c; 多仓库库存调拨&#xff0c; 会员系统。 消费者扫码查价系统。

外卖行业如何借助微信管理系统实现高效运营

摘要&#xff1a;本文将介绍微信管理系统在外卖行业的应用&#xff0c;包括聚合聊天、朋友圈营销和群发功能。通过这些功能&#xff0c;外卖商家可以更高效地管理订单、与客户沟通、推广品牌和增加销售额。 一、引言 随着外卖行业的快速发展&#xff0c;竞争也日益激烈。为了…

前端面试题之HTML篇

1、src 和 href 的区别 具有src的标签有&#xff1a;script、img、iframe 具有href的标签有&#xff1a;link、a 区别 src 是source的缩写。表示源的意思&#xff0c;指向资源的地址并下载应用到文档中。会阻塞文档的渲染&#xff0c;也就是为什么js脚本放在底部而不是头部的…

Vert.x学习笔记-Vert.x的基本处理单元Verticle

Verticle介绍 Verticle是Vert.x的基本处理单元&#xff0c;Vert.x应用程序中存在着处理各种事件的处理单元&#xff0c;比如负责HTTP API响应请求的处理单元、负责数据库存取的处理单元、负责向第三方发送请求的处理单元。Verticle就是对这些功能单元的封装&#xff0c;Vertic…

数据中心系统解决方案

设计思路 系统设计过程中充分考虑各个子系统的信息共享要求&#xff0c;对各子系统进行结构化和标准化设计&#xff0c;通过系统间的各种联动方式将其整合成一个有机的整体&#xff0c;使之成为一套整体的、全方位的数据中心大楼综合管理系统&#xff0c;达到人防、物防和技防…

MySQL8.0.26-unbuntu版安装

MySQL8.0.26-ubuntu版安装 在这里会有一个坑&#xff0c;就是我在安装的时候,是按照另外一种版本的安装&#xff0c;报错没有rpm这个包&#xff0c;然后我就去下载&#xff0c;然后就报错 E: 无法定位软件包 &#xff0c;害的我找了好久的资料&#xff0c;一直没有解决&#x…

2023-11-04:用go语言,如果n = 1,打印 1*** 如果n = 2,打印 1*** 3*** 2*** 如果n = 3,打印

2023-11-04&#xff1a;用go语言&#xff0c;如果n 1&#xff0c;打印 1*** 如果n 2&#xff0c;打印 1***3*** 2*** 如果n 3&#xff0c;打印 1***3*** 2***4*** 5*** 6*** 如果n 4&#xff0c;打印 1***3*** 2***4*** 5*** 6***10** 9*** 8*** 7*** 输入…

SoftwareTest5 - 你就只知道功能测试吗 ?

你就只知道功能测试吗 ? 一 . 按照测试对象划分1.1 文档测试1.2 可靠性测试1.3 容错性测试1.4 安装卸载测试1.5 内存泄漏测试1.6 弱网测试 二 . 按是否查看代码划分2.1 黑盒测试2.2 白盒测试2.3 灰盒测试 三 . 按照开发阶段划分3.1 单元测试3.2 集成测试3.3 冒烟测试3.4 系统测…

如何通过智能管理箱实现高效文件管理:关键字轻松修改文件名

在信息化时代&#xff0c;文件管理变得尤为重要。智能管理箱已经成为我们生活中不可或缺的一部分。它可以帮助我们高效地管理各种文件&#xff0c;使得我们的工作和生活更加便捷。是一种高效的文件管理工具&#xff0c;可以帮助我们轻松地整理和分类文件&#xff0c;提高工作效…

【算法】昂贵的聘礼(dijkstra算法)

题目 年轻的探险家来到了一个印第安部落里。 在那里他和酋长的女儿相爱了&#xff0c;于是便向酋长去求亲。 酋长要他用 10000 个金币作为聘礼才答应把女儿嫁给他。 探险家拿不出这么多金币&#xff0c;便请求酋长降低要求。 酋长说&#xff1a;”嗯&#xff0c;如果你能够替我…

SpringBoot+AOP+自定义注解,优雅实现日志记录

文章目录 前言准备阶段1、数据库日志表2、自定义注解编写3、AOP切面类编写4、业务层4.1、Service 层&#xff1a;4.2 Service 实现层&#xff1a; 5、测试 前言 首先我们看下传统记录日志的方式是什么样的&#xff1a; DeleteMapping("/deleteUserById/{userId}") …

【C语言:函数栈帧的创建与销毁】

文章目录 前言一、前期准备1.寄存器2.汇编指令3.测试代码 二、解开函数栈帧的神秘面纱1.栈帧大体轮廓2.main函数栈帧的创建3.main函数内执行有效代码4.烫烫烫5.函数参数的传递6.add函数栈帧的创建7.add函数内执行有效代码8.add是如何获得参数的9. add函数栈帧的销毁10.main函数…

IDEA中如何移除未使用的import

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是全栈工…

@Slf4j将日志记录到磁盘和数据库

文章目录 1、背景介绍2、存本地2.1、配置文件2.2、使用 3、存数据库3.1、配置文件改造3.2、过滤器编写3.3、表准备3.4、添加依赖3.5、测试 4、优化4.1、日志定期删除 1、背景介绍 现在我一个SpringBoot项目想记录日志&#xff0c;大概可以分为下面这几种&#xff1a; 用户操作…