[Pytorch]torch.nn.functional.conv2d与深度可分离卷积和标准卷积
torch.nn.functional.conv2d与深度可分离卷积和标准卷积
- 前言
- F.conv2d与nn.Conv2d
- F.conv2d
- 标准卷积考虑Batch的影响
- 深度可分离卷积
- 深度可分离卷积考虑Batch
- 参考
前言
是在研究训练过程中遇到的
F.conv2d与nn.Conv2d
也就是torch.nn.functional.conv2d实际上是torch.nn.Conv2d的另一个用法,可以直接指定卷积核和偏置的值。 这在通常情况下是用不到的,因为卷积核的值都是训练得到的。但在一些相关运算(correlation)时,需要指定卷积核的值。首先回顾一下nn.Conv2d
# Conv2d的用法
import torch
x1 = torch.rand([1,256,255,255])
conv = torch.nn.Conv2d(in_channels=256,out_channels=1,kernel_size=3)
out = conv(x1)
计算过程可由下图得到。具体分析,详见上一篇博客Pytorch中的卷积、空洞卷积和组卷积
对于输入(1,Cin,Hin,Win)(1,C_{in},H_{in},W_{in})(1,Cin,Hin,Win),输出Cout{C_{out}}Cout个维度时,所需要的的卷积核维度为(Cout,Cin,Hk,Wk)(C_{out},C_{in},H_{k},W_{k})(Cout,Cin,Hk,Wk)。先假设BatchSize大小BBB与这个过程无关,也就是一个Batch中的所有输入(B,Cin,Hin,Win)(B,C_{in},H_{in},W_{in})(B,Cin,Hin,Win)都被同一组卷积核卷积,因此上图只画出了其中一个输入的卷积过程。
F.conv2d
先看看官方定义
torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1) → Tensor
看着和Conv2d一样,但其中的groups在里面是干什么的?不要紧,先看一个最基础的例子,即输入(1,Cin,Hin,Win)(1,C_{in},H_{in},W_{in})(1,Cin,Hin,Win),输出通道数Cout=1C_{out}=1Cout=1。根据上面的分析,可以得到卷积核的维度为(1,Cin,Hk,Wk)(1,C_{in},H_{k},W_{k})(1,Cin,Hk,Wk)
import torch
import torch.nn.functional as fz1 = torch.rand([1,256,127,127]).cuda() # 卷积核
x1 = torch.rand([1,256,255,255]).cuda() # 输入out_1 = f.conv2d(x1, z1)
print(out_1.shape)# 结果
torch.Size([1, 1, 129, 129])
于是我们可以到一个直观的理解:F.conv2d 中的weight,就是卷积核,其维度是(Cout,Cin,Hk,Wk)(C_{out},C_{in},H_{k},W_{k})(Cout,Cin,Hk,Wk)。
上面这句话是全文的核心。改变weight的第一个维度,直接影响输出大小。
上面那个例子也就是目标跟踪中SiamFC在跟踪时的Correlation过程,
标准卷积考虑Batch的影响
上面是假设BatchSize大小BBB与这个过程无关,也就是一个Batch中的所有输入(B,Cin,Hin,Win)(B,C_{in},H_{in},W_{in})(B,Cin,Hin,Win)都被同一组卷积核卷积。那要不是这样呢,比如SiamFC的训练过程。
输入x维度(B,Cin,Hin,Win)(B,C_{in},H_{in},W_{in})(B,Cin,Hin,Win),被用作卷积核的z输入维度(B,Cin,Hk,Wk)(B,C_{in},H_{k},W_{k})(B,Cin,Hk,Wk)。想要达成的效果是:
x[0,:,:,:]和z[0,:,:,:]进行卷积,x[1,:,:,:]和z[1,:,:,:]进行卷积,以此类推。每个卷积的过程就是标准卷积。
此时需要用到分组卷积和reshape,针对输入,关于分组卷积详见上一篇博客Pytorch中的卷积、空洞卷积和组卷积
batch = 8
z8 = torch.rand([batch,256,127,127]).cuda()
x8 = torch.rand([batch,256,255,255]).cuda()x8_ = x8.reshape([1,256*batch,255,255])
out_3 = (f.conv2d(x8_, z8, groups=batch))print(out_3.shape)# 结果
torch.Size([1, 8, 129, 129])
然后进行out_3.reshape([8, 1, 129, 129])
,即可。
这里你可能会问reshape不影响顺序,进而会导致错误吗?pytorch中的reshape时是首先填满最内侧维度的,然后才填充外侧维度。这种方式不影响计算结果。
直观一点的图
深度可分离卷积
Depth-corr,SiamRPN++中的使用方式。先研究简的跟踪过程:
要求输入x的维度(1,Cin,Hin,Win)(1,C_{in},H_{in},W_{in})(1,Cin,Hin,Win),z的维度(1,Cin,Hk,Wk)(1,C_{in},H_{k},W_{k})(1,Cin,Hk,Wk),输出维度(1,Cin,Hout,Wout)(1,C_{in},H_{out},W_{out})(1,Cin,Hout,Wout),也就是x的第一个维度和z的第一个维度进行卷积,第二个和第二个,依次类推。。。
有了上面的基础,现在研究起来也变得容易了,还是用分组卷积和reshape,针对卷积核
chanel = 256
z1 = torch.rand([1,chanel,127,127])
x1 = torch.rand([1,chanel,255,255])z1_dw = z1.reshape([chanel,1,127,127])
out_2 = f.conv2d(x1, z1_dw, groups=chanel)print(out_2.shape)# 输出
torch.Size([1, 256, 129, 129])
深度可分离卷积考虑Batch
也就相当于SiamRPN++的训练过程。
输入x维度(B,Cin,Hin,Win)(B,C_{in},H_{in},W_{in})(B,Cin,Hin,Win),被用作卷积核的z输入维度(B,Cin,Hk,Wk)(B,C_{in},H_{k},W_{k})(B,Cin,Hk,Wk)。想要达成的效果是:
x[0,:,:,:]和z[0,:,:,:]进行卷积,x[1,:,:,:]和z[1,:,:,:]进行卷积,以此类推。每个卷积的过程就是深度可分离卷积。
如果前面看懂了,这里应该就能学以致用了。
z8 = torch.rand([batch,channel,127,127])
x8 = torch.rand([batch,channel,255,255])x8_ = x8.reshape([1,batch*channel,255,255])
z8_dw = z8.reshape([batch*channel,1,127,127])out_4 = f.conv2d(x8_, z8_dw, groups=channel*batch)
print(out_1.shape)# 输出
torch.Size([1, 2048, 129, 129])
参考
- https://pytorch.org/docs/1.3.1/nn.functional.html?highlight=conv2d#torch.nn.functional.conv2d
[Pytorch]torch.nn.functional.conv2d与深度可分离卷积和标准卷积相关推荐
- 基于torch.nn.functional.conv2d实现CNN
在我们之前的实验中,我们一直用torch.nn.Conv2D来实现卷积神经网络,但是torch.nn.Conv2D在实现中是以torch.nn.functional.conv2d为基础的,这两者的区别 ...
- pytorch: torch.nn.functional.affine_grid(theta,size)
# 仍有部分疑惑 torch.nn.functional.affine_grid(theta,size): 给定一组仿射矩阵(theta),生成一个2d的流场.通常与 grid_sample() 结 ...
- PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx
PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx 在写 PyTorch 代码时,我们会发现在 torch.nn.xxx 和 torch.nn.funct ...
- torch.nn.functional.interpolate函数
torch.nn.functional.interpolate实现插值和上采样 torch.nn.functional.interpolate(input, size=None, scale_fact ...
- 一次将tensorflow中的tf.nn.conv2d优(re)雅(shape)的转化成torch.nn.F.conv2d的咸鱼操作
写在前面 毕设勉强中-看了<A Capsule Network-based Embedding Model for Knowledge Graph Completion and Search P ...
- PyTorch踩坑记录——torch.functional 与 torch.nn.functional的区别
问题描述: 提示:刚入门深度学习,记录一些犯下的小错误: 由于本周开始试图复现华为的CTR库以增加记忆,熟悉代码细节,没想到第一天看基础模块的时候就遇到了麻烦,在torch.utils类中,有如下获取 ...
- pytorch笔记:torch.nn.functional.pad
1 torch.nn.functional.pad函数 torch.nn.functional.pad是pytorch内置的tensor扩充函数,便于对数据集图像或中间层特征进行维度扩充 torch. ...
- opencv和pytorch中的warp操作函数:cv2.warpAffine, torch.nn.functional.grid_sample, cv2.warpPerspective
关于图像的warp操作是指利用一个旋转缩放矩阵对图像进行操作. 常见的操作有,平移,绕某个点旋转,缩放. opencv中有getRotationMatrix2D,warpAffine, getAffi ...
- Pytorch之torch.nn.functional.pad函数详解
torch.nn.functional.pad是PyTorch内置的矩阵填充函数 (1).torch.nn.functional.pad函数详细描述如下: torch.nn.functional.pa ...
最新文章
- 软件工程白盒测试的流图怎么画_功能安全理论 | 黑盒 与 白盒
- Linux文件系统上的特殊权限 SUID, SGID, Sticky(粘之位)
- Spring Web Flow 入门demo(一)简单页面跳转 附源码
- 矩阵置零Python解法
- docker log 文件 清理
- 一行Python代码就可以下载任意网站视频,零基础小白也能轻松学会
- HashTable,Dictionary,ConcurrentDictionary 的应用场景,区别,用法统计
- ktv服务器操作系统,开源ktv客户端服务器系统
- 眼底图像血管增强与分割--(3)基于PCA的增强算法原理及实现
- f2fs学习笔记 - 4. f2fs文件系统组件说明
- TF-IDF mapreduce实现
- 大学加权平均分计算器_澳大利亚移民宝藏专业----西澳大学幼教硕士解析
- R语言中交集,并集,补集,差集的方法:向量和数据框
- STM32硬件SPI时钟频率与时钟解析(基于逻辑分析仪的抓包试验)
- 大幅提升CLIP图像分类准确率-Tip-Adapter
- 手把手教程 | 实现Amazon CloudWatch持续报警
- Android App数据加密
- 新手也能每天挣300,今日头条的这5个隐藏玩法,你知道吗?
- 视觉定位领域专栏(二)常用数据集介绍
- Spring task corn表达式
热门文章
- 物联网平台搭建的全过程介绍(三)阿里云物联网设备接入订阅发布之Android studio例程
- Zblog采集插件-Zblog插件教程以及下载
- Tita OKR分享:我们提出的OKRs-E是什么?
- 删除PDF文件中的空白页面
- Learn OpenGL 笔记7.4 PBR-Specular IBL(Image based lighting-特殊的基于图像的照明)
- 笔记本连接WIFI后,虚拟机不能上网问题解决
- 使用哈尔滨工业大学SCIR的开源代码训练自己的ELMo
- 聚类之K-Means++算法
- Linux使用本地光盘制作yum源
- matlab 的 符号,MATLAB符号计算