卷积神经网络中的填充(padding)和步幅(stride)

之前写过一篇blog,描述CNN网络层的输入和输入尺寸的计算关系,但是并没有描述的很全面,这里全面描述了影响输出尺寸的两个超参数padding和stride,查阅了相关资料,编码理解了pytorch中CNN网络的输入输出关系。

对于CNN网络,一般来说,假设输入形状是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).
所以卷积层的输出形状由输入形状和卷积核窗口形状决定。卷积层还有两个超参数,即填充和步幅。它们可以对给定形状的输入和卷积核改变输出形状。

填充(padding)

填充(padding)是指在输入高和宽的两侧填充元素(通常是0元素)。

对于输入:
input=[012345678]input = \begin{bmatrix} 0 & 1 & 2 \\ 3 & 4 &5 \\ 6 & 7 & 8 \end{bmatrix}input=⎣⎡​036​147​258​⎦⎤​

我们在原输入高和宽的两侧分别添加了值为0的元素,使得输入高和宽从3变成了5,并导致输出高和宽由2增加到4:

[012345678]→[0000000120034500678000000]\begin{bmatrix} 0 & 1 & 2 \\ 3 & 4 &5 \\ 6 & 7 & 8 \end{bmatrix} \rightarrow \begin{bmatrix} 0 & 0&0&0&0\\ 0&0&1&2&0 \\ 0&3&4&5&0\\0&6&7&8&0\\0&0&0&0&0\end{bmatrix} ⎣⎡​036​147​258​⎦⎤​→⎣⎢⎢⎢⎢⎡​00000​00360​01470​02580​00000​⎦⎥⎥⎥⎥⎤​

一般来说,如果在高的两侧一共填充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​。

[0000000120034500678000000]∗[0123]=[03849192510213743166780]\begin{bmatrix} 0 & 0&0&0&0\\ 0&0&1&2&0 \\ 0&3&4&5&0\\0&6&7&8&0\\0&0&0&0&0\end{bmatrix} * \begin{bmatrix} 0&1\\2&3 \end{bmatrix} = \begin{bmatrix} 0&3&8&4\\9 &19& 25& 10\\21 &37& 43& 16\\6 &7 &8 &0 \end{bmatrix}⎣⎢⎢⎢⎢⎡​00000​00360​01470​02580​00000​⎦⎥⎥⎥⎥⎤​∗[02​13​]=⎣⎢⎢⎡​09216​319377​825438​410160​⎦⎥⎥⎤​

在很多情况下,我们会设置
ph=kh−1pw=kw−1p_h=k_h-1 \\ p_w=k_w-1ph​=kh​−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):X = X.view((1, 1) + X.shape)# (1, 1)代表批量大小和通道数,均为1Y = 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

输出不变

步幅(stride)

卷积窗口从输入数组的最左上方开始,按从左往右、从上往下的顺序,依次在输入数组上滑动。我们将每次滑动的行数和列数称为步幅(stride)。

目前我们看到的例子里,在高和宽两个方向上步幅均为1, 我们也可以使用更大的步幅。

在下面的问题中:
在高上步幅为3、在宽上步幅为2。可以看到,输出第一列第二个元素时,卷积窗口向下滑动了3行,而在输出第一行第二个元素时卷积窗口向右滑动了2列。当卷积窗口在输入上再向右滑动2列时,由于输入元素无法填满窗口,无结果输出。

[0000000120034500678000000]∗[0123]=[[0123]∗[0000][0123]∗[0012][0123]∗[0600][0123]∗[7700]]=[0868]\begin{bmatrix} 0 & 0&0&0&0\\ 0&0&1&2&0 \\ 0&3&4&5&0\\0&6&7&8&0\\0&0&0&0&0\end{bmatrix} * \begin{bmatrix} 0&1\\2&3 \end{bmatrix} = \begin{bmatrix} {\begin{bmatrix} 0&1\\2&3 \end{bmatrix}* \begin{bmatrix} 0&0\\0&0 \end{bmatrix} \quad \begin{bmatrix} 0&1\\2&3 \end{bmatrix}* \begin{bmatrix} 0&0\\1&2 \end{bmatrix}}\\ \\ \\ {\begin{bmatrix} 0&1\\2&3 \end{bmatrix}* \begin{bmatrix} 0&6\\0&0 \end{bmatrix} \quad \begin{bmatrix} 0&1\\2&3 \end{bmatrix}* \begin{bmatrix} 7&7\\0&0 \end{bmatrix}} \end{bmatrix} = \begin{bmatrix} 0&8 \\ 6&8\end{bmatrix}⎣⎢⎢⎢⎢⎡​00000​00360​01470​02580​00000​⎦⎥⎥⎥⎥⎤​∗[02​13​]=⎣⎢⎢⎢⎢⎢⎢⎡​[02​13​]∗[00​00​][02​13​]∗[01​02​][02​13​]∗[00​60​][02​13​]∗[70​70​]​⎦⎥⎥⎥⎥⎥⎥⎤​=[06​88​]

一般来说,当高上步幅为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−1pw=kw−1p_h=k_h-1\\p_w=k_w-1ph​=kh​−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])

代入公式,这里应该这么算:
⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(8−3+1×2+2)/2⌋×⌊(8−3+1×2+2)/2⌋=4×4\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 = \\\lfloor(8-3+1\times2+2)/2\rfloor \times \lfloor(8-3+1\times2+2)/2\rfloor = 4 \times 4⌊(nh​−kh​+ph​+sh​)/sh​⌋×⌊(nw​−kw​+pw​+sw​)/sw​⌋=⌊(8−3+1×2+2)/2⌋×⌊(8−3+1×2+2)/2⌋=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])

代入公式,这里应该这么算:
⌊(nh−kh+ph+sh)/sh⌋×⌊(nw−kw+pw+sw)/sw⌋=⌊(8−3+0×2+3)/3⌋×⌊(8−5+1×2+4)/4⌋=2×2\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 = \\\lfloor(8-3+0\times2+3)/3\rfloor \times \lfloor(8-5+1\times2+4)/4\rfloor = 2 \times 2⌊(nh​−kh​+ph​+sh​)/sh​⌋×⌊(nw​−kw​+pw​+sw​)/sw​⌋=⌊(8−3+0×2+3)/3⌋×⌊(8−5+1×2+4)/4⌋=2×2

(pytorch-深度学习系列)卷积神经网络中的填充(padding)和步幅(stride)相关推荐

  1. 吴恩达 深度学习系列--卷积神经网络(Convolutional Neural Networks)-03(目标检测)

    目标检测 3.1 目标定位(Object localization) 3.1.1概念 3.1.2 监督学习任务定义目标标签y 3.2 特征点检测(Landmark detection) 3.3 基于滑 ...

  2. 深度学习_卷积神经网络中感受野的理解和计算

    卷积神经网络感受野的计算方法 https://blog.csdn.net/qq_36653505/article/details/83473943?utm_medium=distribute.pc_r ...

  3. 深度学习:卷积神经网络中的卷积核

    卷积核就是图像处理时,给定输入图像,输入图像中一个小区域中像素加权平均后成为输出图像中的每个对应像素,其中权值由一个函数定义,这个函数称为卷积核.又称滤波器. 同样提取某个特征,经过不同卷积核卷积后效 ...

  4. 【深度学习】卷积神经网络-图片分类案例(pytorch实现)

    前言 前文已经介绍过卷积神经网络的基本概念[深度学习]卷积神经网络-CNN简单理论介绍.下面开始动手实践吧.本文任务描述如下: 从公开数据集CIFAR10中创建训练集.测试集数据,使用Pytorch构 ...

  5. 【深度学习】解析神经网络中的数值稳定性、模型初始化和分布偏移(Pytorch)

    [深度学习]解析神经网络中的数值稳定性.模型初始化和分布偏移 文章目录 1 概述1.1 梯度消失和梯度爆炸1.2 打破对称性 2 参数初始化 3 环境和分布偏移3.1 协变量偏移3.2 标签偏移3.3 ...

  6. 【深度学习】:《PyTorch入门到项目实战》(十二)卷积神经网络:填充(padding)和步幅(stride)

    [深度学习]:<PyTorch入门到项目实战>(十二)填充(padding)和步幅(stride) ✨本文收录于[深度学习]:<PyTorch入门到项目实战>专栏,此专栏主要记 ...

  7. 【深度学习】卷积神经网络速成

    [深度学习]卷积神经网络速成 文章目录 [深度学习]卷积神经网络速成 1 概述 2 组成 2.1 卷积层 2.2 池化层 2.3 全连接层 3 一个案例 4 详细分析 1 概述 前馈神经网络(feed ...

  8. 深度学习~卷积神经网络(CNN)概述

    目录​​​​​​​ 1. 卷积神经网络的形成和演变 1.1 卷积神经网络结构 1.2 卷积神经网络的应用和影响 1.3 卷积神经网络的缺陷和视图 1.3.1 缺陷:可能错分 1.3.2 解决方法:视图 ...

  9. 深度学习之卷积神经网络(12)深度残差网络

    深度学习之卷积神经网络(12)深度残差网络 ResNet原理 ResBlock实现 AlexNet.VGG.GoogleLeNet等网络模型的出现将神经网络的法阵带入了几十层的阶段,研究人员发现网络的 ...

最新文章

  1. asp.net[web.config] httphandlers 与实现自由定义访问地址
  2. Android 截屏并写入SD卡中
  3. 入职3个月的Java程序员面临转正,挑战大厂重燃激情!
  4. 美团支付平台产品规划
  5. PHP格子在线自动发卡网源码 全新一键安装版
  6. 数据质量 开源框架_Netflix开源Polynote框架,可简化数据科学和机器学习工作流程...
  7. 在reader中勾选pdf复选框_轻松控制PDF文件的打开方式
  8. 使用Python批量提取并保存docx文档中的图片
  9. php遗漏,PHP被遗漏的执行函数
  10. python新手入门代码-Python 新手入门习题及代码
  11. 【java笔记】打印流printStream
  12. Linux线程间死锁分析
  13. IE浏览器异常,无法正常使用,如何修复?
  14. 22. 协程与Python中的多任务异步协程
  15. 工程总承包(EPC)项目经理培训项目背景介绍
  16. 你好,罗茜——爱要怎么说出口
  17. YOLOV5代码解析——优化器
  18. C盘Windows XP,D盘Windows7,双系统安装纪录
  19. SDN跟网络虚拟化的完美结合
  20. 项目经理在团队不同阶段的领导风格

热门文章

  1. js获取dom html元素属性,JS如何通过元素的CLASS属性得到对应的DOM对象?
  2. 改进初学者的PID-手自动切换
  3. verilog异步复位jk触发器_Verilog专题(九)DFF、Dlatch、JK flipflop
  4. 中科大在50年代的教学理念
  5. 计算机网络中缓存技术,编程达人
  6. exfat最佳单元大小_双动圈四喇叭单元的头戴式耳机,DACOM HF002上手体验
  7. 掌握Java编程思想,学好Java只需要三步?网友:真的吗?
  8. python循环结构语句_python控制语句---循环结构语句
  9. 【学习笔记】第二章——管程(解决生产者消费者问题、封装、Java 体现)
  10. java token_Java实现基于token认证的方法示例