注意:这里展示的是本篇博文写时的版本最新的实现,但是后续会代码可能会迭代更新,建议对照 官方文档 进行学习。

首先看一下这个类的定义:

class Conv2d(_ConvNd):# 初始化函数,这里主要了解有哪些参数传进来就可以了def __init__(self,in_channels: int,out_channels: int,kernel_size: _size_2_t,stride: _size_2_t = 1,padding: _size_2_t = 0,dilation: _size_2_t = 1,groups: int = 1,bias: bool = True,padding_mode: str = 'zeros'  # TODO: refine this type):#————————————————看到这就可以了————————————————————kernel_size = _pair(kernel_size)stride = _pair(stride)padding = _pair(padding)dilation = _pair(dilation)super(Conv2d, self).__init__(in_channels, out_channels, kernel_size, stride, padding, dilation,False, _pair(0), groups, bias, padding_mode)def _conv_forward(self, input, weight):if self.padding_mode != 'zeros':return F.conv2d(F.pad(input, self._reversed_padding_repeated_twice, mode=self.padding_mode),weight, self.bias, self.stride,_pair(0), self.dilation, self.groups)return F.conv2d(input, weight, self.bias, self.stride,self.padding, self.dilation, self.groups)# 前向传播计算def forward(self, input: Tensor) -> Tensor:return self._conv_forward(input, self.weight)

上面就是Cov2d这个类的源码实现,是不是感觉代码特别少?是不是突然对掌握它信心倍增!

从整体上来看:

Conv2d是一个类,它包含了做卷积运算所需要的参数(__init__函数),以及卷积操作(forward函数)。

再来看一下它的详细参数:

一共九个参数,一般用前三个就可以处理一般的任务:

  1. in_channels :输入通道数目
  2. out_channels :输出通道数目
  3. kernel_size :卷积核大小,如果输入是一个值,比如 333,那么卷积核大小就是 3×33 \times 33×3 ,如果不想卷积核宽和高相等,还可以输入tuple类型数据,比如: (3,5)(3, 5)(3,5)
  4. stride :步长大小,跟上面卷积核参数一样,如果输入是一个值,比如 222 ,步长就是 2×22 \times 22×2 ,还可以输入元组 (2,1)(2, 1)(2,1) ,表示卷积核每次向右移动 111 个步长,向下移动 222 个步长。
  5. padding :填充,参数表示在周围补0的情况。补0的方向为上、下、左、右四个方向。如果是输入是单个值,比如1,就是在上下左右四个方向补一圈0。如果输入是元组比如 (2,1) ,表示在上下两个方向各补两行0,在左右两个方向各补一列0。
  6. dilation :进行扩展卷积需要的参数。
  7. groups :进行分组卷积需要的参数。(有需要自行深入了解)
  8. bias :偏置,布尔类型,默认为 True ,即增加一个学习的偏置项。
  9. padding_mode :填充的模式,默认是 zero ,还可以选择 reflectreplicatecircular 。(有需要自行深入了解)

首先是关于输入通道数 in_channels 和输出通道数 out_channels 的解释

如果对通道是什么还不太理解可以去看我的这篇博客:如何理解卷积神经网络中的通道(channel)

如果卷积核输入的是原始的图片,那么我们可以根据图片类型决定图片的输入通道数,如果是RGB图片, in_channels=3 ,如果是灰度图像,in_channels=1 。输出通道数需要我们自己指定,具体指定多少需要根据经验。

如果是第二层或者更多层卷积,当前层的输入通道数就是上一层卷积的输出通道数,当前层的输出通道数需要自己指定。

关于卷积核的解释

这里的卷积核参数只是指定卷积核的宽度和高度,对于多通道的卷积,代码内部会根据输入通道数初始化对应的卷积核数目,即:如果输入是3通道,那么就会有三个我们指定宽高的卷积核做相应的卷积操作。

关于步长的解释

步长指的是卷积核在输入矩阵的上每次移动几步。移动方向由两个,向右或者向下。分别由两个值指定。

关于填充的解释

填充的主要目的是为了充分利用输入图片的边缘信息。

关于为什么需要填充,可以参考这篇博客:CNN基础知识——卷积(Convolution)、填充(Padding)、步长(Stride)

关于扩张(dilation)参数的解释

本质上就是扩大卷积核,比如将 3×33 \times 33×3 的扩大为 7×77 \times 77×7 的,然后对扩大的部分用0进行填充,

目的是扩大感受野,捕获多尺度上下文信息。

具体怎么扩张,详细请参考:

【1】如何理解扩张卷积(dilated convolution)

【2】总结-空洞卷积(Dilated/Atrous Convolution)

关于分组(group)的解释

对于一般的卷积神经网络,假设通道数有100个,那么我们需要100个卷积核对这100个通道分别做卷积操作,然后求和,最后得到1个特征图。如果我们需要得到30个特征图,就需要30*100=3000个卷积核。参数量非常大。

而对于分组卷积,依然假设通道数有100个,我们分成两组,每组50个通道数,分别对每组单独做卷积操作,每组需要50个卷积核,总的卷积核数目没变,但是我们每组可以得到2个特征图。如果我们分成4组,每组25个通道数,最终可以得到4个特征图。

也就是说,我们在不增加参数量的情况下,得到了更多的特征图。这是分组的优势之一,对于分组的通道,我们可以在不同的GPU上并行训练,加速训练过程。

更详细的解释参考:

卷积网络基础知识—Group Convolution分组卷积

关于偏置项的解释

这个项是个布尔类型值,如果为True,就会在训练的时候加上偏置项,反之,不会。默认是True。

关于填充模式的解释

我们一般情况下对于填充的数据,默认是0。还可以选择常数填充、镜像填充、重复填充.。

常数填充就是指定一个常数值进行填充,如果为0,等价于零填充;

镜像填充是指对图像边缘进行镜像对称的填充;

重复填充指的是用图像边缘的像素值进行填充。

详细参考:PyTorch中的padding(边缘填充)操作

OK,到这里就对所有的参数解释完了。下面我们解释一下,经过一次卷积操作之后,图像形状如何进行变化。

图像形状的变化规则

卷积神经网络的输入: N,Cin,Hin,WinN,C_{in},H_{in},W_{in}N,Cin​,Hin​,Win​

卷积神经网络的输出: N,Cout,Hout,WoutN,C_{out},H_{out},W_{out}N,Cout​,Hout​,Wout​

其中, NNN 表示批处理的大小,即batch_size。CinC_{in}Cin​ 和 CoutC_{out}Cout​ 分别表示输入和输出通道数。 HinH_{in}Hin​ 和 WinW_{in}Win​ 表示输入图片的高和宽,以像素为单位。同理, HoutH_{out}Hout​ 和 WoutW_{out}Wout​ 表示输出图片的高和宽。

OK,我们来看一下输入输出是怎么变化的。

首先是batch_size,卷积神经网络并不会改变这个参数;然后是 CinC_{in}Cin​ 和 CoutC_{out}Cout​ 这两个参数是我们初始化的时候就指定的;实际上卷积神经网络改变的是图片的尺寸,图片尺寸变化公式为:
Hout=⌊Hin+2×padding⌊0⌋−dilation⌊0⌋×(kernel_size⌊0⌋−1)−1stride⌊0⌋+1⌋H_{out}=\lfloor \frac{H_{in} + 2 \times padding\lfloor 0 \rfloor - dilation \lfloor 0 \rfloor \times (kernel\_size\lfloor 0 \rfloor - 1)-1}{stride\lfloor 0 \rfloor} + 1 \rfloor Hout​=⌊stride⌊0⌋Hin​+2×padding⌊0⌋−dilation⌊0⌋×(kernel_size⌊0⌋−1)−1​+1⌋

Wout=⌊Win+2×padding⌊1⌋−dilation⌊1⌋×(kernel_size⌊1⌋−1)−1stride⌊1⌋+1⌋W_{out}=\lfloor \frac{W_{in} + 2 \times padding\lfloor 1 \rfloor - dilation \lfloor 1 \rfloor \times (kernel\_size\lfloor 1 \rfloor - 1)-1}{stride\lfloor 1 \rfloor} + 1 \rfloor Wout​=⌊stride⌊1⌋Win​+2×padding⌊1⌋−dilation⌊1⌋×(kernel_size⌊1⌋−1)−1​+1⌋

然后我们用一段代码测试一下:

import torch
import torch.nn as nn
# in_channels=16, out_channels=33, kernel_size=(3, 5)
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
print(m)
# 我们随机构造输入数据
# N=20, C_in=16, H_in=50, W_in=100
# 对应上面说的 (N, C, H, W)
input = torch.randn(20, 16, 50, 100)
output = m(input)
print(output.shape)

结果:

Conv2d(16, 33, kernel_size=(3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
torch.Size([20, 33, 26, 100])

上面的torch.size表示输出的形状:

batch_size=20batch\_size=20batch_size=20

out_channel=33out\_channel=33out_channel=33

Hout=26H_{out}=26Hout​=26

Wout=100W_{out}=100Wout​=100

我们带入数据实际计算一下:
Hout=⌊50+2×4−3×(3−1)−12+1⌋=26H_{out}= \lfloor \frac{50 + 2 \times 4 - 3 \times (3 - 1) - 1}{2} + 1\rfloor=26 Hout​=⌊250+2×4−3×(3−1)−1​+1⌋=26

Wout=⌊100+2×2−1×(5−1)−11+1⌋=100W_{out}=\lfloor \frac{100 + 2 \times 2 - 1 \times (5 - 1) - 1}{1} + 1 \rfloor = 100 Wout​=⌊1100+2×2−1×(5−1)−1​+1⌋=100

Conv2d中的权重和偏置项

最后我们有必要了解一下Conv2d的两个变量:

~Conv2d.weight

其形状为: (out_channels,in_channelsgroup,kernel_size[0],kernel_size[1])(out\_channels, \frac{in\_channels}{group},kernel\_size[0], kernel\_size[1])(out_channels,groupin_channels​,kernel_size[0],kernel_size[1])

数据从 U(−k,k)\mathcal{U}(-\sqrt{k}, \sqrt{k})U(−k​,k​) 中取样,其中 k=groupsCin∗∏i=01kernel_size[i]k=\frac{groups}{C_{in}*\prod_{i=0}^1kernel\_size[i]}k=Cin​∗∏i=01​kernel_size[i]groups​

~Conv2d.bias

其形状为: (out_channels)(out\_channels)(out_channels)

数据从 U(−k,k)\mathcal{U}(-\sqrt{k}, \sqrt{k})U(−k​,k​) 中取样,其中 k=groupsCin∗∏i=01kernel_size[i]k=\frac{groups}{C_{in}*\prod_{i=0}^1kernel\_size[i]}k=Cin​∗∏i=01​kernel_size[i]groups​

还是上面的代码,我们可以查看这个卷积神经网络的权重和偏置的形状:

import torch
import torch.nn as nn
# in_channels=16, out_channels=33, kernel_size=(3, 5)
m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
print(m)
# 我们随机构造输入数据
# N=20, C_in=16, H_in=50, W_in=100
# 对应上面说的 (N, C, H, W)
input = torch.randn(20, 16, 50, 100)
output = m(input)
print(m.weight.shape)
print(m.bias.shape)

输出:

torch.Size([33, 16, 3, 5])
torch.Size([33])

torch.nn.Conv2d详解相关推荐

  1. PyTorch中的torch.nn.Parameter() 详解

    PyTorch中的torch.nn.Parameter() 详解 今天来聊一下PyTorch中的torch.nn.Parameter()这个函数,笔者第一次见的时候也是大概能理解函数的用途,但是具体实 ...

  2. torch.nn.Linear详解

    在学习transformer时,遇到过非常频繁的nn.Linear()函数,这里对nn.Linear进行一个详解. 参考:https://pytorch.org/docs/stable/_module ...

  3. torch.nn.MaxPool2d详解

    注意:这里展示的是本篇博文写时的版本最新的实现,但是后续会代码可能会迭代更新,建议对照官方文档进行学习. 先来看源码: # 这个类是是许多池化类的基类,这里有必要了解一下 class _MaxPool ...

  4. nn.Conv2d详解

    nn.Conv2d 是 PyTorch 中的一个卷积层,用于实现二维卷积操作.其主要参数有: in_channels:表示输入图像的通道数,也就是输入特征图的深度. out_channels:表示输出 ...

  5. torch.nn.parameter详解

    :-- 目录: 参考: 1.parameter基本解释: 2.参数requires_grad的深入理解: 2.1 Parameter级别的requires_grad 2.2Module级别的requi ...

  6. Pytorch损失函数torch.nn.NLLLoss()详解

    在各种深度学习框架中,我们最常用的损失函数就是交叉熵(torch.nn.CrossEntropyLoss),熵是用来描述一个系统的混乱程度,通过交叉熵我们就能够确定预测数据与真是数据之间的相近程度.交 ...

  7. Tensorflow(r1.4)API--tf.nn.conv2d详解

    (一)函数简介 conv2d(input,filter,strides,padding,use_cudnn_on=True,data_format='NHWC',name=None) 1.参数: in ...

  8. conv2d的输入_pytorch1.0中torch.nn.Conv2d用法详解

    Conv2d的简单使用 torch 包 nn 中 Conv2d 的用法与 tensorflow 中类似,但不完全一样. 在 torch 中,Conv2d 有几个基本的参数,分别是 in_channel ...

  9. pytorch之torch.nn.Conv2d()函数详解

    文章目录 一.官方文档介绍 二.torch.nn.Conv2d()函数详解 参数详解 参数dilation--扩张卷积(也叫空洞卷积) 参数groups--分组卷积 三.代码实例 一.官方文档介绍 官 ...

  10. pytorch 笔记:torch.nn.Conv2d

    1 基本用法 torch.nn,Conv2d(in_channels, out_channels, kernel_size, stride=1,padding=0, dilation=1, group ...

最新文章

  1. Rancher部署Traefik实现微服务的快速发现
  2. 里氏替换原则(Liskov Substitution Principle,LSP)
  3. Makedown 本地图片问题
  4. GetWindowText和GetDlgItemText的区别
  5. [bzoj4003][JLOI2015]城池攻占_左偏树
  6. 【转载保存】B+树索引原理以及应用案例
  7. 正则表达式基础知识,持续更新…
  8. 面试数据分析岗,怎么提升一倍成功率?让过来人给你支支招
  9. [BZOJ 4010] 菜肴制作
  10. 所有快捷方式失效的解决方法
  11. vasp和ms_武汉理工大学赵焱课题组开发脚本 MS建模一键获取VASP输入文件POSCAR
  12. 基于LineMod与ORK的三维物体识别与姿态估计
  13. Python之shp文件
  14. 2020年注册电气工程师基础考试大纲:公共基础(供配电、发输变电相同)
  15. Vue+UpLoad实现上传、点图预览、删除图片
  16. 平安性格测试题及答案_平安人寿做性格测试怎么?
  17. app开发都有哪些基本的开发语言选择?
  18. windows 组策略
  19. created与mounted执行顺序
  20. 暴涨375%超越ZOOM,Fastly靠“网络快递”成为华尔街新宠?

热门文章

  1. 自动控制原理之控制系统的数学模型(类比神经网络学习数学模型)
  2. 六年级计算机课件,六年级信息技术上册课件.ppt
  3. HTML页面分享微博、QQ、微信功能
  4. 批量查询网站收录情况的站长工具
  5. python学习笔记六
  6. 使用python+ffmpeg批量将视频水平翻转
  7. JAVA操作Excel 可配置,动态 生成复杂表头 复杂的中国式报表表头
  8. (转帖)Spring循环依赖的解决办法
  9. 如何开启计算机cpu虚拟化,电脑开启虚拟化设置的方法 如何开启虚拟化设置
  10. office随笔记录—— 批量删除空白行