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])

参考

  1. https://pytorch.org/docs/1.3.1/nn.functional.html?highlight=conv2d#torch.nn.functional.conv2d

[Pytorch]torch.nn.functional.conv2d与深度可分离卷积和标准卷积相关推荐

  1. 基于torch.nn.functional.conv2d实现CNN

    在我们之前的实验中,我们一直用torch.nn.Conv2D来实现卷积神经网络,但是torch.nn.Conv2D在实现中是以torch.nn.functional.conv2d为基础的,这两者的区别 ...

  2. pytorch: torch.nn.functional.affine_grid(theta,size)

    # 仍有部分疑惑  torch.nn.functional.affine_grid(theta,size): 给定一组仿射矩阵(theta),生成一个2d的流场.通常与 grid_sample() 结 ...

  3. PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx

    PyTorch : torch.nn.xxx 和 torch.nn.functional.xxx 在写 PyTorch 代码时,我们会发现在 torch.nn.xxx 和 torch.nn.funct ...

  4. torch.nn.functional.interpolate函数

    torch.nn.functional.interpolate实现插值和上采样 torch.nn.functional.interpolate(input, size=None, scale_fact ...

  5. 一次将tensorflow中的tf.nn.conv2d优(re)雅(shape)的转化成torch.nn.F.conv2d的咸鱼操作

    写在前面 毕设勉强中-看了<A Capsule Network-based Embedding Model for Knowledge Graph Completion and Search P ...

  6. PyTorch踩坑记录——torch.functional 与 torch.nn.functional的区别

    问题描述: 提示:刚入门深度学习,记录一些犯下的小错误: 由于本周开始试图复现华为的CTR库以增加记忆,熟悉代码细节,没想到第一天看基础模块的时候就遇到了麻烦,在torch.utils类中,有如下获取 ...

  7. pytorch笔记:torch.nn.functional.pad

    1 torch.nn.functional.pad函数 torch.nn.functional.pad是pytorch内置的tensor扩充函数,便于对数据集图像或中间层特征进行维度扩充 torch. ...

  8. opencv和pytorch中的warp操作函数:cv2.warpAffine, torch.nn.functional.grid_sample, cv2.warpPerspective

    关于图像的warp操作是指利用一个旋转缩放矩阵对图像进行操作. 常见的操作有,平移,绕某个点旋转,缩放. opencv中有getRotationMatrix2D,warpAffine, getAffi ...

  9. Pytorch之torch.nn.functional.pad函数详解

    torch.nn.functional.pad是PyTorch内置的矩阵填充函数 (1).torch.nn.functional.pad函数详细描述如下: torch.nn.functional.pa ...

最新文章

  1. 软件工程白盒测试的流图怎么画_功能安全理论 | 黑盒 与 白盒
  2. Linux文件系统上的特殊权限      SUID, SGID, Sticky(粘之位)
  3. Spring Web Flow 入门demo(一)简单页面跳转 附源码
  4. 矩阵置零Python解法
  5. docker log 文件 清理
  6. 一行Python代码就可以下载任意网站视频,零基础小白也能轻松学会
  7. HashTable,Dictionary,ConcurrentDictionary 的应用场景,区别,用法统计
  8. ktv服务器操作系统,开源ktv客户端服务器系统
  9. 眼底图像血管增强与分割--(3)基于PCA的增强算法原理及实现
  10. f2fs学习笔记 - 4. f2fs文件系统组件说明
  11. TF-IDF mapreduce实现
  12. 大学加权平均分计算器_澳大利亚移民宝藏专业----西澳大学幼教硕士解析
  13. R语言中交集,并集,补集,差集的方法:向量和数据框
  14. STM32硬件SPI时钟频率与时钟解析(基于逻辑分析仪的抓包试验)
  15. 大幅提升CLIP图像分类准确率-Tip-Adapter
  16. 手把手教程 | 实现Amazon CloudWatch持续报警
  17. Android App数据加密
  18. 新手也能每天挣300,今日头条的这5个隐藏玩法,你知道吗?
  19. 视觉定位领域专栏(二)常用数据集介绍
  20. Spring task corn表达式

热门文章

  1. 物联网平台搭建的全过程介绍(三)阿里云物联网设备接入订阅发布之Android studio例程
  2. Zblog采集插件-Zblog插件教程以及下载
  3. Tita OKR分享:我们提出的OKRs-E是什么?
  4. 删除PDF文件中的空白页面
  5. Learn OpenGL 笔记7.4 PBR-Specular IBL(Image based lighting-特殊的基于图像的照明)
  6. 笔记本连接WIFI后,虚拟机不能上网问题解决
  7. 使用哈尔滨工业大学SCIR的开源代码训练自己的ELMo
  8. 聚类之K-Means++算法
  9. Linux使用本地光盘制作yum源
  10. matlab 的 符号,MATLAB符号计算