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

卷积神经网络中的填充(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).(nhkh+1)×(nwkw+1).
所以卷积层的输出形状由输入形状和卷积核窗口形状决定。卷积层还有两个超参数,即填充和步幅。它们可以对给定形状的输入和卷积核改变输出形状。

填充(padding)

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

对于输入:
input=[012345678]input = \begin{bmatrix} 0 & 1 & 2 \\ 3 & 4 &5 \\ 6 & 7 & 8 \end{bmatrix}input=036147258

我们在原输入高和宽的两侧分别添加了值为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} 0361472580000000360014700258000000

一般来说,如果在高的两侧一共填充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),(nhkh+ph+1)×(nwkw+pw+1),

也就是说,输出的高和宽会分别增加php_hphpwp_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}0000000360014700258000000[0213]=09216319377825438410160

在很多情况下,我们会设置
ph=kh−1pw=kw−1p_h=k_h-1 \\ p_w=k_w-1ph=kh1pw=kw1

使输入和输出具有相同的高和宽。这样会方便在构造网络时推测每个层的输出形状。假设这里khk_hkh是奇数,我们会在高的两侧分别填充ph/2p_h/2ph/2行。如果khk_hkh是偶数,一种可能是在输入的顶端一侧填充⌈ph/2⌉\lceil p_h/2\rceilph/2行,而在底端一侧填充⌊ph/2⌋\lfloor p_h/2\rfloorph/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}0000000360014700258000000[0213]=[0213][0000][0213][0102][0213][0060][0213][7070]=[0688]

一般来说,当高上步幅为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.(nhkh+ph+sh)/sh×(nwkw+pw+sw)/sw.

如果设置
ph=kh−1pw=kw−1p_h=k_h-1\\p_w=k_w-1ph=kh1pw=kw1
那么输出形状将简化为
⌊(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+sh1)/sh×(nw+sw1)/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(nhkh+ph+sh)/sh×(nwkw+pw+sw)/sw=(83+1×2+2)/2×(83+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(nhkh+ph+sh)/sh×(nwkw+pw+sw)/sw=(83+0×2+3)/3×(85+1×2+4)/4=2×2

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/507985.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(pytorch-深度学习系列)CNN的多输入通道和多输出通道

CNN的多输入通道和多输出通道 之前的输入都视为二维数组,但是真实数据往往具有更高的维度,彩色图像有RGB三个颜色通道,那么这个图像(高为h,宽为w)可以表示为3∗h∗w3*h*w3∗h∗w的多维数组,一般…

(pytorch-深度学习系列)CNN中的池化层-学习笔记

CNN中的池化层 首先,池化(pooling)层的提出是为了缓解卷积层对位置的过度敏感性。 什么意思? 比如在图像边缘检测问题中,实际图像里,我们的目标物体不会总出现在固定位置,即使我们连续拍摄同…

(pytorch-深度学习系列)卷积神经网络LeNet-学习笔记

卷积神经网络LeNet 先上图:LeNet的网络结构 卷积(6个5∗5的核)→降采样(池化)(2∗2的核,步长2)→卷积(16个5∗5的核)→降采样(池化)(2∗2的核,步长2)→全连接16∗5∗5→120→全连接120→84→全连接84→10\begin{matrix}卷积 \\ (6个5*5的核…

(pytorch-深度学习系列)深度卷积神经网络AlexNet

深度卷积神经网络AlexNet 文字过多,但是重点已经标出来了 背景 在LeNet提出后的将近20年里,神经网络一度被其他机器学习方法超越,如支持向量机。虽然LeNet可以在早期的小数据集上取得好的成绩,但是在更大的真实数据集上的表现并…

(pytorch-深度学习系列)使用重复元素的网络(VGG)

使用重复元素的网络(VGG) VGG的名字来源于论文作者所在的实验室Visual Geometry Group,VGG提出了可以通过重复使用简单的基础块来构建深度模型的思路。 VGG Block(VGG 块) VGG块的组成规律是:连续使用数个相同的填充为1、窗口形…

(pytorch-深度学习系列)网络中的网络(NiN)

网络中的网络(NiN) LeNet、AlexNet和VGG在设计上的共同之处是:先以由卷积层构成的模块充分抽取空间特征,再以由全连接层构成的模块来输出分类结果。其中,AlexNet和VGG对LeNet的改进主要在于如何对这两个模块加宽&…

(pytorch-深度学习)包含并行连结的网络(GoogLeNet)

包含并行连结的网络(GoogLeNet) 在2014年的ImageNet图像识别挑战赛中,一个名叫GoogLeNet的网络结构大放异彩。它虽然在名字上向LeNet致敬,但在网络结构上已经很难看到LeNet的影子。GoogLeNet吸收了NiN中网络串联网络的思想&#…

(pytorch-深度学习)批量归一化

批量归一化 批量归一化(batch normalization)层能让较深的神经网络的训练变得更加容易 通常来说,数据标准化预处理对于浅层模型就足够有效了。随着模型训练的进行,当每层中参数更新时,靠近输出层的输出较难出现剧烈变…

(pytorch-深度学习)实现残差网络(ResNet)

实现残差网络(ResNet) 我们一般认为,增加神经网络模型的层数,充分训练后的模型理论上能更有效地降低训练误差。理论上,原模型解的空间只是新模型解的空间的子空间。也就是说,如果我们能将新添加的层训练成恒等映射f(x)xf(x) xf(…

(pytorch-深度学习)实现稠密连接网络(DenseNet)

稠密连接网络(DenseNet) ResNet中的跨层连接设计引申出了数个后续工作。稠密连接网络(DenseNet)与ResNet的主要区别在于在跨层连接上的主要区别: ResNet使用相加DenseNet使用连结 ResNet(左)…

(pytorch-深度学习)语言模型-学习笔记

语言模型 自然语言处理中最常见的数据是文本数据。我们可以把一段自然语言文本看作一段离散的时间序列。 假设一段长度为TTT的文本中的词依次为w1,w2,…,wTw_1, w_2, \ldots, w_Tw1​,w2​,…,wT​,那么在离散的时间序列中: wtw_twt​(1≤t…

(pytorch-深度学习)循环神经网络

循环神经网络 在nnn元语法中,时间步ttt的词wtw_twt​基于前面所有词的条件概率只考虑了最近时间步的n−1n-1n−1个词。如果要考虑比t−(n−1)t-(n-1)t−(n−1)更早时间步的词对wtw_twt​的可能影响,需要增大nnn。 这样模型参数的数量将随之呈指数级增长…

配置jupyter-pytorch深度学习环境

配置jupyter-pytorch深度学习环境 安装anaconda3新建环境,命名为pytorch在虚拟环境里安装jupyter activate pytorch pip install jupyter安装可视化插件,ipywidgets,并且关联 pip install ipywidgets jupyter nbextension enable --py wid…

(pytorch-深度学习)SE-ResNet的pytorch实现

SE-ResNet的pytorch实现 残差块: class Resiual_block(nn.Module):def __init__(self, in, middle_out, out, kernel_size3, padding1):self.out_channel middle_outsuper(Resiual_block, self).__init__()self.shortcut nn.Sequential(nn.Conv2d(nin, nout, ke…

(pytorch-深度学习)循环神经网络的从零开始实现

循环神经网络的从零开始实现 首先,我们读取周杰伦专辑歌词数据集: import time import math import numpy as np import torch from torch import nn, optim import torch.nn.functional as F import sys sys.path.append("..") device tor…

(pytorch-深度学习)使用pytorch框架nn.RNN实现循环神经网络

使用pytorch框架nn.RNN实现循环神经网络 首先,读取周杰伦专辑歌词数据集。 import time import math import numpy as np import torch from torch import nn, optim import torch.nn.functional as Fimport sys sys.path.append("..") device torch.d…

(pytorch-深度学习)通过时间反向传播

通过时间反向传播 介绍循环神经网络中梯度的计算和存储方法,即通过时间反向传播(back-propagation through time)。 正向传播和反向传播相互依赖。正向传播在循环神经网络中比较直观,而通过时间反向传播其实是反向传播在循环神经…

(pytorch-深度学习)门控循环单元(GRU)

门控循环单元(GRU) 循环神经网络中的梯度计算 当时间步数较大或者时间步较小时,循环神经网络的梯度较容易出现衰减或爆炸。虽然裁剪梯度可以应对梯度爆炸,但无法解决梯度衰减的问题。通常由于这个原因,循环神经网络在…

(pytorch-深度学习)长短期记忆(LSTM)

长短期记忆(LSTM) LSTM 中引入了3个门,即 输入门(input gate)遗忘门(forget gate)输出门(output gate)以及与隐藏状态形状相同的记忆细胞(某些文献把记忆细…

(pytorch-深度学习)深度循环神经网络

深度循环神经网络 循环神经网络只有一个单向的隐藏层,在深度学习应用里,我们通常会用到含有多个隐藏层的循环神经网络,也称作深度循环神经网络。 下图演示了一个有LLL个隐藏层的深度循环神经网络,每个隐藏状态不断传递至当前层的…