假设输入形状是nh×nwn_h\times n_wnh​×nw​,卷积核窗口形状是kh×kwk_h\times k_wkh​×kw​,那么输出形状将会是

(nh−kh+1)×(nw−kw+1).(n_h-k_h+1) \times (n_w-k_w+1).(nh​−kh​+1)×(nw​−kw​+1).

所以卷积层的输出形状由输入形状和卷积核窗口形状决定。本节我们将介绍卷积层的两个超参数,即填充和步幅。它们可以对给定形状的输入和卷积核改变输出形状。

1. 填充

填充(padding)是指在输入高和宽的两侧填充元素(通常是0元素)。图5.2里我们在原输入高和宽的两侧分别添加了值为0的元素,使得输入高和宽从3变成了5,并导致输出高和宽由2增加到4。图5.2中的阴影部分为第一个输出元素及其计算所使用的输入和核数组元素:0×0+0×1+0×2+0×3=00\times0+0\times1+0\times2+0\times3=00×0+0×1+0×2+0×3=0。

一般来说,如果在高的两侧一共填充php_hph​行,在宽的两侧一共填充pwp_wpw​列,那么输出形状将会是

(nh−kh+ph+1)×(nw−kw+pw+1),(n_h-k_h+p_h+1)\times(n_w-k_w+p_w+1),(nh​−kh​+ph​+1)×(nw​−kw​+pw​+1),

也就是说,输出的高和宽会分别增加php_hph​和pwp_wpw​。

在很多情况下,我们会设置ph=kh−1p_h=k_h-1ph​=kh​−1和pw=kw−1p_w=k_w-1pw​=kw​−1来使输入和输出具有相同的高和宽。这样会方便在构造网络时推测每个层的输出形状。假设这里khk_hkh​是奇数,我们会在高的两侧分别填充ph/2p_h/2ph​/2行。如果khk_hkh​是偶数,一种可能是在输入的顶端一侧填充⌈ph/2⌉\lceil p_h/2\rceil⌈ph​/2⌉行,而在底端一侧填充⌊ph/2⌋\lfloor p_h/2\rfloor⌊ph​/2⌋行。在宽的两侧填充同理。

卷积神经网络经常使用奇数高宽的卷积核,如1、3、5和7,所以两端上的填充个数相等。对任意的二维数组X,设它的第i行第j列的元素为X[i,j]。当两端上的填充个数相等,并使输入和输出具有相同的高和宽时,我们就知道输出Y[i,j]是由输入以X[i,j]为中心的窗口同卷积核进行互相关计算得到的。

下面的例子里我们创建一个高和宽为3的二维卷积层,然后设输入高和宽两侧的填充数分别为1。给定一个高和宽为8的输入,我们发现输出的高和宽也是8。

import torch
from torch import nn# 定义一个函数来计算卷积层。它对输入和输出做相应的升维和降维
def comp_conv2d(conv2d, X):# (1, 1)代表批量大小和通道数(“多输入通道和多输出通道”一节将介绍)均为1X = X.view((1, 1) + X.shape)Y = conv2d(X)return Y.view(Y.shape[2:])  # 排除不关心的前两维:批量和通道# 注意这里是两侧分别填充1行或列,所以在两侧一共填充2行或列
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=3, padding=1)X = torch.rand(8, 8)
comp_conv2d(conv2d, X).shape

输出:

torch.Size([8, 8])

当卷积核的高和宽不同时,我们也可以通过设置高和宽上不同的填充数使输出和输入具有相同的高和宽。

# 使用高为5、宽为3的卷积核。在高和宽两侧的填充数分别为2和1
conv2d = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=(5, 3), padding=(2, 1))
comp_conv2d(conv2d, X).shape

输出:

torch.Size([8, 8])

2. 步幅

在上一节里我们介绍了二维互相关运算。卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅(stride)。

目前我们看到的例子里,在高和宽两个方向上步幅均为1。我们也可以使用更大步幅。图5.3展示了在高上步幅为3、在宽上步幅为2的二维互相关运算。可以看到,输出第一列第二个元素时,卷积窗口向下滑动了3行,而在输出第一行第二个元素时卷积窗口向右滑动了2列。当卷积窗口在输入上再向右滑动2列时,由于输入元素无法填满窗口,无结果输出。图5.3中的阴影部分为输出元素及其计算所使用的输入和核数组元素:0×0+0×1+1×2+2×3=80\times0+0\times1+1\times2+2\times3=80×0+0×1+1×2+2×3=8、0×0+6×1+0×2+0×3=60\times0+6\times1+0\times2+0\times3=60×0+6×1+0×2+0×3=6。

一般来说,当高上步幅为shs_hsh​,宽上步幅为sws_wsw​时,输出形状为

⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋.\lfloor(n_h-k_h+p_h+s_h)/s_h\rfloor \times \lfloor(n_w-k_w+p_w+s_w)/s_w\rfloor.⌊(nh​−kh​+ph​+sh​)/sh​⌋×⌊(nw​−kw​+pw​+sw​)/sw​⌋.

如果设置ph=kh−1p_h=k_h-1ph​=kh​−1和pw=kw−1p_w=k_w-1pw​=kw​−1,那么输出形状将简化为⌊(nh+sh−1)/sh⌋×⌊(nw+sw−1)/sw⌋\lfloor(n_h+s_h-1)/s_h\rfloor \times \lfloor(n_w+s_w-1)/s_w\rfloor⌊(nh​+sh​−1)/sh​⌋×⌊(nw​+sw​−1)/sw​⌋。更进一步,如果输入的高和宽能分别被高和宽上的步幅整除,那么输出形状将是(nh/sh)×(nw/sw)(n_h/s_h) \times (n_w/s_w)(nh​/sh​)×(nw​/sw​)。

下面我们令高和宽上的步幅均为2,从而使输入的高和宽减半。

conv2d = nn.Conv2d(1, 1, kernel_size=3, padding=1, stride=2)
comp_conv2d(conv2d, X).shape

输出:

torch.Size([4, 4])

接下来是一个稍微复杂点儿的例子。

conv2d = nn.Conv2d(1, 1, kernel_size=(3, 5), padding=(0, 1), stride=(3, 4))
comp_conv2d(conv2d, X).shape

输出:

torch.Size([2, 2])

为了表述简洁,当输入的高和宽两侧的填充数分别为php_hph​和pwp_wpw​时,我们称填充为(ph,pw)(p_h, p_w)(ph​,pw​)。特别地,当ph=pw=pp_h = p_w = pph​=pw​=p时,填充为ppp。当在高和宽上的步幅分别为shs_hsh​和sws_wsw​时,我们称步幅为(sh,sw)(s_h, s_w)(sh​,sw​)。特别地,当sh=sw=ss_h = s_w = ssh​=sw​=s时,步幅为sss。在默认情况下,填充为0,步幅为1。

小结

  • 填充可以增加输出的高和宽。这常用来使输出与输入具有相同的高和宽。
  • 步幅可以减小输出的高和宽,例如输出的高和宽仅为输入的高和宽的1/n1/n1/n(nnn为大于1的整数)。

pytorch学习笔记(二十):Padding-And-Strides相关推荐

  1. uniapp 学习笔记二十二 购物车页面结构搭建

    uniapp 学习笔记二十二 购物车页面结构搭建 cart.vue <template><view><view class="flex padding" ...

  2. PyTorch学习笔记(二)——回归

    PyTorch学习笔记(二)--回归 本文主要是用PyTorch来实现一个简单的回归任务. 编辑器:spyder 1.引入相应的包及生成伪数据 import torch import torch.nn ...

  3. Mr.J-- jQuery学习笔记(二十八)--DOM操作方法(添加方法总结)

    Table of Contents appendTo appendTo(source, target) 源代码 append prependTo ​ ​ ​ ​ prependTo源码 prepend ...

  4. 嵌入式系统设计师学习笔记二十八:嵌入式程序设计③——高级程序设计语言

    嵌入式系统设计师学习笔记二十八:嵌入式程序设计③--高级程序设计语言 解释程序和编译程序 编译器的工作阶段示意图 语法错误:非法字符,关键字或标识符拼写错误 语法错误:语法结构出错,if--endif ...

  5. Polyworks脚本开发学习笔记(二十)-补充几个常见操作指令的使用

    Polyworks脚本开发学习笔记(二十)-补充几个常见操作指令的使用 大概要写到结尾了,最后几篇就将手册的各常用命令再看一遍,组合一下,并列举出常见的一些有用的操作. DATA_COLOR_MAP数 ...

  6. JVM 学习笔记二十六、JVM监控及诊断工具-GUI篇

    二十六.JVM监控及诊断工具-GUI篇 1.工具概述 使用上一张命令行工具或组合能帮您获取目标Java应用性能相关的基础信息,但他们存在下列局限: (1)无法获取方法级别的分析数据,如方法间的调用关系 ...

  7. JVM 学习笔记二十五、JVM监控及诊断工具-命令行篇

    二十五.JVM监控及诊断工具-命令行篇 1.概述 性能诊断是软件工程师在日常工作中经常面对和解决的问题,在用户体验至上的今天,解决好应用软件的性能问题能带来非常大的收益. Java作为最流行的编程语言 ...

  8. 立创eda学习笔记二十八:在嘉立创购买pcb板并贴片(smt)

    完整的写一下,分为两部分: 1.下pcb订单 这个可以看之前写的一个博客: 立创eda学习笔记三:pcb购买_Gutie_bartholomew的博客-CSDN博客 补充一下,买pcb可以直接有几个途 ...

  9. pytorch学习笔记(十九):二维卷积层

    文章目录 1. 二维互相关运算 2. 二维卷积层 3. 图像中物体边缘检测 4. 通过数据学习核数组 卷积神经网络(convolutional neural network)是含有卷积层(convol ...

  10. pytorch学习笔记(十二):权重衰减

    文章目录 1. 方法 2. 高维线性回归实验 3. 从零开始实现 3.1 初始化模型参数 3.2 定义L2L_2L2​范数惩罚项 3.3 定义训练和测试 3.4 观察过拟合 3.5 使用权重衰减 4. ...

最新文章

  1. 攻击面管理预防网络攻击原理?
  2. Shader Compilation for Multiple Platforms
  3. Lua与Redis交互
  4. Delphi编程实现是否开启“平滑屏幕字体边缘“
  5. win7功能找不到信息服务器,win7系统找不到Internet信息服务的解决方法
  6. [Java基础]File基础
  7. array专题3-一道题目不断分析就会慢慢有了思路
  8. 基于PHP实现一个简单的在线聊天功能(轮询ajax )
  9. angularjs揭秘
  10. 【公众号】微信第三方登录(静默授权和非静默授权)(具体代码:U盘 新浪云SAE)...
  11. python 退出自定义函数_python通过自定义异常,提前退出方法
  12. 顺序表操作集 (20 分)
  13. Linux中几个简单实用的文本处理工具
  14. 学编程语言,记不住代码怎么办?
  15. 消除IBM P750小机上的黄色报警灯
  16. Jetbrains好用的插件(经验总结)
  17. read tcp 192.168.0.106:56298->185.199.111.153:80: wsarecv: An existing connection was forcibly close
  18. 线性代数学习笔记——线性方程组解的判定与解法
  19. C++程序设计谭浩强 第三章(程序设计初步)习题答案(部分有改进)
  20. 专访李智慧:架构是最高层次的规划和难以改变的决定

热门文章

  1. .Net程序测试阿里云OSS开放存储服务
  2. 2019杭电多校第九场 Rikka with Cake (hdu6681)
  3. 【第九届蓝桥杯大赛决赛真题】JAVA大学C组题解
  4. react native进一步学习(NavigatorIOS 学习)
  5. Android SharedPreference最佳实践
  6. Akka边学边写(3)-- ByteString介绍
  7. PDF模板报表导出(Java+Acrobat+itext)
  8. opengl笔记—— glMultMatrixf() 区别 glLoadMatrixf()
  9. Logback的配置说明
  10. 《设计模式详解》行为型模式 - 模板方法模式