【pytorch系列】卷积操作原理解析与nn.Conv2d用法详解
参考:
https://pytorch.org/docs/master/generated/torch.nn.Conv2d.html#torch.nn.Conv2d
https://zhuanlan.zhihu.com/p/251068800
https://www.cnblogs.com/mrlonely2018/p/13946730.html
https://www.jb51.net/article/177739.htm
https://www.jianshu.com/p/a6da4ad8e8e7
https://blog.csdn.net/HappinessSourceL/article/details/106207022
目录:
- 1 官方文档
- 2 函数原型及参数介绍
- 3 关于二维卷积:
- (1)单通道卷积
- (2)多通道卷积
- (3)多通道输入,多通道输出
- 4 卷积操作后图形尺寸的变化公式:
- 5 关于参数 padding与padding_mode:
- (1)padding的理解:
- (2) PyTorch Conv2d中的padding_mode四种填充模式解析
- 6 关于参数dilation:
- 7 关于参数groups——分组卷积:
- 为什么要设置groups参数,有什么优点?
- 9 标准卷积的详细计算图可表示为:
- 10 案例代码:
1 官方文档
2 函数原型及参数介绍
函数原型:
class torch.nn.Conv2d(in_channels, out_channels,kernel_size,stride=1, padding=0, dilation=1, groups=1, bias=True)
函数作用:定义一个卷积核,方便后面进行二维卷积操作
我们会发现一个现象:pytorch的conv2d没有要求输入卷积核的信息,设置卷积核的权重可以在后面采用:
conv_zeros = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=False)
conv_zeros.weight = torch.nn.Parameter(torch.ones(1,1,1,1))
Parameters:
参数 | 数据类型 | ||
---|---|---|---|
in_channels | int | Number of channels in the input image | 输入图像通道数 |
out_channels | int | Number of channels produced by the convolution | 卷积产生的通道数 |
kernel_size | (int or tuple) | Size of the convolving kernel | 卷积核尺寸,可以设为1个int型数或者一个(int, int)型的元组。例如(2,3)是高2宽3卷积核 |
stride | (int or tuple, optional) | Stride of the convolution. Default: 1 | 卷积步长,默认为1。可以设为1个int型数或者一个(int, int)型的元组。 |
padding | (int or tuple, optional) | Zero-padding added to both sides of the input. Default: 0 | 填充操作,控制padding_mode的数目。简言之,就是决定图像边沿填充的方式 |
padding_mode | (string, optional) | optional) ‘zeros’, ‘reflect’, ‘replicate’ or ‘circular’. Default: ‘zeros’ | padding模式,默认为Zero-padding 。 |
dilation | (int or tuple, optional) | Spacing between kernel elements. Default: 1 | 扩张操作:控制kernel点(卷积核点)的间距,默认值:1。 |
groups | (int, optional) | Number of blocked connections from input channels to output channels. Default: 1 | group参数的作用是控制分组卷积,默认不分组,为1组。输入图像通道数 |
bias | (bool, optional) | If True, adds a learnable bias to the output. Default: True | 为真,则在输出中添加一个可学习的偏差。默认:True。 |
3 关于二维卷积:
首先我们介绍以下基本的卷积运算:
可以看出,上图的卷积运算实质上就是两个相同尺寸的矩阵进行了一次矩阵内积运算。
实际上,一次卷积操作要经过很多次上述的矩阵内积运算,最终也会获得一个新的矩阵。
(1)单通道卷积
下图可以看作是一次常规的卷积操作:
这是用一个卷积核在一个二维图像上进行卷积操作后得到一个二维的特征映射。
可以看出卷积核尺寸为3*3kernel_size=3
,卷积步长为1stride=1
。
输入通道in_channels
和输出通道out_channels
不得而知,假设都为1。
关于padding
后面介绍,暂定为padding=0
代码:
nn.Conv2d(in_channels=1,out_channels=1,kernel_size=3,stride=1,padding=0)
(2)多通道卷积
若是出现in_channels>1
,out_channels=1
,则可以参考下图的卷积运算:
卷积过程如下,每一个通道的像素值与对应的卷积核通道的数值进行卷积,因此每一个通道会对应一个输出卷积结果,三个卷积结果对应位置累加求和,得到最终的卷积结果(这里卷积输出结果通道只有1个,因为卷积核只有1个。卷积多输出通道下面会继续讲到)。
可以这么理解:最终得到的卷积结果是原始图像各个通道上的综合信息结果。
代码:
nn.Conv2d(in_channels=3,out_channels=1,kernel_size=3,stride=1,padding=0)
上述过程中,每一个卷积核的通道数量,必须要求与输入通道数量一致,因为要对每一个通道的像素值要进行卷积运算,所以每一个卷积核的通道数量必须要与输入通道数量保持一致
(3)多通道输入,多通道输出
代码:
nn.Conv2d(in_channels=3,out_channels=3,kernel_size=1,stride=1,padding=0)
4 卷积操作后图形尺寸的变化公式:
input_size: 输入图形的尺寸
output_size: 输出图形的尺寸
kernel_size: 卷积核的尺寸
stride: 步长
padding: 边缘扩充
output_size = ((input_size - dilation*(kernel_size-1) + 2* padding)-1)/stride + 1
注:整除
常见举例:
input_size=(512,512)conv2d(in_channels,out_channels,kernel_size=3,stride=2, padding=1)
# 求output_size:
output_size = (input_size - kernel_size + 2* padding)/stride + 1
output = (512 - 3 +2)/2+1 = 255+1 = 256
input_size=(128,128)conv2d(in_channels,out_channels,kernel_size=3,stride=1, padding=1)
# 求output_size:
output_size = (input_size - kernel_size + 2* padding)/stride + 1
output = (128 - 3 +2)/1+1 = 127+1 = 128
5 关于参数 padding与padding_mode:
(1)padding的理解:
padding参数作用:控制zero-padding的数目。
用容易理解的语言来说:padding就是在图像四周加格子。
原因:如果不对图像边缘进行填充,卷积核将无法到达图像边缘的像素,而且卷积前后图像的尺寸也会发生变化,这会造成许多麻烦。
因此现在各大深度学习框架的卷积层实现上基本都配备了padding操作,以保证图像输入输出前后的尺寸大小不变。
例如,若卷积核大小为3x3,那么就应该设定padding=1,即填充1层边缘像素;若卷积核大小为7x7,那么就应该设定padding=3,填充3层边缘像素;也就是padding大小一般设定为核大小的一半。在pytorch的卷积层定义中,默认的padding为零填充。
(2) PyTorch Conv2d中的padding_mode四种填充模式解析
padding,即边缘填充,可以分为四类:零填充,常数填充,镜像填充,重复填充。
padding_mode
参数,可选项有4种:
(1) zeros
,代表零填充。padding_mode
默认选项为zeros
即在矩阵的高、宽两个维度上用0进行填充,填充时将在一个维度的两边都进行填充:
torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='zeros',bias=False)
(2) reflect
,代表镜像填充。
reflect
是以矩阵边缘为对称轴,将矩阵中的元素对称的填充到最外围。
torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='reflect',bias=False)
(3) replicate
,代表重复填充。
对图像或者张量的边缘进行重复填充,就是说直接用边缘的像素值来填充。示例如下:
torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='replicate',bias=False)
(4) circular
,代表循环填充。
示例如下:
# 定义一个1*1卷积,设置填充模式为'circular',在高和宽维度上两边各填充1个单位
In [64]: conv_reflect = torch.nn.Conv2d(1,1,1,1,padding=1,padding_mode='circular',bias=False)# 将卷积核的权重设置为1,这样可使卷积后的输出即为填充后的输入矩阵
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>)
6 关于参数dilation:
dilation:控制kernel点(卷积核点)的间距,默认值:1。
(1)dilation=0的话,效果如图:
蓝色(下面)为输入,绿色(上面)为输出,卷积核为3*3,此时为密集连接。
(2)dilation=1,那么效果如图:
称为扩张卷积(也叫空洞卷积)
优点:
这样单次计算时覆盖的面积(即感受域)由dilation=0时的3*3=9
变为了dilation=1时的5*5=25
。
在增加了感受域的同时却没有增加计算量,保留了更多的细节信息,对图像还原的精度有明显的提升。
7 关于参数groups——分组卷积:
Group Convolution顾名思义,则是对输入feature map进行分组,然后每组分别卷积。
当group=1时,该卷积层需要6611=36个参数,即需要6个61*1的卷积核
计算时就是6H_inW_in的输入整个乘以一个611的卷积核,得到输出的一个channel的值,即1H_outW_out。这样经过6次与6个卷积核计算就能够得到6H_outW_out的结果了
如果将group=3时,卷积核大小为torch.Size([6, 2, 1, 1]),即6个211的卷积核,只需要需要621*1=12个参数
那么每组计算就只被in_channels/groups=2个channels的卷积核计算,当然这也会将输入分为三份大小为2H_inW_in的小输入,分别与211大小的卷积核进行三次运算,然后将得到的3个2H_outW_out的小输出concat起来得到最后的6H_outW_out输出
在实际实验中,同样的网络结构下,这种分组的卷积效果是好于未分组的卷积的效果的。
为什么要设置groups参数,有什么优点?
为了在GPU上并行计算:
标准卷积的计算如下图:
举个例子,假设有一个3×3大小的卷积层,其输入通道为16、输出通道为32。
那么一般的操作就是用32个3×3的卷积核来分别同输入数据卷积,这样每个卷积核需要3×3×16个参数,得到的输出是只有一个通道的数据。之所以会得到一通道的数据,是因为刚开始3×3×16的卷积核的每个通道会在输入数据的每个对应通道上做卷积,然后叠加每一个通道对应位置的值,使之变成了单通道,那么32个卷积核一共需要(3×3×16)×32 =4068个参数。
分组卷积的计算:
9 标准卷积的详细计算图可表示为:
10 案例代码:
>>> # With square kernels and equal stride
>>> m = nn.Conv2d(16, 33, 3, stride=2)
>>> # non-square kernels and unequal stride and with padding
>>> m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))
>>> # non-square kernels and unequal stride and with padding and dilation
>>> m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))
>>> input = torch.randn(20, 16, 50, 100)
>>> output = m(input)
【pytorch系列】卷积操作原理解析与nn.Conv2d用法详解相关推荐
- conv2d的输入_pytorch1.0中torch.nn.Conv2d用法详解
Conv2d的简单使用 torch 包 nn 中 Conv2d 的用法与 tensorflow 中类似,但不完全一样. 在 torch 中,Conv2d 有几个基本的参数,分别是 in_channel ...
- pytorch之torch.nn.Conv2d()函数详解
文章目录 一.官方文档介绍 二.torch.nn.Conv2d()函数详解 参数详解 参数dilation--扩张卷积(也叫空洞卷积) 参数groups--分组卷积 三.代码实例 一.官方文档介绍 官 ...
- 【PyTorch】nn.Conv2d函数详解
文章目录 1. 函数语法格式 2. 参数解释 3. 尺寸关系 4. 使用案例 5. nn.functional.conv2d 1. 函数语法格式 CONV2D官方链接 torch.nn.Conv2d( ...
- tf.nn.conv2d()函数详解(strides与padding的关系)
tf.nn.conv2d()是TensorFlow中用于创建卷积层的函数,这个函数的调用格式如下: def conv2d(input: Any,filter: Any,strides: Any,pad ...
- tf.nn.sampled_softmax_loss用法详解
tensorflow中具体的函数说明如下: tf.nn.sampled_softmax_loss(weights, # Shape (num_classes, dim) - floatXXbiases ...
- pytorch教程之nn.Module类详解——使用Module类来自定义网络层
前言:前面介绍了如何自定义一个模型--通过继承nn.Module类来实现,在__init__构造函数中申明各个层的定义,在forward中实现层之间的连接关系,实际上就是前向传播的过程. 事实上,在p ...
- pytorch教程之nn.Module类详解——使用Module类来自定义模型
pytorch教程之nn.Module类详解--使用Module类来自定义模型_MIss-Y的博客-CSDN博客_nn是什么意思前言:pytorch中对于一般的序列模型,直接使用torch.nn.Se ...
- 【卷积神经网络结构专题】一文详解AlexNet(附代码实现)
关注上方"深度学习技术前沿",选择"星标公众号", 资源干货,第一时间送达! [导读]本文是卷积神经网络结构系列专题第二篇文章,前面我们已经介绍了第一个真正意义 ...
- python中如何反解函数_PyTorch中反卷积的用法详解
pytorch中的 2D 卷积层 和 2D 反卷积层 函数分别如下: class torch.nn.Conv2d(in_channels, out_channels, kernel_size, str ...
最新文章
- 2011寒假-joomla学习笔记
- 各种编码范围总结以及linux下面的编码批量转化
- php email 发送,php 发送 Email
- 1、kali的安装与环境配置
- python初学者用什么软件_初学者编写python用什么软件
- linux回收内存的方法,linux释放内存的方法
- cpu为何有两个温度?
- 未来教育2019年计算机三级数据库,2019年计算机三级数据库考试强化试题及答案012...
- 不会真有人觉得聊天机器人难吧——开篇
- .NET 使用MD5加盐加密
- 基于Android的虚拟校园移动学习系统
- Proguard混淆器
- 软件工程导论——软件工程介绍
- 国际反垃圾邮件组织有哪些?
- win10服务器网页打不开怎么办,win10系统浏览器网页打不开的解决技巧
- vue3 tsx语法
- 池化层(pooling layer) 感受野(Receptive Field) 神经网络的基本组成
- 数据分析您需要一个现代化的数据仓库
- 向量点积(Dot Product),向量叉积(Cross Product)
- HTML5第三弹:亦酷亦萌的网络拓扑图