nn.Conv2d——二维卷积运算解读

2023-11-10

nn.Conv2d——二维卷积运算

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)

功能:对多个输入平面组成的输入信号应用2D卷积运算,常用于图像处理

输入:

  • in_channels:输入图像中的通道数
  • out_channels:经过卷积运算产生的通道数
  • kernel_size:卷积核大小,整数或者元组类型
  • stride:卷积运算的步幅,整数或者元组类型,默认1
  • padding:边界处的填充大小,整数或者元组类型,默认0
  • padding_mode:填充方式,zerosreflectreplicatecircular,默认是zeros
    zeros:零填充,在张量边界全部填充0
    reflect:镜像填充,以矩阵边缘为对称轴,将反方向的对称元素填充到最外围。
    replicate:复制填充,使用输入边界的复制值填充张量
    circular:循环填充,重复矩阵边界另一侧的元素
    具体区别请见代码案例
  • dilation:控制点之间的距离,默认是1,如果大于1,则该运算又称为扩张卷积运算。
    一图看懂扩张卷积运算

在这里插入图片描述

图片来源:https://github.com/vdumoulin/conv_arithmetic

  • groups:控制输入和输出之间的连接,默认是1。
    • groups=1时,所有输入都被卷积为输出
    • groups=2时,该操作相当于先把输入通道对半分,分别经过相同的conv运算(因此卷积参数会减半),产生对应的输出,然后再将两者的输出连接起来。groups>2的情况类似,最大不能超过输入的通道数。
    • groups必须可以整除in_channelsout_channels
  • bias:是否有偏置项,默认True,即默认存在偏置项。
  • 输入的数组数据类型必须是TensorFloat32类型

注意:

  • in_channelsout_channels kernel_size是必须指定的参数,其他参数都有默认值,可以不指定。
  • kernel_sizestridepaddingdilation既可以指定为整数类型,也可以指定为元组类型。
    • 如果被指定为整数时,则高度和宽度尺寸使用相同的值(正方形)
    • 如果被指定为元组类型时,元组中第一个值用于高,第二个维度用于宽(长方形)

补充:

  • 输出图像的高、宽计算公式(公式转自官方文档):

假设 : 输入 i n p u t : ( N , C i n , H i n , W i n ) , 输出 o u t p u t : ( N , C o u t , H o u t , W o u t ) 其中 N 是 b a t c h _ s i z e 、 C i 是通道, H i 是图像的高、 W i 是图像的宽 假设: 输入input:(N,C_{in},H_{in},W_{in}),输出output:(N,C_{out},H_{out},W_{out})\\ 其中N是batch\_size、C_i是通道,H_i是图像的高、W_i是图像的宽 假设:输入input:(N,Cin,Hin,Win),输出output:(N,Cout,Hout,Wout)其中Nbatch_sizeCi是通道,Hi是图像的高、Wi是图像的宽

H o u t = H i n + 2 × p a d d i n g [ 0 ] − d i l a t i o n [ 0 ] × ( k e r n e l _ s i z e [ 0 ] − 1 ) − 1 s t r i d e [ 0 ] + 1 W o u t = W i n + 2 × p a d d i n g [ 1 ] − d i l a t i o n [ 1 ] × ( k e r n e l _ s i z e [ 1 ] − 1 ) − 1 s t r i d e [ 1 ] + 1 H_{out}=\frac{H_{in}+2\times padding[0]-dilation[0]\times(kernel\_size[0]-1)-1}{stride[0]}+1\\ W_{out}=\frac{W_{in}+2\times padding[1]-dilation[1]\times(kernel\_size[1]-1)-1}{stride[1]}+1\\ Hout=stride[0]Hin+2×padding[0]dilation[0]×(kernel_size[0]1)1+1Wout=stride[1]Win+2×padding[1]dilation[1]×(kernel_size[1]1)1+1

  • 卷积层的权重可通过方法Conv2d.weight提取,输出的权重数组尺寸为:
    ( o u t _ c h a n n e l s , i n _ c h a n n e l s g r o u p s , k e r n e l _ s i z e [ 0 ] , k e r n e l _ s i z e [ 0 ] ) (out\_channels,\frac{in\_channels}{groups},kernel\_size[0],kernel\_size[0]) (out_channels,groupsin_channels,kernel_size[0],kernel_size[0])

并且初始化权重分部服从均匀分布:
u ( − k , k ) , 其中 k = g r o u p s C i n × ∏ i = 0 1 k e r n e l _ s i z e [ i ] u(-\sqrt{k},\sqrt{k}),其中k=\frac{groups}{C_{in}\times \prod\limits_{i=0}^1 kernel\_size[i]} u(k ,k ),其中k=Cin×i=01kernel_size[i]groups

  • 卷积层的偏置参数可以通过方法Conv2d.bias提取(前提bias=True),输出的数组尺寸与out_channels大小一样,初始化分部与weight权重分部一样。
  • 卷积层参数也可以通过.parameters()方法获取

代码案例

一般用法

import torch.nn as nn
import torch
img=torch.arange(49,dtype=torch.float32).view(1,1,7,7)
conv=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=3)
img_2=conv(img)
print(img)
print(img_2)

输出

# 经过卷积运算前
tensor([[[[ 0.,  1.,  2.,  3.,  4.,  5.,  6.],
          [ 7.,  8.,  9., 10., 11., 12., 13.],
          [14., 15., 16., 17., 18., 19., 20.],
          [21., 22., 23., 24., 25., 26., 27.],
          [28., 29., 30., 31., 32., 33., 34.],
          [35., 36., 37., 38., 39., 40., 41.],
          [42., 43., 44., 45., 46., 47., 48.]]]])
# 卷积运算后
tensor([[[[4.7303, 4.8851, 5.0398, 5.1945, 5.3492],
          [5.8134, 5.9681, 6.1228, 6.2775, 6.4323],
          [6.8964, 7.0512, 7.2059, 7.3606, 7.5153],
          [7.9795, 8.1342, 8.2889, 8.4436, 8.5984],
          [9.0625, 9.2172, 9.3720, 9.5267, 9.6814]]]],
       grad_fn=<ThnnConv2DBackward>)

图像尺寸的变化

import torch.nn as nn
import torch
img=torch.arange(4*64*28*28,dtype=torch.float32).view(4,64,28,28)
conv=nn.Conv2d(in_channels=64,out_channels=128,kernel_size=3,padding=1)
img_2=conv(img)
print(img.shape)
print(img_2.shape)

输出

# 卷积前
torch.Size([4, 64, 28, 28])
# 卷积后
torch.Size([4, 128, 28, 28])

通道数变为了原来的两倍,由于填充了一格,所以卷积后尺寸不变

输出卷积运算的参数

卷积层数值

import torch.nn as nn
import torch
conv=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=3)
print(conv.weight)
print(conv.bias)
print(type(conv.weight))
# 利用.parameters()方法调用参数
for i in conv.parameters():
    print(i)
print(type(i))

输出

# 卷积层权重参数
Parameter containing:
tensor([[[[-0.1891, -0.2296,  0.0362],
          [-0.1552, -0.0747,  0.2922],
          [-0.1434,  0.0802, -0.0778]]]], requires_grad=True)
# 卷积层偏置参数
Parameter containing:
tensor([0.1998], requires_grad=True)
# 参数的类型,均为Parameter类
<class 'torch.nn.parameter.Parameter'>
# 下面是通过.parameters()方法调用参数,与前面的方法结果一样
Parameter containing:
tensor([[[[-0.1891, -0.2296,  0.0362],
          [-0.1552, -0.0747,  0.2922],
          [-0.1434,  0.0802, -0.0778]]]], requires_grad=True)
Parameter containing:
tensor([0.1998], requires_grad=True)
# 返回的数据类型也一样
<class 'torch.nn.parameter.Parameter'>

卷积层参数尺寸

import torch.nn as nn
import torch
conv=nn.Conv2d(in_channels=64,out_channels=128,kernel_size=[5,3],padding=2)
print(conv.weight.shape)
print(conv.bias.shape)

输出

# 权重参数,从第一维到第四维依次代表:
# 输出通道数、输入通道数、卷积核的高、卷积核的宽
torch.Size([128, 64, 5, 3])
# 偏置项参数,大小和输入通道数一样
torch.Size([128])

填充方式

为了消除卷积运算对原图的影响,我们首先将卷积核大小设为1,并且参数也设为1,不设置偏置项,并且为了凸显扩充后的效果,我们将padding调整为3。

初始化过程

import torch.nn as nn
import torch
conv_1=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=1,bias=False,padding=3,mode='zeros')
conv_1.weight=nn.parameter(torch.ones((1,1,1,1)))
conv_2=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=1,bias=False,padding=3,mode='reflect')
conv_2.weight=nn.parameter(torch.ones((1,1,1,1)))
conv_3=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=1,bias=False,padding=3,mode='replicate')
conv_3.weight=nn.parameter(torch.ones((1,1,1,1)))
conv_4=nn.Conv2d(in_channels=1,out_channels=1,kernel_size=1,bias=False,padding=3,mode='circular')
conv_4.weight=nn.parameter(torch.ones((1,1,1,1)))
img=torch.arange(25,dtype=torch.float32).reshape(1,1,5,5)

零填充

img_1=conv_1(img)
print(img)
print(img_1)

输出
在这里插入图片描述

镜像填充

img_2=conv_2(img)
print(img)
print(img_2)

输出

在这里插入图片描述

复制填充

img_3=conv_3(img)
print(img)
print(img_3)

输出

在这里插入图片描述

循环填充

img_4=conv_4(img)
print(img)
print(img_4)

输出

在这里插入图片描述

官方文档

nn.Conv2d():https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html?highlight=conv2d#torch.nn.Conv2d

点个赞支持一下吧

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

nn.Conv2d——二维卷积运算解读 的相关文章

随机推荐

  • ADB无线连接/wifi调试 安卓设备

    一般 对android设备使用adb命令前 需要先用数据线连接设备后 才可以继续使用 此篇文章 我们来讲另外一种android设备的连接方式 无线连接 一 无线连接设置的具体步骤如下 第一步 先用USB数据线 将手机和电脑连接在一起 1 数
  • Python兼职接单也能月入过万,整理了70个练手的小项目,赶快学起来

    下面是一些的python兼职单子截图 心动了吗 快去抓紧时间学习起来吧 上述这份完整版的Python全套学习资料已经上传CSDN官方 朋友们如果需要可以直接划到文末免费领取 保证100 免费 关于Python技术储备 学好Python 不论
  • SpringSecurity学习笔记(一)springSecurity的整体架构

    参考视频 编程不良人 1 什么是SpringSecurity 首先我们要知道SpringSecurity是Spring家族中的一员 是基于spring框架提供的一套web应用安全性的完整解决方案 包括可高度定制的认证 授权 鉴权等一系列的流
  • 元宇宙沉浸式互动展示系统开发定制平台

    2021年公认是元宇宙元年 今年元宇宙的发展更是得到了社会各界的广泛关注 元宇宙首次被写入地方 十四五 规划 各大数字科技巨头 政府机构也都纷纷入局元宇宙 随着元宇宙的变现能力和商业化前景已经得到证实 元宇宙概念与广告营销业的深度融合优势开
  • 计算机毕业设计ssm基于java语言的自行车在线租赁系统k22rh9 (附源码)轻松不求人

    项目运行 环境配置 Jdk1 8 Tomcat7 0 Mysql HBuilderX Webstorm也行 Eclispe IntelliJ IDEA Eclispe MyEclispe Sts都支持 项目技术 ssm mybatis Ma
  • Java 自定义注解及使用场景

    Java自定义注解一般使用场景为 自定义注解 拦截器或者AOP 使用自定义注解来自己设计框架 使得代码看起来非常优雅 本文将先从自定义注解的基础概念说起 然后开始实战 写小段代码实现自定义注解 拦截器 自定义注解 AOP 一 什么是注解 A
  • 小程序+uniapp部分问题

    微信小程序showModal中content的内容如何换行 在需要换行的位置加上 r n 即可实现内容的换行 注 微信开发者工具可能看不到效果 但是真机实测是会换行的 wx showModal title 提示 content 未达到最低使
  • 百度云加速配置SSL证书方法

    配置前提 确保域名在HTTP普通网站可以正常打开 并且域名已经解析到百度加速 一 登录沃通数字证书商店下载 SSL证书文件并且解压 选择nginx文件夹 百度云加速只需要用到nginx文件夹 二 登录百度云加速 https su baidu
  • 子系统 Arch Linux

    去年 还是前年不记得了 微软推出了子系统 官方支持的是Ubuntu 由于我对Ubuntu这样的重量级Linux没啥好感 当时只是安装了一下 就没怎么玩了 现在又有机会重新安装了Win10 去年在Arch社区得知Github上有关于Arch子
  • java Json转string方法

    Java中Json转string方法 Java利用Json lib包进行json对象转换成string JSONArray转换string方法实例 public static void main String args throws JSO
  • springboot配置类编写

    以配置一个DataSource为例 其他的类似 接下来我就给大家介绍具体步骤 1 首先写两个类 并添加注解 ConfigurationProperties 表明这是一个配置类 其中一个为dataSource的配置类 一个为jdbc的配置类
  • 为什么docker容器启动不了?

    sudo docker run d centos bin bash创建容器之后 使用docker ps a 发现容器已经停止 再使用docker start id 启动容器之后 观察ps a 的操作时间 发现容器其实已经启动过 但是马上就停
  • wsl 修改 hostname

    我在使用Windows 的 wsl 功能的时候发现在默认情况下 wsl 的 hostname 是和当前 windows 系统的主机名称保持一致的 当我尝试使用 hostname 修改主机名时 发现并不能完全修改 在重新进入后又会恢复成原来的
  • IDEA忽略文件,防止git提交不想提交的文件的探索

    使用IDEA开发有 一段时间了 从陌生到熟悉的过程算是很平稳的度过 感谢IntelliJ IDEA交流群 群号244908708 里面的群友对我提供的帮助 感谢群主的github上面提供的资料 这篇文章是探索git忽略文件提交的一些方面的研
  • 麦克风音频服务器未响应,耳机和麦克风都没坏,插上电脑后为什么不能语音聊天?...

    耳机和麦克风都没坏 插上电脑后为什么不能语音聊天 以下文字资料是由 历史新知网www lishixinzhi com 小编为大家搜集整理后发布的内容 让我们赶快一起来看一下吧 耳机和麦克风都没坏 插上电脑后为什么不能语音聊天 先确认你的电脑
  • 第十七章 Chisel基础——数据类型

    一 Chisel的常见问题 在学习Chisel前 应该熟悉一些常见问题 这些问题在编写Chisel的任何时候都应该牢记 Chisel是寄宿在Scala里的语言 所以它本质还是Scala 为了从Chisel转变成Verilog 语言开发人员开
  • 径向基神经网络(RBF)回归预测MATLAB实现超详细

    在机械学习算法的过程中 我们常用到一种神经网络就是径向基神经网络 这是一种使用径向基函数作为激活函数的人工神经网络 这种神经网络也有很多用途 比如时间序列预测 数据分类以及回归预测等等 今天主要讲解径向基神经网络在MATLAB的实现过程 对
  • 003_linux驱动之_file_operations函数

    一 解析file operations函数 解析002 linux驱动之 register chrdev注册字符设备中的问题 二 file operations结构原型 使用举例 三 从上面的原型可以看出file operations函数有
  • 不走索引的情况

    1 条件字段选择性弱 查出的结果集较大 不走索引 2 where条件等号两边字段类型不同 不走索引 3 优化器分析的统计信息陈旧也可能导致不走索引 4 索引字段 is null 不走索引 5 对于count 当索引字段有not null约束
  • nn.Conv2d——二维卷积运算解读

    PyTorch学习笔记 nn Conv2d 二维卷积运算解读 nn Conv2d 二维卷积运算 代码案例 一般用法 输出卷积运算的参数 填充方式 零填充 镜像填充 复制填充 循环填充 官方文档 nn Conv2d 二维卷积运算 torch