神经网络基础部件-卷积层详解

news2024/9/27 19:21:38

前言

在全连接层构成的多层感知机网络中,我们要通过将图像数据展平成一维向量来送入模型,但这会忽略了每个图像的空间结构信息。理想的策略应该是要利用相近像素之间的相互关联性,将图像数据二维矩阵送给模型中学习。

卷积神经网络(convolutional neural network,CNN)正是一类强大的、专为处理图像数据(多维矩阵)而设计的神经网络,CNN 的设计是深度学习中的一个里程碑式的技术。在 Transformer 应用到 CV 领域之前,基于卷积神经网络架构的模型在计算机视觉领域中占主导地位,几乎所有的图像识别、目标检测、语义分割、3D目标检测、视频理解等任务都是以 CNN 方法为基础。

卷积神经网络核心网络层是卷积层,其使用了卷积(convolution)这种数学运算,卷积是一种特殊的线性运算。另外,通常来说,卷积神经网络中用到的卷积运算和其他领域(例如工程领域以及纯数学领域)中的定义并不完全一致。

一,卷积

在理解卷积层之前,我们首先得理解什么是卷积操作。

卷积与傅里叶变换有着密切的关系。例如两函数的傅里叶变换的乘积等于它们卷积后的傅里叶变换,利用此一性质,能简化傅里叶分析中的许多问题。

operation 视语境有时译作“操作”,有时译作“运算”,本文不做区分。

1.1,卷积运算定义

为了给出卷积的定义, 这里从现实世界会用到函数的例子出发。

假设我们正在用激光传感器追踪一艘宇宙飞船的位置。我们的激光传感器给出 一个单独的输出 x ( t ) x(t) x(t),表示宇宙飞船在时刻 t t t 的位置。 x x x t t t 都是实值的,这意味着我们可以在任意时刻从传感器中读出飞船的位置。

现在假设我们的传感器受到一定程度的噪声干扰。为了得到飞船位置的低噪声估计,我们对得到的测量结果进行平均。显然,时间上越近的测量结果越相关,所 以我们采用一种加权平均的方法,对于最近的测量结果赋予更高的权重。我们可以采用一个加权函数 w ( a ) w(a) w(a) 来实现,其中 a a a 表示测量结果距当前时刻的时间间隔。如果我们对任意时刻都采用这种加权平均的操作,就得到了一个新的对于飞船位置的平滑估计函数 s s s :
s ( t ) = ∫ x ( a ) w ( t − a ) d a s(t) = \int x(a)w(t-a )da s(t)=x(a)w(ta)da
这种运算就叫做卷积(convolution)。更一般的,卷积运算的数学公式定义如下:
连续定义 :    h ( x ) = ( f ∗ g ) ( x ) = ∫ − ∞ ∞ f ( t ) g ( x − t ) d t (1) 连续定义: \; h(x)=(f*g)(x) = \int_{-\infty}^{\infty} f(t)g(x-t)dt \tag{1} 连续定义:h(x)=(fg)(x)=f(t)g(xt)dt(1)

离散定义 :    h ( x ) = ( f ∗ g ) ( x ) = ∑ t = − ∞ ∞ f ( t ) g ( x − t ) (2) 离散定义: \; h(x) = (f*g)(x) = \sum^{\infty}_{t=-\infty} f(t)g(x-t) \tag{2} 离散定义:h(x)=(fg)(x)=t=f(t)g(xt)(2)

以上卷积计算公式可以这样理解:

  1. 先对函数 g ( t ) g(t) g(t) 进行反转(reverse),相当于在数轴上把 g ( t ) g(t) g(t) 函数从右边褶到左边去,也就是卷积的“卷”的由来。
  2. 然后再把 g ( t ) g(t) g(t) 函数向左平移 x x x 个单位,在这个位置对两个函数的对应点相乘,然后相加,这个过程是卷积的“积”的过程。

1.2,卷积的意义

对卷积这个名词,可以这样理解:所谓两个函数的卷积( f ∗ g f*g fg),本质上就是先将一个函数翻转,然后进行滑动叠加。在连续情况下,叠加指的是对两个函数的乘积求积分,在离散情况下就是加权求和,为简单起见就统一称为叠加。

因此,卷积运算整体来看就是这么一个过程:

翻转—>滑动—>叠加—>滑动—>叠加—>滑动—>叠加…

多次滑动得到的一系列叠加值,构成了卷积函数。

这里多次滑动过程对应的是 t t t 的变化过程。

那么,卷积的意义是什么呢?可以从卷积的典型应用场景-图像处理来理解:

  1. 为什么要进行“卷”?进行“卷”(翻转)的目的其实是施加一种约束,它指定了在“积”的时候以什么为参照。在空间分析的场景,它指定了在哪个位置的周边进行累积处理。
  2. 在图像处理的中,卷积处理的结果,其实就是把每个像素周边的,甚至是整个图像的像素都考虑进来,对当前像素进行某种加权处理。因此,“积”是全局概念,或者说是一种“混合”,把两个函数进行时间(信号分析)或空间(图像处理)上进行混合。

卷积意义的理解来自知乎问答,有所删减和优化。

1.3,从实例理解卷积

一维卷积的实例有 “丢骰子” 等经典实例,这里不做展开描述,本文从二维卷积用于图像处理的实例来理解。

一般,数字图像可以表示为如下所示矩阵:

本节图片摘自知乎用户马同学的文章。

图像矩阵

而卷积核 g g g 也可以用一个矩阵来表示,如:
g = [ b − 1 , − 1 b − 1 , 0 b − 1 , 1 b 0 , − 1 b 0 , 0 b 0 , 1 b 1 , − 1 b 1 , 0 b 1 , 1 ] g = \begin{bmatrix} &b_{-1,-1} &b_{-1,0} &b_{-1,1} \\ &b_{0,-1} &b_{0,0} &b_{0,1} \\ &b_{1,-1} &b_{1,0} &b_{1,1} \end{bmatrix} g= b1,1b0,1b1,1b1,0b0,0b1,0b1,1b0,1b1,1
按照卷积公式的定义,则目标图片的第 ( u , v ) (u, v) (u,v) 个像素的二维卷积值为:
( f ∗ g ) ( u , v ) = ∑ i ∑ j f ( i , j ) g ( u − i , v − j ) = ∑ i ∑ j a i , j b u − i , v − j (f * g)(u, v)=\sum_{i} \sum_{j} f(i, j)g(u-i, v-j)=\sum_{i} \sum_{j} a_{i,j} b_{u-i,v-j} (fg)(u,v)=ijf(i,j)g(ui,vj)=ijai,jbui,vj
展开来分析二维卷积计算过程就是,首先得到原始图像矩阵中 ( u , v ) (u, v) (u,v) 处的矩阵:
f = [ a u − 1 , v − 1 a u − 1 , v a u − 1 , v + 1 a u , v − 1 a u , v a u , v + 1 a u + 1 , v − 1 a u + 1 , v a u + 1 , v + 1 ] f=\begin{bmatrix} &a_{u-1,v-1} &a_{u-1,v} &a_{u-1,v+1}\\ &a_{u,v-1} &a_{u,v} &a_{u,v+1} \\ &a_{u+1,v-1} &a_{u+1,v} &a_{u+1,v+1} \end{bmatrix} f= au1,v1au,v1au+1,v1au1,vau,vau+1,vau1,v+1au,v+1au+1,v+1
然后将图像处理矩阵翻转(两种方法,结果等效),如先沿 x x x 轴翻转,再沿 y y y 轴翻转(相当于将矩阵 g g g 旋转 180 度):
g = [ b − 1 , − 1 b − 1 , 0 b − 1 , 1 b 0 , − 1 b 0 , 0 b 0 , 1 b 1 , − 1 b 1 , 0 b 1 , 1 ] = > [ b 1 , − 1 b 1 , 0 b 1 , 1 b 0 , − 1 b 0 , 0 b 0 , 1 b − 1 , − 1 b − 1 , 0 b − 1 , 1 ] = [ b 1 , 1 b 1 , 0 b 1 , − 1 b 0 , 1 b 0 , 0 b 0 , − 1 b − 1 , 1 b − 1 , 0 b − 1 , − 1 ] = g ′ \begin{aligned} g &= \begin{bmatrix} &b_{-1,-1} &b_{-1,0} &b_{-1,1}\\ &b_{0,-1} &b_{0,0} &b_{0,1} \\ &b_{1,-1} &b_{1,0} &b_{1,1} \end{bmatrix} => \begin{bmatrix} &b_{1,-1} &b_{1,0} &b_{1,1}\\ &b_{0,-1} &b_{0,0} &b_{0,1} \\ &b_{-1,-1} &b_{-1,0} &b_{-1,1} \end{bmatrix} \\ &= \begin{bmatrix} &b_{1,1} &b_{1,0} &b_{1,-1}\\ &b_{0,1} &b_{0,0} &b_{0,-1} \\ &b_{-1,1} &b_{-1,0} &b_{-1,-1} \end{bmatrix} = g^{'} \end{aligned} g= b1,1b0,1b1,1b1,0b0,0b1,0b1,1b0,1b1,1 => b1,1b0,1b1,1b1,0b0,0b1,0b1,1b0,1b1,1 = b1,1b0,1b1,1b1,0b0,0b1,0b1,1b0,1b1,1 =g
最后,计算卷积时,就可以用 f f f g ′ g′ g 的内积:
f ∗ g ( u , v ) = a u − 1 , v − 1 × b 1 , 1 + a u − 1 , v × b 1 , 0 + a u − 1 , v + 1 × b 1 , − 1 + a u , v − 1 × b 0 , 1 + a u , v × b 0 , 0 + a u , v + 1 × b 0 , − 1 + a u + 1 , v − 1 × b − 1 , 1 + a u + 1 , v × b − 1 , 0 + a u + 1 , v + 1 × b − 1 , − 1 \begin{aligned} f * g(u,v) &= a_{u-1,v-1} \times b_{1,1} + a_{u-1,v} \times b_{1,0} + a_{u-1,v+1} \times b_{1,-1} \\ &+ a_{u,v-1} \times b_{0,1} + a_{u,v} \times b_{0,0} + a_{u,v+1} \times b_{0,-1} \\ &+ a_{u+1,v-1} \times b_{-1,1} + a_{u+1,v} \times b_{-1,0} + a_{u+1,v+1} \times b_{-1,-1} \end{aligned} fg(u,v)=au1,v1×b1,1+au1,v×b1,0+au1,v+1×b1,1+au,v1×b0,1+au,v×b0,0+au,v+1×b0,1+au+1,v1×b1,1+au+1,v×b1,0+au+1,v+1×b1,1

计算过程可视化如下动图所示,注意动图给出的是 g g g 不是 g ′ g' g

二维卷积计算过程

以上公式有一个特点,做乘法的两个对应变量 a , b a, b a,b 的下标之和都是 ( u , v ) (u,v) (u,v),其目的是对这种加权求和进行一种约束,这也是要将矩阵 g g g 进行翻转的原因。上述计算比较麻烦,实际计算的时候,都是用翻转以后的矩阵,直接求矩阵内积就可以了。

1.4,图像卷积(二维卷积)

在机器学习和图像处理领域,卷积的主要功能是在一个图像(或某种特征) 上滑动一个卷积核(即滤波器),通过卷积操作得到一组新的特征。一幅图像在经过卷积操作后得到结果称为特征映射(Feature Map)。如果把图像矩阵简写为 I I I,把卷积核 Kernal 简写为 K K K,则目标图片的第 ( i , j ) (i,j) (i,j) 个像素的卷积值为:
h ( i , j ) = ( I ∗ K ) ( i , j ) = ∑ m ∑ n I ( m , n ) K ( i − m , j − n ) (3) h(i,j) = (I*K)(i,j)=\sum_m \sum_n I(m,n)K(i-m,j-n) \tag{3} h(i,j)=(IK)(i,j)=mnI(m,n)K(im,jn)(3)
可以看出,这和一维情况下的卷积公式 2 是一致的。因为卷积的可交换性,我们也可以把公式 3 等价地写作:
h ( i , j ) = ( I ∗ K ) ( i , j ) = ∑ m ∑ n I ( i − m , j − n ) K ( m , n ) (4) h(i,j) = (I*K)(i,j)=\sum_m \sum_n I(i-m,j-n)K(m,n) \tag{4} h(i,j)=(IK)(i,j)=mnI(im,jn)K(m,n)(4)
通常,下面的公式在机器学习库中实现更为简单,因为 m m m n n n 的有效取值范围相对较小。

卷积运算可交换性的出现是因为我们将核相对输入进行了翻转(flip),从 m m m 增 大的角度来看,输入的索引在增大,但是卷积核的索引在减小。我们将卷积核翻转的唯一目 的是实现可交换性。尽管可交换性在证明时很有用,但在神经网络的应用中却不是一个重要的性质。相反,许多神经网络库会实现一个互相关函数corresponding function),它与卷积相同但没有翻转核:
h ( i , j ) = ( I ∗ K ) ( i , j ) = ∑ m ∑ n I ( i + m , j + n ) K ( m , n ) (5) h(i,j) = (I*K)(i,j)=\sum_m \sum_n I(i+m,j+n)K(m,n) \tag{5} h(i,j)=(IK)(i,j)=mnI(i+m,j+n)K(m,n)(5)

互相关函数的运算,是两个序列滑动相乘,两个序列都不翻转。卷积运算也是滑动相乘,但是其中一个序列需要先翻转,再相乘。

1.5,互相关和卷积

互相关和卷积运算的关系,可以通过下述公式理解:
Y = W ⊗ X = rot180 ( W ) ∗ X \begin{aligned} Y &= W\otimes X \\ &= \text{rot180}(W) * X \end{aligned} Y=WX=rot180(W)X
其中 ⊗ \otimes 表示互相关运算, ∗ * 表示卷积运算, rot180(⋅) \text{rot180(⋅)} rot180(⋅) 表示旋转 180 度, Y Y Y 为输出矩阵。从上式可以看出,互相关和卷积的区别仅仅在于卷积核是否进行翻转。因此互相关也可以称为不翻转卷积.

离散卷积可以看作矩阵的乘法,然而,这个矩阵的一些元素被限制为必须和另外一些元素相等。

在神经网络中使用卷积是为了进行特征抽取,卷积核是否进行翻转和其特征抽取的能力无关(特别是当卷积核是可学习的参数时),因此卷积和互相关在能力上是等价的。事实上,很多深度学习工具中卷积操作其实都是互相关操作,用来减少一些不必要的操作或开销(不反转 Kernal)

总的来说,

  1. 我们实现的卷积操作不是原始数学含义的卷积,而是工程上的卷积,但一般也简称为卷积。
  2. 在实现卷积操作时,并不会反转卷积核。

二,卷积层

在传统图像处理中,线性空间滤波的原理实质上是指指图像 f f f 与滤波器核 w w w 进行乘积之和(卷积)运算。核是一个矩阵,其大小定义了运算的邻域,其系数决定了该滤波器(也称模板、窗口滤波器)的性质,并通过设计不同核系数(卷积核)来实现低通滤波(平滑)和高通滤波(锐化)功能,因此我们可以认为卷积是利用某些设计好的参数组合(卷积核)去提取图像空域上相邻的信息。

2.1,卷积层定义

在全连接前馈神经网络中,如果第 l l l 层有 M l M_l Ml 个神经元,第 l − 1 l-1 l1 层有 M l − 1 M_{l-1} Ml1 个 神经元,连接边有 M l × M l − 1 M_{l}\times M_{l-1} Ml×Ml1 个,也就是权重矩阵有 M l × M l − 1 M_{l}\times M_{l-1} Ml×Ml1 个参数。当 M l M_l Ml M l − 1 M_{l-1} Ml1 都很大时,权重矩阵的参数就会非常多,训练的效率也会非常低。

如果采用卷积来代替全连接,第 l l l 层的净输入 z ( l ) z^{(l)} z(l) 为第 l − 1 l-1 l1 层激活值 a ( l − 1 ) a^{(l−1)} a(l1) 和卷积核 w ( l ) ∈ R K w^{(l)}\in \mathbb{R}^K w(l)RK 的卷积,即
z ( l ) = w ( l ) ⊗ a ( l − 1 ) + b ( l ) z^{(l)} = w^{(l)}\otimes a^{(l−1)} + b^{(l)} z(l)=w(l)a(l1)+b(l)
其中 b ( l ) ∈ R b^{(l)}\in \mathbb{R} b(l)R 为可学习的偏置。

上述卷积层公式也可以写成这样的形式: Z = W ∗ A + b Z = W*A+b Z=WA+b

根据卷积层的定义,卷积层有两个很重要的性质:

  1. 局部连接:在卷积层(假设是第 l l l 层)中的每一个神经元都只和下一层(第 l − 1 l − 1 l1 层)中某个局部窗口内的神经元相连,构成一个局部连接网络。
  2. 权重共享:作为参数的卷积核 w ( 𝑙 ) w^{(𝑙)} w(l) 对于第 l l l 层的所有的神经元都是相同的。权重共享可以理解为一个卷积核只捕捉输入数据中的一种特定的局部特征.因此,如果要提取多种特征就需要使用多个不同的卷积核。

全连接层和卷积层对比

总而言之,卷积层的作用是提取一个局部区域的特征,不同的卷积核(滤波器)相当于不同的特征提取器。为了提高卷积网络的表示能力,可以在每一层使用多个不同的特征映射,即增加卷积核(滤波器)的数量,以更好地提取图像的特征。

2.2,卷积层理解

前面章节内容中,卷积的输出形状只取决于输入形状和卷积核的形状。而神经网络中的卷积层,在卷积的标准定义基础上,还引入了卷积核的滑动步长和零填充来增加卷积的多样性,从而可以更灵活地进行特征抽取。

  • 步长(Stride):指卷积核每次滑动的距离
  • 零填充(Zero Padding):在输入图像的边界填充元素(通常填充元素是0)

卷积层定义:每个卷积核(Kernel)在输入矩阵上滑动,并通过下述过程实现卷积计算:

  1. 在来自卷积核的元素和输入特征图子矩阵的元素之间进行乘法以获得输出感受野。
  2. 然后将相乘的值与添加的偏差相加以获得输出矩阵中的值。

卷积层数值计算过程可视化如下图 1 所示:

Example of Convolutional layer

来源论文 Improvement of Damage Segmentation Based on Pixel-Level Data Balance Using VGG-Unet。

注意,卷积层的输出 Feature map 的大小取决于输入的大小、Pad 数、卷积核大小和步长。在 Pytorch 框架中,图片(feature map)经卷积 Conv2D输出大小计算公式如下: ⌊ N = W − F + 2 P S + 1 ⌋ \left \lfloor N = \frac{W-F+2P}{S}+1 \right \rfloor N=SWF+2P+1

其中 ⌊ ⌋ \lfloor \rfloor 是向下取整符号,用于结果不是整数时进行向下取整(PytorchConv2d 卷积函数的默认参数 ceil_mode = False,即默认向下取整, dilation = 1),其他符号解释如下:

  • 输入图片大小 W×W(默认输入尺寸为正方形)
  • Filter 大小 F×F
  • 步长 S
  • padding的像素数 P
  • 输出特征图大小 N×N

上图1侧重于解释数值计算过程,而下图2则侧重于解释卷积层的五个核心概念的关系:

  • 输入 Input Channel
  • 卷积核组 WeightsBias
  • 过滤器 Filter
  • 卷积核 kernal
  • 输出 Feature Map

三通道经过两组过滤器的卷积过程

上图是三通道经过两组过滤器的卷积过程,在这个例子中,输入是三维数据 3 × 32 × 32 3\times 32 \times32 3×32×32,经过权重参数尺寸为 2 × 3 × 5 × 5 2\times 3\times 5\times 5 2×3×5×5 的卷积层后,输出为三维 2 × 28 × 28 2\times 28\times 28 2×28×28,维数并没有变化,只是每一维内部的尺寸有了变化,一般都是要向更小的尺寸变化,以便于简化计算。

假设三维卷积(也叫滤波器)尺寸为 ( c i n , k , k ) (c_{in}, k, k) (cin,k,k),一共有 c o u t c_{out} cout 个滤波器,即卷积层参数尺寸为 ( c o u t , c i n , k , k ) (c_{out}, c_{in}, k, k) (cout,cin,k,k) ,则标准卷积层有以下特点:

  1. 输出的 feature map 的数量等于滤波器数量 c o u t c_{out} cout,即卷积层参数值确定后,feature map 的数量也确定,而不是根据前向计算自动计算出来;
  2. 对于每个输出,都有一个对应的过滤器 Filter,图例中 Feature Map-1 对应 Filter-1;
  3. 每个 Filter 内都有一个或多个卷积核 Kernal,对应每个输入通道(Input Channel),图例为 3,对应输入的红绿蓝三个通道;
  4. 每个 Filter 只有一个 Bias 值,图例中 Filter-1 对应 b1;
  5. 卷积核 Kernal 的大小一般是奇数如: 1 × 1 1\times 1 1×1 3 × 3 3\times 3 3×3

注意,以上内容都描述的是标准卷积,随着技术的发展,后续陆续提出了分组卷积、深度可分离卷积、空洞卷积等。详情可参考我之前的文章-MobileNetv1论文详解。

2.3,卷积层 api

Pytorch 框架中对应的卷积层 api 如下:

class torch.nn.Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True)

主要参数解释:

  • in_channels(int) – 输入信号的通道。
  • out_channels(int) – 卷积产生的通道。
  • kerner_size(int or tuple) - 卷积核的尺寸。
  • stride(int or tuple, optional) - 卷积步长,默认值为 1
  • padding(int or tuple, optional) - 输入的每一条边补充 0 的层数,默认不填充。
  • dilation(int or tuple, optional) – 卷积核元素之间的间距,默认取值 1
  • groups(int, optional) – 从输入通道到输出通道的阻塞连接数。
  • bias(bool, optional) - 如果 bias=True,添加偏置。

示例代码:

###### Pytorch卷积层输出大小验证
import torch
import torch.nn as nn
import torch.autograd as autograd
# With square kernels and equal stride
# output_shape: height = (50-3)/2+1 = 24.5,卷积向下取整,所以 height=24.
m = nn.Conv2d(16, 33, 3, stride=2)
# # non-square kernels and unequal stride and with padding
# m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2))  # 输出shape: torch.Size([20, 33, 28, 100])
# # non-square kernels and unequal stride and with padding and dilation
# m = nn.Conv2d(16, 33, (3, 5), stride=(2, 1), padding=(4, 2), dilation=(3, 1))  # 输出shape: torch.Size([20, 33, 26, 100])
input = autograd.Variable(torch.randn(20, 16, 50, 100))
output = m(input)

print(output.shape)  # 输出shape: torch.Size([20, 16, 24, 49])

三,卷积神经网络

卷积神经网络一般由卷积层、汇聚层和全连接层构成。

3.1,汇聚层

通常当我们处理图像时,我们希望逐渐降低隐藏表示的空间分辨率、聚集信息,这样随着我们在神经网络中层叠的上升,每个神经元对其敏感的感受野(输入)就越大。

汇聚层(Pooling Layer)也叫子采样层(Subsampling Layer),其作用不仅是进降低卷积层对位置的敏感性,同时降低对空间降采样表示的敏感性。

与卷积层类似,汇聚层运算符由一个固定形状的窗口组成,该窗口根据其步幅大小在输入的所有区域上滑动,为固定形状窗口(有时称为汇聚窗口)遍历的每个位置计算一个输出。然而,不同于卷积层中的输入与卷积核之间的互相关计算,汇聚层不包含参数。相反,池运算是确定性的,我们通常计算汇聚窗口中所有元素的最大值或平均值。这些操作分别称为最大汇聚层(maximum pooling)和平均汇聚层(average pooling)。

在这两种情况下,与互相关运算符一样,汇聚窗口从输入张量的左上⻆开始,从左往右、从上往下的在输入张量内滑动。在汇聚窗口到达的每个位置,它计算该窗口中输入子张量的最大值或平均值。计算最大值或平均值是取决于使用了最大汇聚层还是平均汇聚层。

最大汇聚层计算结果

值得注意的是,与卷积层一样,汇聚层也可以通过改变填充和步幅以获得所需的输出形状。

3.2.,汇聚层 api

Pytorch 框架中对应的聚合层 api 如下:

class torch.nn.MaxPool2d(kernel_size, stride=None, padding=0, dilation=1, return_indices=False, ceil_mode=False)

主要参数解释

  • kernel_size(int or tuple):max pooling 的窗口大小。
  • stride(int or tuple, optional):max pooling的窗口移动的步长。默认值是kernel_size`。
  • padding(int or tuple, optional):默认值为 0,即不填充像素。输入的每一条边补充 0 的层数。
  • dilation:滑动窗中各元素之间的距离。
  • ceil_mode:默认值为 False,即上述公式默认向下取整,如果设为 True,计算输出信号大小的时候,公式会使用向上取整。

Pytorch 中池化层默认ceil mode = false,而 Caffe 只实现了 ceil mode= true 的计算方式。

示例代码:

import torch
import torch.nn as nn
import torch.autograd as autograd
# 大小为3,步幅为2的正方形窗口池
m = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
# pool of non-square window
input = autograd.Variable(torch.randn(20, 16, 50, 32))
output = m(input)
print(output.shape)  # torch.Size([20, 16, 25, 16])

四,卷积神经网络结构

一个典型的卷积网络结构是由卷积层、汇聚层、全连接层交叉堆叠而成。如下图所示:

典型的卷积网络整体结构

一个简单的 CNN 网络连接图如下所示。

经典 CNN 网络的总结,可参考我之前写的文章-经典 backbone 网络总结。

一个简单的cnn网络结构图目前,卷积网络的整体结构趋向于使用更小的卷积核(比如 1 × 1 1 \times 1 1×1 3 × 3 3 \times 3 3×3) 以及更深的结构(比如层数大于 50)。另外,由于卷积层的操作性越来越灵活(同样可完成减少特征图分辨率),汇聚层的作用越来越小,因此目前的卷积神经网络逐渐趋向于全卷积网络。

另外,可通过这个网站可视化 cnn 的全部过程。

cnn_explainer

参考资料

  1. AI EDU-17.3 卷积的反向传播原理
  2. Visualizing the Feature Maps and Filters by Convolutional Neural Networks
  3. 《神经网络与深度学习》-第5章
  4. 《动手学深度学习》-第6章
  5. https://www.zhihu.com/question/22298352

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

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

相关文章

教育舆情监测方案有哪些,TOOM讲解教育舆情的应对与处理?

教育舆情方案是针对教育领域的舆情事件或问题而制定的应对方案。其主要目的是通过有效的信息收集、分析、处理和传播,帮助教育机构或相关组织及时掌握和应对公众舆论的发展趋势,维护良好的舆情形象和声誉,教育舆情监测方案有哪些,…

黑马Java后端项目实战--在线聊天交友

【课程简介】 越来越多的系统都有消息推送的功能,如聊天室、邮件推送、系统消息推送等; 要实现消息推送就需要服务端在数据有变化时主动推送消息给客户端,本次课程将带大家使用websocket实现消息推送。 【主讲内容】 1.方法:如…

ANR系列(二)——ANR监听方案之WatchDog

前言 ANR的监控在Android6.0之前可以通过监听文件data/anr/trace读取trace信息来分析,但从6.0之后就被禁止了。随着Android的发展,手机里的ANR越来越多,对ANR的监控方案也就五花八门。 WatchDog方案 WatchDog是个开源的框架,是…

大漠插件最新中文易语言模块7.2302

模块名称:大漠插件中文模块最新通用7.2302模块简介:大漠插件中文模块最新通用7.2302模块特色:原翻译:花老板完善命令备注:易生易世本人花费一个月时间才将命令完善了插件的备注说明.且用且珍惜去掉了大漠插件定制版类.因为没用.模块特色:什么是中文模块?大漠插件模块是由大漠类…

Java SPI 概念和应用实现

Java SPI 测试 Demo一.SPI 简介1.概念 SPI 与 API2.作用二.Jdk SPI 实现1.SPI 接口定义2.SPI 实现类定义3.SPI 配置4.测试三.SpringBoot SPI 实现1.引入 SpringBoot 依赖2.SpringBoot SPI 配置3.测试一.SPI 简介 1.概念 SPI 与 API SPI 全称:Service Provider Int…

Xshell连接阿里云服务器搭建网站

一、建设一个网站的基本要求 申请一个独立的域名申请一台云服务器ECS在服务器上安装网站环境,如:Apache发布网站内容至云服务器将第一步注册的域解析至云服务器的外网IP地址进行ICP备案 二、用户访问网站的过程 在浏览器上输入域名浏览器自动调用DNS&…

SPI(服务提供发现机制)简单使用

一、概述 SPI的英文全称是Service Provider Interface,是Java内置的一种服务提供发现机制。一般常用于一些框架或组件库的开发,我们最熟悉JDBC就应用到了SPI机制,并且在Spring、Dubbo中也大量应用了SPI机制。SPI机制是针对同一个接口采用不同…

质量小议18 -- 熵

未能深入理解其包含的物理意义,浅记于此,以求理解对抗有自然无序的过程。 熵,对系统无序程序的度量,表征系统混乱程度。系统总是由有序向无序,最后走向静寂。 关键词:1. 无序和混乱;2. 有序向无…

Java中static关键字和代码块的学习

本文介绍了Java中static关键字的使用,即静态成员变量和成员方法以及使用,静态与非静态成员变量和方法的对比总结 Java中的代码块介绍与最后结合代码块和构造方法后的初始化代码执行顺序的练习 static和代码块的学习三.认识static关键字1.static修饰成员变量2.static修饰成员方法…

GAMES101-计算机图形学入门 LEC4: TRANSFORMATION-3D

本节课程视频地址:https://www.bilibili.com/video/BV1X7411F744/?p4 补充上一节课的一个内容,旋转矩阵的逆矩阵是它的转置,也就是说有R−θRθ−1RθTR_{-\theta} R_\theta^{-1}R_\theta^TR−θ​Rθ−1​RθT​ 上节课讲了,…

【go】结合一个go开源项目分析谷歌浏览器cookie为什么不安全 附go项目导包失败怎么解决教程

本文创作背景 源于谷歌浏览器提示密码被泄露 并且某站很快收到了异地企图登录的提醒。 当即怀疑是不是谷歌浏览器保存的密码不安全,最后查阅诸多资料 并找到一个go语言编写的开源项目进行研究,虽然最终不能确定密码是如何泄露的 但研究结论还是让人不由感…

在华为MateBook Ego的arm windows 11上安装hyper-V虚拟机

入手一台华为matebook Ego的笔记本,由于想要测试一些arm的驱动功能,经常会把系统搞蓝屏,于是想安装一个虚拟机,于是试了vmware ,visual-box,由于本机是arm架构上面两个软件都无法进行正常安装,可能是由于有…

Excel+SQL实战项目 - 餐饮业日销售情况分析仪

目录1、要完成的任务2、认识数据3、SQL数据加工4、excel形成分析仪1、要完成的任务 目标:结合SQL和excel实现餐饮业日销售情况分析仪,如下表: 认识分析仪: 切片器:店面 分为四部分:KPI 、组合图、饼图、数…

如何自学芯片设计?

众所周知,芯片设计自学还是比较困难的,更不存在速成的。这里简单说一下学习的规划。 学会相应的知识 无论是科班毕业,还是理工科专业,想要入行IC,那就一定要具备相关的基础知识。尤其是在学校里,学习的很…

Centos7 内核升级

一、背景 在 CentOS 使用过程中,高版本的应用环境可能需要更高版本的内核才能支持,所以难免需要升级内核,所以下面将介绍yum和rpm两种升级内核方式。 关于内核种类: kernel-ml——kernel-ml 中的ml是英文【 mainline stable 】的缩写&…

2W字正则表达式基础知识总结,这一篇就够了!!(含前端常用案例,建议收藏)

正则表达式 (Regular Expression,简称 RE 或 regexp ) 是一种文本模式,包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为"元字符")正则表达式使用单个字符串来描述、匹配一系列匹…

wpscan常见的使用方法

目录 简单介绍 暴力破解 信息收集 指定用户爆破 命令集合 简单介绍 Wordpress是一个以PHP和MySQL为平台的免费自由开源的博客软件和内容管理系统。 WPScan是Kali Linux默认自带的一款漏洞扫描工具,它采用Ruby编写,能够扫描WordPress网站中的多种安…

微信微店怎么开店铺步骤【微信开店】

商家在微信平台主要是通过什么方式进行卖货呢,大家的答案都会是微信小店、小程序微店铺之类的,的确微信店铺是商家在微信平台上重要的卖货渠道,那么微信微店怎么开店铺,下面就给大家分享微信微店怎么开店铺步骤。 一、准备好资料…

Netty启动流程源码剖析

案例 本文利用natty-all-source 包下的的demo案例 echo来分析下源码,代码如下:server 端代码 /*** Echoes back any received data from a client.*/ public final class EchoServer {static final boolean SSL System.getProperty("ssl") …

day14_oop_抽象_接口

今日内容 上课同步视频:CuteN饕餮的个人空间_哔哩哔哩_bilibili 同步笔记沐沐霸的博客_CSDN博客-Java2301 零、 复习昨日 一、作业 二、抽象 三、接口 零、 复习昨日 多态的好处: 扩展性强.加入新的功能,不需要改动代码降低代码耦合度(解耦合或者松耦合) 一、抽象类 1.1 抽象类…