💻
QMMMS的笔记
博客
  • QMMMS的笔记
  • agent
    • MCP的背景、原理和开发
    • Agent 历史与背景
    • Agentic Workflows
    • 环境检查与基础工具
    • Tool Call
    • 工具与运行时的值
    • temp
    • 处理 Tool Call error
    • trick
  • algorithm
    • 线性结构
    • 二叉树
    • 图
    • 查找
    • 排序
    • 动态规划
    • 优化方法
    • 数学
    • 迁移至Java
  • computer_composition
    • 系统总线
    • 存储器
    • 输入输出系统
    • 计算机的运算方法
    • 指令系统
    • 补充
  • computer_network
    • 引入
    • 应用层
    • 传输层
    • 网络层(数据平面)
    • 网络层(控制平面)
    • 链路层
    • 常见问答
    • 实验
  • database
    • SQL实战
    • 关系代数
    • 数据库设计
    • 规范化
    • 数据库基本概念
    • 查询原理
    • 数据库恢复技术
    • 并发控制
  • dev_tools
    • Git
    • Nginx
    • Spring
    • LangChain
    • PyTorch Cheat Sheet
    • MyBatis
    • MySQL Cheat Sheet
    • MySQL 补充
    • Redis
    • Docker
    • RocketMQ
    • Chrome
  • linux
    • Linux基础命令与使用
    • 文件与权限
    • 文件与目录操作
    • 权限属性高级
    • 命令与文件的查找
    • 文件压缩和打包
    • vim编辑器
    • shell变量
    • 命令补充
    • 数据流重定向
    • 管道命令
    • shell脚本
    • 用户管理
    • 用户间交流
    • 计划任务
    • 进程管理
    • 软件管理
    • 认识系统服务
    • 运维常用命令
    • 常用命令
  • llm
    • 大规模语言模型概述
    • 分布式训练概述
    • 有监督微调概述
    • 强化学习与LLM
    • LLM评估概述
    • 大模型应用
    • 理解大模型
    • 量化
    • 预训练
    • 上下文学习
  • machine_learning
    • 引入
    • 大致正确学习
    • 一致收敛
    • 偏差还是过拟合?
    • 可学习的充要条件
    • 非均匀可学习性
    • 计算复杂性
  • mathematics
    • 概率与统计基础
    • 线性代数基础
  • operating_system
    • 操作系统基本概念
    • 进程和线程
    • 同步,互斥与死锁
    • 内存管理
    • 文件系统
    • I/O系统
    • 保护与安全
    • 《现代操作系统》
  • statistical_learning
    • 统计学习引入
    • 线性回归
    • 分类
    • 重抽样方法
    • 线性模型选择与正则化
    • 非线性模型
    • 基于树的方法
    • 支持向量机
    • 无指导学习
    • 马尔科夫链和蒙托卡罗方法简明理解
    • R语言速查
  • deep_learning
    • basic_concepts
      • 逻辑回归与损失函数
      • 神经网络
      • 正则化、预处理、权重初始化
      • 优化算法
      • 机器学习策略
      • 复习:从计算机视觉的角度
      • 卷积神经网络
      • 深度卷积网络示例
      • 计算机视觉任务
      • 循环神经网络
      • 自然语言处理任务
      • 注意力
      • Transformers 家族
      • 显卡扫盲
      • 强化学习概述
    • semi-supervise
      • 半监督学习简介
      • Consistency Regularization
      • Proxy-label Methods
      • Holistic Methods
      • Generative Models
      • Graph-Based SSL
      • Self-Supervision for SSL
      • Other SSL methods
  • programming
    • cpp
      • STL
      • C++基础
      • 内存管理
      • 面向对象
    • java
      • 环境和介绍
      • 注释
      • String
      • 面向对象思想
      • Object
      • 包
      • 访问权限修饰符
      • 初始化块
      • 接口
      • 内部类
      • 注解
      • 枚举
      • 集合框架
      • List
      • Map
      • 泛型
      • 迭代
      • IO与流
      • 序列化
      • 异常
      • Lambda
      • Stream流
      • Socket
      • 缓冲
      • 命名规范
      • 拆箱装箱
      • 值传递
      • 深拷贝
      • 反射
      • JVM
      • 并发编程基础
    • python
      • 并发编程
      • 环境管理
  • software_engineering
    • basic_concepts
      • 系统分析与设计概述
      • 规划
      • 需求分析与原型设计
      • 项目管理
      • 建模
      • 数据库设计
      • 架构
      • 配置管理
      • 测试管理
      • 安全
      • 编码原则
      • 微服务
      • 补充内容
    • software_testing
      • CMMI基础
      • PPQA与SQA
      • 软件测试基础
      • 黑盒测试
      • 白盒测试
      • 集成测试
      • 系统测试
      • 测开面试补充
由 GitBook 提供支持
在本页
  • 边缘检测示例
  • 更多过滤器选择
  • Padding
  • 卷积步长
  • 多通道卷积
  • 单层卷积网络
  • 池化层
  • 卷积神经网络示例
  • 直观理解
  • 逆卷积
  • 空洞卷积
  • 计算量
在GitHub上编辑
  1. deep_learning
  2. basic_concepts

卷积神经网络

上一页复习:从计算机视觉的角度下一页深度卷积网络示例

最后更新于9个月前

边缘检测示例

卷积运算是卷积神经网络最基本的组成部分,这一小节使用边缘检测作为入门样例。

  • 如上图,左边是一个6×6的灰度图像。(因为是灰度图像,没有RGB三通道,所以它是6×6×1的矩阵,而不是6×6×3的)

  • 为了检测图像中的垂直边缘,构造中间的一个3×3矩阵,被称为过滤器(在论文它有时候会被称为核)。

  • 这个卷积运算的输出将会是一个4×4的矩阵,可以将它看成一个4×4的图像。

为什么这样可以做垂直边缘检测呢?这是另外一个例子。把输出看做图像,它能很好地体现图片边缘,而不是每一个像素点的灰度。

在这个例子中,好像检测到的边缘太粗了,是因为在这个例子中图片太小了。如果用一个1000×1000的图像,而不是6×6的图片,会发现其会很好地检测出图像中的垂直边缘。

卷积具有平移不变性,比方说目标是在图像的左上角,经过卷积之后,目标的特征也会在特征图的左上角;目标在图像的左下角,经过相同的卷积核卷积之后,目标的特征也会在特征图的左下角。

类似的,最大池化也可以看作具有平移不变性

更多过滤器选择

当然,过滤器不止这一种,来看看更多过滤器例子:

通过使用不同的过滤器,可以找出垂直的或是水平的边缘。

如上图,甚至不一定要去使用那些研究者们所选择的这九个数字,可以把这矩阵中的9个数字当成9个参数,并且在之后可以学习使用反向传播算法,其目标就是去理解这9个参数。

一些卷积核(kernel)的例子,尺寸都是[11x11]:

当图片某些部分与卷积核模式一致时,卷积核会给出强烈的响应,可以看作卷积核在积极寻找和匹配某种模式。

Padding

为了构建深度神经网络,一个基本的卷积操作就是padding。

如果按照之前的方式运算,用一个3×3的过滤器卷积一个6×6的图像,最后会得到一个4×4的输出矩阵。那是因为3×3过滤器在6×6矩阵中,只可能有4×4种可能的位置。

这样的话会有两个缺点:

  1. 每次做卷积操作,图像就会缩小,从6×6缩小到4×4,可能做了几次之后,图像就会变得很小了,甚至可能会缩小到只有1×1的大小。

  2. 那些在角落或者边缘区域的像素点,相比更靠中间的像素点,在输出中采用较少,意味着丢掉了图像边缘位置的许多信息。

为了解决这些问题,可以在卷积操作之前填充这幅图像。在这个案例中,可以沿着图像边缘再填充一层像素(习惯上,可以用0去填充)。如果6×6的图像被填充成了一个8×8的图像。再用3×3的过滤器做卷积,就会得到6×6的与原来大小相同的图像。

  • full卷积方法从filter和image刚相交开始做卷积

卷积步长

这里引入卷积步长的概念,之前例子中卷积步长为1,意思是每次移动一格,向右或向下。

当移动到下一行的时候,也是使用步长2,所以蓝色框移动到这里:

如果跳到某一位置时蓝色框(过滤器)不能覆盖原矩阵,则不进行计算。

多通道卷积

假如不仅想检测灰度图像的特征,也想检测RGB彩色图像的特征。彩色图像如果是6×6×3,这里的3指的是三个颜色通道,你可以把它想象成三个6×6图像的堆叠。为了检测图像的边缘或者其他的特征,需要跟一个三维的过滤器做卷积,它的维度是3×3×3,这样这个过滤器也有三层,对应红绿、蓝三个通道。

一个6×6×3的输入图像卷积上一个3×3×3的过滤器,步长为1,不使用Padding,得到一个4×4的二维输出。

当然可以使用多个过滤器,再把输出堆叠得到三维输出。一个6×6×3的输入图像卷积上两个3×3×3的过滤器,步长为1,不使用Padding,得到一个4×4×2的三维输出。

注:2D卷积并考虑通道数,与3D卷积但不考虑通道数一样,都是想象为立方体。

  • 1D 卷积(不考虑多通道):卷积核是一个向量

  • 2D 卷积(不考虑多通道):卷积核是一个矩阵

  • 3D 卷积(不考虑多通道):卷积核是一个立方体

单层卷积网络

现在考虑将这些卷积操作对应到神经网络中。

我们使用之前的例子,有一个6×6×3的输入图像卷积上两个3×3×3的过滤器,步长为1,不使用Padding。现在我们做对应:

在多层卷积处理完成后,可以将输出平滑或展开成多个单元。平滑处理后可以输出一个向量,再做后续处理。

一个典型的卷积神经网络通常有三层:

  • 一个是卷积层,我们常常用Conv来标注。

  • 一个是池化层,我们称之为POOL。

  • 最后一个是全连接层,用FC表示。

虽然仅用卷积层也有可能构建出很好的神经网络,但大部分神经网络架构师依然会添加池化层和全连接层。幸运的是,池化层和全连接层比卷积层更容易设计。后两节会快速讲解这两个概念。

池化层

除了卷积层,卷积网络也经常使用池化层来缩减模型的大小,提高计算速度,同时提高所提取特征的鲁棒性。

先举一个池化层的例子,输入是一个4×4矩阵,用到的池化类型是最大池化(max pooling)。执行最大池化的树池是一个2×2矩阵。把4×4的输入拆分成不同的色块。对于2×2的输出,输出的每个元素都是其对应色块中的最大元素值。

大部分情况下,最大池化很少用Padding。初始设置好之后池化过程中没有需要学习的参数。

最大化运算的实际作用就是,如果在过滤器中提取到某个特征,那么保留其最大值(类似神经元中激发程度超过阈值,超过阈值的那个数是最重要的)。尽管刚刚描述的直观理解经常被引用,但人们使用最大池化的主要原因是此方法在很多实验中效果都很好。

另外还有一种类型的池化,平均池化,这种运算顾名思义,选取的是每个区域的平均值。目前来说,最大池化比平均池化更常用。

卷积神经网络示例

这节加入全连接层并给出一个简单卷积神经网络示例。

有一张大小为32×32×3的输入图片,这是一张RGB模式的图片,如果想识别这张图片有从0-9这10个数字中的哪一个,可以构建一个神经网络来实现这个功能。

结构为:输入->卷积层1->池化层1->卷积层2->池化层2->全连接层1->全连接层2->softmax得到输出。

它有很多超参数,关于如何选定这些参数,之后会提供更多建议。常规做法是,尽量不要自己设置超参数,而是查看文献中别人采用了哪些超参数,选一个在别人任务中效果很好的架构,那么它也有可能适用于你自己的应用程序。

Q:为什么使用卷积?

A:假设有一张32×32×3维度的图片,用了6个大小为5×5的过滤器,输出维度为28×28×6。

不使用卷积,两层中的每个神经元彼此相连,然后计算权重矩阵,它等于4074×3072≈1400万,所以要训练的参数很多。

使用卷积,计算卷积层的参数数量,每个过滤器都是5×5,再加上偏差参数,每个过滤器就有26个参数,一共有6个过滤器,所以参数共计156个,参数数量很少。并且当图片变大时,参数数量不会变多因为它与输入无关。

简单来说,参数很少,代价很小,但依然有效。

直观理解

在一个多层的卷积神经网络中,可以把前面的卷积层看作提取简单的视觉信息,例如线,后面的卷积层提取高级的图像模式,这与人类视觉细胞有相似之处。

在提取高级的图像模式后,全连接层将其转化为特征向量,这些特征向量有聚类效应:同类图片的特征向量会比较相似。

CNN 的每层都给出了 C x H x W 的特征张量,我们将这个特征张量转为一个矩阵G,称为Gram matrix,通过让一张噪声图片的G和已有图像的G通过损失函数不断训练接近,我们可以从噪声图片慢慢得到原图像的纹理:

换一种思路,如果我们不断优化图片,使得某一层的神经元被最大激活(梯度上升),那么我们能看到CNN网络是如何看待分类任务的:

逆卷积

转置卷积又称反卷积,逆卷积。在主流的深度学习框架之中,如Tensorflow,Pytorch,Kreas中的函数名都是conv_transpose。

举个例子,将一个4X4的输入通过3X3的卷积核核进行普通卷积后(无padding,stride=1),将得到2X2的输出。而转置卷积将一个2X2的输入通过同样的3X3的卷积核,将得到一个4X4的输出。这看起来像是普通卷积的逆过程。事实上,这两者没有任何关系,操作过程也是不可逆的。

在实际卷积计算中,并不是通过卷积核在输入上进行滑动计算,效率太低,而是将卷积核转换为等效矩阵,将输入转化为向量,通过输入向量核卷积核矩阵的相乘获得输出向量。输出的向量经过整形便可得到我们的二维输出特征。

具体操作如下图所示,由于一个3X3的卷积核要在输入上不同位置卷积卷积4次,所以通过补0的方式,将卷积核分别置于一个4X4矩阵的四个角落,这样我们的输入可以直接和这四个4X4的矩阵进行卷积,而舍去了滑动操作。

进一步我们将输入拉成长向量,四个4X4的卷积核也进行拼接,如下图:

于是可以得到如下的结果,其实本身就是点积:

我们将一个1X16的行向量乘以一个16X4的矩阵,得到一个1X4的行向量。那么反过来一个1X4的向量乘以一个4X16的矩阵不就是能得到一个1X16的行向量,这就是转置卷积的思想

这里需要注意的是,这两个操作并不是可逆的,对于用一个卷积核,经过转置卷积操作后并不能恢复到原始的数值,只是保留了原始的形状。

转置卷积将一个2X2的输入通过同样的3X3的卷积核,将得到一个4X4的输出,具体操作如下:

空洞卷积

ilated/Atrous Convolution(中文叫做空洞卷积或者膨胀卷积) 或者是 Convolution with holes ,是在标准的 convolution map 里注入空洞,以此来增加 reception field。

相比原来的正常convolution,dilated convolution 多了一个 hyper-parameter 称之为 dilation rate,指的是kernel的间隔数量(e.g. 正常的 convolution 是 dilatation rate 1)。

池化可以扩大感受野,可以降低数据维度,可以减少计算量,但是会损失信息,而对于语义分割来说,这造成了发展瓶颈。而空洞卷积可以在扩大感受野的情况下不损失信息

计算量

  • FLOPS 注意全部大写 是floating point of per second的缩写,意指每秒浮点运算次数。可以理解为计算速度,用来衡量硬件的性能。

  • FLOPs 是floating point of operations的缩写,是浮点运算次数,理解为计算量,可以用来衡量算法/模型复杂度。

同一硬件,它的最大FLOPS(每秒运算浮点数代表着硬件性能,区分FLOPs)是相同的,不同网络,处理每张图片所需的FLOPs(浮点操作数)是不同的,所以同一硬件处理相同图片所需的FLOPs越小,相同时间内,就能处理更多的图片,速度也就越快。

处理每张图片所需的FLOPs与许多因素有关,比如你的网络层数,参数量,选用的激活函数等等,这里仅谈一下网络的参数量对其的影响,一般来说参数量越低的网络,FLOPs会越小,保存模型所需的内存小,对硬件内存要求比较低,因此比较对嵌入式端较友好。

对CNN而言,每个卷积层的参数量计算如下:

  • C 代表输入和输出通道数

  • k 代表卷积核宽与高

  • 使用Batch Normalization时不需要bias,此时计算式中的+1项去除

对CNN而言,每个卷积层的运算量计算如下:

  • 括号内的值表示卷积操作计算出feature map中一个点所需要的运算量(乘法和加法)

  • + 1 表示bias,W和H分别表示feature map的长和宽

  • 建议看多通道卷积一节的动态图理解

对全连接层而言,其参数量非常容易计算:

每一个输出神经元连接着所有输入神经元,所以有 I 个权重,每个输出神经元还要加一个bias。

对全连接层而言,其运算量计算如下:

第一个 I 表示乘法运算量,I-1 表示加法运算量,+1表示bias,×O 表示计算O个神经元的值。

矩阵乘法的 FLOPs

A 的维度是 (m,n) B的维度是(n,p) 结果矩阵 C 的维度将是(m,p)

矩阵 element_wise 操作 FLOPs

比如矩阵加法,ReLU,对 ReLU(A) 求导等运算,都是矩阵中每个元素的一次操作,这类操作的运算量如下, ewops 表示 element wise operations

反向传播的计算量是前向传播计算量的几倍?

粗略估算是2倍,因为网络实现的差异,略有浮动。简单一点的解释就是反向传播需要对输入和权重进行求导,所以是前向传播计算量的两倍。

计算代码--以PyTorch框架为例:

# 计算
from torchvision.models import resnet50
from thop import profile
model = resnet50()
dummy_input = torch.randn(1, 3, 224, 224)
macs, params = profile(model, inputs=(dummy_input, ))
#输出
from thop import clever_format
macs, params = clever_format([macs, params], "%.3f")

对这个6×6的图像进行卷积运算,卷积运算用“∗*∗”来表示,用3×3的过滤器对其进行卷积。

过滤器先和对应灰度图像矩阵进行元素乘法(element-wise products)运算,再求和得到输出值。对于输出的左上角值 −5-5−5 来说,计算过程如下:

[3×10×01×(1)1×15×08×(−1)2×17×02×(−1)]=[30−110−820−2]\begin{bmatrix} 3 \times 1 & 0 \times 0 & 1 \times \left(1 \right) \\ 1 \times 1 & 5 \times 0 & 8 \times \left( - 1 \right) \\ 2 \times1 & 7 \times 0 & 2 \times \left( - 1 \right) \\ \end{bmatrix} = \begin{bmatrix}3 & 0 & - 1 \\ 1 & 0 & - 8 \\ 2 & 0 & - 2 \\\end{bmatrix}​3×11×12×1​0×05×07×0​1×(1)8×(−1)2×(−1)​​=​312​000​−1−8−2​​
3+1+2+0+0+0+(−1)+(−8)+(−2)=−53+1+2+0+0 +0+(-1)+(-8) +(-2)=-53+1+2+0+0+0+(−1)+(−8)+(−2)=−5

Sobel过滤器:[10−120−210−1]\begin{bmatrix}1 & 0 & - 1 \\ 2 & 0 & - 2 \\ 1 & 0 & - 1 \\\end{bmatrix}​121​000​−1−2−1​​,它的优点在于增加了中间一行元素的权重,这使得结果的鲁棒性会更高一些。

Scharr过滤器:[30−3100−1030−3]\begin{bmatrix} 3& 0 & - 3 \\ 10 & 0 & - 10 \\ 3 & 0 & - 3 \\\end{bmatrix}​3103​000​−3−10−3​​,实际上也是一种垂直边缘检测,如果你将其翻转90度,你就能得到对应水平边缘检测。

这背后的数学解释是,对于n×nn×nn×n的图像,用f×ff×ff×f的过滤器做卷积,那么输出的维度就是(n−f+1)×(n−f+1)(n-f+1)×(n-f+1)(n−f+1)×(n−f+1)。

Valid卷积方法不填充图像,将会给你一个(n−f+1)×(n−f+1)(n-f+1)×(n-f+1)(n−f+1)×(n−f+1)维的输出。

Same卷积方法填充图像并得到和输入大小一样的输出,具体来说,填充p=(f−1)/2p=(f-1)/2p=(f−1)/2个像素点。

习惯上,计算机视觉中,fff通常是奇数。因为只有fff是奇数的情况下,Same卷积才会有自然的填充,并且奇数维过滤器有一个中心点,在计算机视觉里,如果有一个中心像素点会更方便,便于指出过滤器的位置。

我们可以设置卷积步长为其他值,比如上图这个例子卷积步长为2,在计算完最左上角的3∗33*33∗3个元素(左上角为2)之后,计算左上角为7的3∗33*33∗3个元素。

总结一下维度情况,如果有一个n×nn×nn×n的矩阵或者n×nn×nn×n的图像,与一个f×ff×ff×f的矩阵卷积,或者说f×ff×ff×f的过滤器。Padding是ppp,步幅为sss,输出尺寸为:

⌊n+2p−fs+1⌋×⌊n+2p−fs+1⌋\lfloor{\frac{n + 2p - f}{s}}+1\rfloor \times \lfloor{\frac{n + 2p - f}{s}}+1\rfloor⌊sn+2p−f​+1⌋×⌊sn+2p−f​+1⌋

总结一下维度,如果有一个n×n×ncn \times n \times n_{c}n×n×nc​的输入图像,这里的ncn_{c}nc​就是通道数目,然后卷积上一个f×f×ncf×f×n_{c}f×f×nc​的过滤器,按照惯例,前一个ncn_{c}nc​和后一个ncn_{c}nc​必须数值相同,步长为1,不使用Padding,然后得到(n−f+1)×(n−f+1)×nc′(n-f+1)×(n-f+1)×n_{c^{'}}(n−f+1)×(n−f+1)×nc′​的输出,这里nc′n_{c^{'}}nc′​其实就是下一层的通道数,它就是用的过滤器的个数。

复习一下,在从输入a[0]a^{\left\lbrack 0\right\rbrack}a[0](也就是xxx)前向传播到a[1]a^{[1]}a[1]时,我们做的计算是:

z[1]=W[1]a[0]+b[1]z^{[1]} = W^{[1]}a^{[0]} + b^{[1]}z[1]=W[1]a[0]+b[1]
a[1]=g(z[1])a^{[1]} = g(z^{[1]})a[1]=g(z[1])

6×6×3的输入图像为a[0]a^{\left\lbrack 0\right\rbrack}a[0](也就是xxx)

两个3×3×3的过滤器为W[1]W^{[1]}W[1]

两个4×4的输出为W[1]a[0]W^{[1]}a^{[0]}W[1]a[0]

再加上偏差b[1]b^{[1]}b[1],然后应用激活函数ggg,演化为一个4×4×2维度的a[1]a^{[1]}a[1]

最后总结一下用于描述卷积神经网络中的一层(以lll层为例),也就是卷积层的各种标记:

f[l]f^{[l]}f[l]表示表示lll层中过滤器大小为f×ff×ff×f

p[l]p^{[l]}p[l]来标记Padding的数量

s[l]s^{[l]}s[l]标记步幅

某层数据维度表示为nH[l]×nW[l]×nc[l]n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}nH[l]​×nW[l]​×nc[l]​,分别为高,宽,颜色通道数

这一层的输入会是nH[l−1]×nW[l−1]×nc[l−1]n_{H}^{\left\lbrack l - 1 \right\rbrack} \times n_{W}^{\left\lbrack l - 1 \right\rbrack} \times n_{c}^{\left\lbrack l - 1\right\rbrack}nH[l−1]​×nW[l−1]​×nc[l−1]​,因为它是上一层的激活值

这一层的输出nH[l]=⌊nH[l−1]+2p[l]−f[l]s[l]+1⌋n_{H}^{[l]} = \lfloor\frac{n_{H}^{\left\lbrack l - 1 \right\rbrack} +2p^{[l]} - f^{[l]}}{s^{[l]}} +1\rfloornH[l]​=⌊s[l]nH[l−1]​+2p[l]−f[l]​+1⌋

这一层的输出nW[l]=⌊nW[l−1]+2p[l]−f[l]s[l]+1⌋n_{W}^{[l]} = \lfloor\frac{n_{W}^{\left\lbrack l - 1 \right\rbrack} +2p^{[l]} - f^{[l]}}{s^{[l]}} +1\rfloornW[l]​=⌊s[l]nW[l−1]​+2p[l]−f[l]​+1⌋

这一层的输出nc[l]n_{c}^{[l]}nc[l]​等于该层中过滤器的数量

复习一下,过滤器中通道的数量必须与输入中通道的数量一致,所以所有过滤器维度等于f[l]×f[l]×nc[l−1]f^{[l]} \times f^{[l]} \times n_{c}^{\left\lbrack l - 1 \right\rbrack}f[l]×f[l]×nc[l−1]​

如果有mmm个例子,就是有mmm个激活值的集合,那么输出A[l]=m×nH[l]×nW[l]×nc[l]A^{[l]} = m \times n_{H}^{[l]} \times n_{W}^{[l]} \times n_{c}^{[l]}A[l]=m×nH[l]​×nW[l]​×nc[l]​

这就像是应用了一个规模为2的过滤器(只是像,没有使用过滤器),因为我们选用的是2×2区域,步幅是2,这些就是最大池化的超参数。即f=2f=2f=2,s=2s=2s=2。

之前计算卷积层输出大小的公式同样适用于最大池化,即⌊n+2p−fs+1⌋\lfloor\frac{n + 2p - f}{s} + 1\rfloor⌊sn+2p−f​+1⌋,而ncn_cnc​保持不变(对ncn_cnc​个通道分别做池化)。

一个普遍的规律是,随着层数增加,高度nHn_{H}nH​和宽度nWn_{W}nW​都会减小,而通道数量ncn_{c}nc​会增加,激活值尺寸会逐渐变小。

params=Co×(k2×Ci+1)params=C_o \times (k^2 \times C_i + 1)params=Co​×(k2×Ci​+1)
FLOPs=(Ci×k2+Ci×k2−1+1)×Co×H×WFLOPs=(C_i \times k^2 + C_i \times k^2 - 1 + 1) \times C_o \times H \times WFLOPs=(Ci​×k2+Ci​×k2−1+1)×Co​×H×W

Ci×k2C_i\times k^2Ci​×k2 表示一次卷积操作中的乘法运算量

Ci×k2−1C_i\times k^2 - 1Ci​×k2−1 表示一次卷积操作中的加法运算量

在计算机视觉论文中,常常将一个’乘-加’组合视为一次浮点运算,英文表述为’Multi-Add’,运算量正好是上面的算法减半,此时的运算量为:Ci×k2×Co×H×WC_i \times k^2 \times C_o \times H \times WCi​×k2×Co​×H×W

params=(I+1)×Oparams=(I+1)\times Oparams=(I+1)×O
FLOPs=(I+I−1+1)×O=2I×OFLOPs=(I+I-1+1)\times O = 2I\times OFLOPs=(I+I−1+1)×O=2I×O

矩阵 C 的每一个元素都是一次点积运算,一共 (m×pm\times pm×p)次点积运算。每个点积运算有 n 次 乘法和 n - 1 次加法。所以

FLOPs=m×p×(n+n−1)FLOPs=m\times p\times(n+n-1)FLOPs=m×p×(n+n−1)
FLOPs(fewops(A))=SIZE(A)FLOPs(f_{ewops}(A))=SIZE(A)FLOPs(fewops​(A))=SIZE(A)
卷积运算
边缘检测
如果用一个更大的图像做边缘检测
垂直和水平过滤器
自动学习过滤器的参数
填充图像