文章目录

  • 卷积层
    • 卷积计算
    • 二维卷积层
    • 特征图和感受野
    • 填充
    • 步幅
  • 小结

卷积层

卷积神经网络(convolutional neural network)是含有卷积层(convolutional layer)的神经网络。它有高和宽两个空间维度,常用来处理图像数据。下面我们将介绍简单形式的二维卷积层的工作原理。

卷积计算

在二维卷积层中,一个二维输入数组和一个二维核(kernel)数组通过互相关运算输出一个二维数组。 我们用一个具体例子来解释二维互相关运算的含义。如图5.1所示,输入是一个高和宽均为3的二维数组。我们将该数组的形状记为3×33×3或(3,3)。核数组的高和宽分别为2。该数组在卷积计算中又称卷积核或过滤器(filter)。卷积核窗口(又称卷积窗口)的形状取决于卷积核的高和宽,即2×22×2。图中的阴影部分为第一个输出元素及其计算所使用的输入和核数组元素:0×0+1×1+3×2+4×3=190×0+1×1+3×2+4×3=19。

一般来说,当卷积核的形状为(kh×kw)(k_h \times k_w)(kh​×kw​)时,输出的形状为
(nh−kh+1)×(nk−kh+1)(n_h - k_h + 1)\times(n_k - k_h + 1)(nh​−kh​+1)×(nk​−kh​+1)

import torch
from torch import nndef corr2d(X, K):  h, w = K.shapeY = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1))for i in range(Y.shape[0]):for j in range(Y.shape[1]):Y[i, j] = (X[i: i + h, j: j + w] * K).sum()return Y
X = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]])
K = torch.tensor([[0, 1], [2, 3]])
corr2d(X, K)
tensor([[19., 25.],[37., 43.]])

二维卷积层

二维卷积层将输入和卷积核做互相关运算,并加上一个标量偏差来得到输出。卷积层的模型参数包括了卷积核和标量偏差。在训练模型的时候,通常我们先对卷积核随机初始化,然后不断迭代卷积核和偏差。

下面基于corr2d函数来实现一个自定义的二维卷积层。在构造函数__init__里我们声明weightbias这两个模型参数。前向计算函数forward则是直接调用corr2d函数再加上偏差。

class Conv2D(nn.Module):def __init__(self, kernel_size):super(Conv2D, self).__init__()self.weight = nn.Parameter(torch.randn(kernel_size))self.bias = nn.Parameter(torch.randn(1))def forward(self, x):return corr2d(x, self.weight) + self.bias
# 卷积窗口形状为p×qp×q的卷积层称为p×qp×q卷积层。
# 同样,p×qp×q卷积或p×qp×q卷积核说明卷积核的高和宽分别为pp和qq。

特征图和感受野

二维卷积层输出的二维数组可以看作是输入在空间维度(宽和高)上某一级的表征,也叫特征图(feature map)。影响元素xx的前向计算的所有可能输入区域(可能大于输入的实际尺寸)叫做xx的感受野(receptive field)。以下图为例,输入中阴影部分的四个元素是输出中阴影部分元素的感受野。我们将图中形状为2×22×2的输出记为YY,并考虑一个更深的卷积神经网络:将YY与另一个形状为2×22×2的核数组做互相关运算,输出单个元素zz。那么,zz在YY上的感受野包括YY的全部四个元素,在输入上的感受野包括其中全部9个元素。可见,我们可以通过更深的卷积神经网络使特征图中单个元素的感受野变得更加广阔,从而捕捉输入上更大尺寸的特征。

我们常使用“元素”一词来描述数组或矩阵中的成员。在神经网络的术语中,这些元素也可称为“单元”。

填充

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

卷积神经网络经常使用奇数高宽的卷积核,如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])

步幅

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

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

一般来说,当高上步幅为shs_hsh​,宽上步幅为sws_wsw​时,输出形状为
[(nh−kh+ph+sh)sh]×[(nw−kw+pw+sw)sw]\left[ \frac{(n_h - k_h + p_h + s_h)}{s_h} \right] \times \left[ \frac{(n_w - k_w + p_w + s_w)}{s_w} \right][sh​(nh​−kh​+ph​+sh​)​]×[sw​(nw​−kw​+pw​+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])

小结

  • 一般来说,当卷积核的形状为(kh×kw)(k_h \times k_w)(kh​×kw​)时,输出的形状为
    (nh−kh+1)×(nk−kh+1)(n_h - k_h + 1)\times(n_k - k_h + 1)(nh​−kh​+1)×(nk​−kh​+1)

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

  • 当高上步幅为shs_hsh​,宽上步幅为sws_wsw​时,输出形状为
    [(nh−kh+ph+sh)sh]×[(nw−kw+pw+sw)sw]\left[ \frac{(n_h - k_h + p_h + s_h)}{s_h} \right] \times \left[ \frac{(n_w - k_w + p_w + s_w)}{s_w} \right][sh​(nh​−kh​+ph​+sh​)​]×[sw​(nw​−kw​+pw​+sw​)​]

  • 池化部分较为简单,和卷积原理类似。主要为最大池化层和平均池化层,为的是缓解卷积后导致的敏感性

pytorch卷积详解相关推荐

  1. 将卷积引入transformer中VcT(Introducing Convolutions to Vision Transformers)的pytorch代码详解

    文章目录 1. Motivation: 2. Method 2.1 Convolutional Token Embedding 模块 2.2 Convolutional Projection For ...

  2. 3D 池化(MaxPool3D) 和 3D(Conv3d) 卷积详解

    3D 池化(MaxPool3D) 和 3D(Conv3d) 卷积详解 池化和卷积的过程是类似的,只是池化没有权重,相比起来更容易说明计算的过程.这里从 3D 池化开始详细介绍 MaxPool3D 和 ...

  3. pytorch函数详解

    pytorch函数详解 在typora这里写之后复制到简书上 1. torchvision 1.1 transforms.Compose(transforms) 把几个转换组合 example: fr ...

  4. YOLO V1~V7论文及Pytorch实现详解

    YOLO~V1论文及Pytorch实现详解 论文地址:https://paperswithcode.com/paper/you-only-look-once-unified-real-time-obj ...

  5. 对比损失的PyTorch实现详解

    对比损失的PyTorch实现详解 本文以SiT代码中对比损失的实现为例作介绍. 论文:https://arxiv.org/abs/2104.03602 代码:https://github.com/Sa ...

  6. 转置卷积详解(原理+实验)

    文章目录 转置卷积详解 转置卷积理论

  7. 高斯模糊java代码_Java编程实现高斯模糊和图像的空间卷积详解

    高斯模糊 高斯模糊(英语:Gaussian Blur),也叫高斯平滑,是在Adobe Photoshop.GIMP以及Paint.NET等图像处理软件中广泛使用的处理效果,通常用它来减少图像杂讯以及降 ...

  8. BilSTM 实体识别_NLP-入门实体命名识别(NER)+Bilstm-CRF模型原理Pytorch代码详解——最全攻略

    最近在系统地接触学习NER,但是发现这方面的小帖子还比较零散.所以我把学习的记录放出来给大家作参考,其中汇聚了很多其他博主的知识,在本文中也放出了他们的原链.希望能够以这篇文章为载体,帮助其他跟我一样 ...

  9. BilSTM 实体识别_NLP入门实体命名识别(NER)+BilstmCRF模型原理Pytorch代码详解——最全攻略...

    来自 | 知乎   作者 | seven链接 | https://zhuanlan.zhihu.com/p/79552594编辑 | 机器学习算法与自然语言处理公众号本文仅作学术分享,如有侵权,请联系 ...

最新文章

  1. 配置Tomcat使用https协议
  2. 提取ESX/ESXI4.0脚本安装文件ks.cfg、ks-first.cfg和ks-first-safe.cfg
  3. .Net/C# 实现: FlashFXP 地址簿中站点密码的加解密算法
  4. mysql 怎么登陆远程服务器_教你手机怎么远程连接云服务器
  5. 【python数据挖掘课程】二十九.数据预处理之字符型转换数值型、标准化、归一化处理
  6. linux模式匹配,sed的模式匹配用法探讨
  7. ef oracle 批量更新慢_详解Oracle中多表关联批量插入、批量更新与批量删除
  8. Python演示--UDP套接字真的无连接吗?
  9. ibatis.net 学习笔记
  10. PuTTY免输密码自动登录Linux,让 Putty 保存密码,自动登陆的三种方法
  11. 强制打开BIOS中禁用的I/OAT DCA(二)
  12. 2019最新某私塾在线高级java软件架构师实战培训教程
  13. android 双拼输入法,高效输入解决方案——双拼输入法
  14. 电脑卡住了怎么保存excel_win7系统遇到死机没及时保存excel文件该怎么办
  15. java程序员3-5年职业规划,附源代码
  16. [算法题]返回数组A的元素组成的小于n的最大数
  17. 【报告分享】2021年中国新能源汽车行业洞察-Mob研究院(附下载)
  18. LM08丨网格系列之网格反转(精)
  19. 80个自我提升的网站
  20. 计算机运维方向要考什么证,IT运维项目经理考的证

热门文章

  1. no matching manifest for windows/amd64 10.0.18362 in the manifest list entries.
  2. 一台计算机中 虚拟机数量取决于,虚拟机对电脑伤害大吗
  3. java中图片排版,教你轻松集成华为Image Kit图文排版功能
  4. linux系统安装微信开发者工具版本太低问题(已解决)
  5. 河北省2023年职业院校(中职组)技能大赛“网络搭建与应用”赛项竞赛样题
  6. 【Linux】Linux扩容(VmWare扩容linux根目录)
  7. 综合布线系统概念及组成课堂作业
  8. C++中string::npos的用法总结
  9. kali linux入侵安卓7.0,【教程】metasploit入侵安卓手机
  10. 【技术】如何确定IC的输入阻抗