阿里天池-零基础入门CV赛事构建深度网络的流程

重干货,尽快发货

卷积神经网络CNN是深度学习的基础知识。本文对CNN和常见CNN网络的基本原理进行了详细解读,并介绍了在Pytorch中构建深度网络的过程。最后以阿里天池零基础入门CV大赛为学习实践,实现了Pytorch搭建的CNN模型。

数据和背景

(阿里巴巴天池-零基础入门简历大赛)

CNN 原理

CNN,又称卷积神经网络,是深度学习的一个重要分支。 CNN 在许多领域都表现出色,其准确性和速度远高于传统的计算学习算法。特别是在计算机视觉领域,CNN是解决图像分类、图像检索、目标检测和语义分割的主流模型。

1.卷积

如图1所示,无论图中的X和O如何旋转或缩放,人眼仍然可以轻松识别X和O。

ͼ1

但是计算机不同。它看到的其实是一个像素数组,如图2。如何从一个像素数组中提取特征其实就是卷积神经网络要做的事情。

ͼ2

再看图3,我们发现即使X旋转了,两幅图中绿色、橙色和紫色方框标记的区域还是一样的。某种程度上,这其实是X的特点。

ͼ3

因此,可以提取这三个特征的区间,形成三个卷积核,如图4所示。

ͼ4

既然有卷积核,那么卷积核是如何进行卷积操作的呢?事实上,这很简单。大家可以看图5。卷积核其实就是这个矩阵在图片的矩阵上的一点平移,就像扫地一样。每次扫描一个地方时都可以执行卷积操作。计算方法非常简单。如图5所示,左上角的卷积核被扫到绿框的位置,卷积核矩阵的个数与扫描值一致。位置矩阵的个数一一相乘再相加,最后取一个平均值,就是卷积核提取的特征。

ͼ5

卷积核提取的所有特征形成一个长宽递减的矩阵,也称为特征图,如图6所示。不同的特征图可以通过使用不同的卷积核来提取。所以可以想象,如果连续进行卷积操作,图像的矩阵会在长宽上逐渐减小,厚度逐渐增加。

ͼ6

可以看出,卷积运算可以通过卷积核分别提取图像的特征,但是如何提前知道卷积核呢?像上面的例子,很容易找到3个卷积核,但是如果是人脸识别等上千个特征的图片,没有办法提前知道什么是合适的卷积核。其实不需要知道,因为选择什么样的卷积核是可以通过训练不断优化的。一开始只需要随机设置一些卷积核。通过训练,模型实际上可以自己学习到合适的卷积核,这也是卷积神经网络模型的强大之处。

2.池化

池化,也称为下采样,本质上是对数据的缩减。因为我们知道,比如人脸识别空间自定义模块没了,通过卷积运算得到上千个特征图,每个特征图也有很多像素点,后续操作需要很长时间。

池化实际上是进一步细化每个特征图的过程。如图 7 所示,原来的 4X4 特征图在经过池化操作后变成了一个更小的 2*2 矩阵。池化方法包括max pooling,即取最大值,average pooling,即取平均值。

ͼ7

3.归一化

这里的归一化就是将矩阵中的负数的值转化为0,也就是使用一个叫做ReLu的激活函数来进行负数到0的运算。ReLu函数本质上就是max(0,x) 这一步其实是为了方便。

4.卷积神经网络理解

因此,卷积、ReLu、池化不断重复,基本构成了卷积神经网络的框架,如图8所示。然后将最终的特征图排成一列(图8),连接它到全连接层,从而形成我们的卷积神经网络。值得注意的是,排列在一列中的值都有权重,这些权重是通过训练和反向传播得到的。通过权重的计算,我们可以知道什么不同分类的概率是。

ͼ8

卷积神经网络

卷积神经网络基础知识:LeNet5

手写字体识别模型LeNet5诞生于1994年,是最早的卷积神经网络之一。 LeNet5通过巧妙的设计,利用卷积、参数共享、池化等操作提取特征,避免了大量的计算成本,最终使用全连接的神经网络进行分类识别。该网络也是近期大量神经网络架构的起点。

下图展示了LeNet的网络结构。网络一共7层(不包括输入层),2个卷积层,2个池化层,3个全连接层。

LeNet分为两部分:卷积层块和全连接层块。下面我们分别介绍这两个模块。卷积层块中的基本单元是一个卷积层,后跟一个最大池化层:卷积层用于识别图像中的空间模式,例如线条和对象部分,随后的最大池化层用于减少卷积层。对位置的敏感性。一个卷积层块由重复堆叠的两个这样的基本单元组成。在卷积层块中,每个卷积层使用 5*5 的窗口,并在输出上使用 sigmoid 激活函数。第一个卷积层的输出通道数为6,第二个卷积层的输出通道数增加到16个。这是因为第二个卷积层的输入在高度和宽度上都小于第一个卷积层,所以增加输出通道使得两个卷积层的参数大小相似。卷积层块的两个最大池化层的窗口形状为2*2,步幅为2。由于池化窗口的形状与步幅相同,因此池化窗口在输入上的每次滑动所覆盖的区域不重叠。

卷积层块的输出形状为(batch size, channels, height, width)。当卷积层块的输出传入全连接层块时,全连接层块会将小批量中的每个样本展平。即全连接层的输入shape会变成二维的,其中第一维是mini-batch中的样本,第二维是每个样本的扁平化向量表示,向量长度是channel, height和宽度的乘积。全连接层块包含 3 个全连接层。它们的输出数量分别为120、84和10,其中10是输出类别的数量。

卷积块中输入的高度和宽度是逐层递减的。卷积层使用高宽为5的卷积核,将高宽减少了4,而池化层将高宽减半,但通道数从1增加到16。全连接层减少逐层输出的数量,直到图像的类别数为10。

通过多次卷积和池化,最后一层 CNN 将输入图像像素映射到具体输出。比如在分类任务中,会转换成不同类别的概率输出,然后计算真实标签与CNN模型预测结果的差值,通过更新每一层的参数反向传播,更新完成后会重复前向传播,以此类推。直到训练完成。

数字识别效果如图:

高级卷积神经网络

随着网络结构的发展,研究人员初步发现,网络模型结构越深,网络参数越多,模型的准确性就越好。比较典型的是AlexNet、VGG、InceptionV3和ResNet的开发上下文。

1. AlexNet(2012)

2012 年,AlexNet 诞生了。该模型的名字来自该论文的第一作者 Alex Krizhevsky。 AlexNet 使用了 8 层卷积神经网络,并以较大优势赢得了 ImageNet 2012 Image Recognition Challenge。它是第一个证明学习特征可以胜过手工设计的特征,一举打破计算机视觉研究的困境。

AlexNet 和 LeNet 的设计理念非常相似,但也存在显着差异。

1. 与相对较小的 LeNet 相比,AlexNet 包含 8 层变换,其中 5 个卷积层和 2 个全连接隐藏层,以及 1 个全连接输出层。下面我们详细描述这些层的设计: AlexNet 第一层的卷积窗口形状为 11*11。由于 ImageNet 中绝大多数图像的高度和宽度是 MNIST 图像的 10 倍以上,因此 ImageNet 图像中的对象占用的像素更多,因此需要更大的卷积窗口来捕获对象。第二层的卷积窗口形状缩小为5*5,然后全部使用3*3。此外,一、 第二和第五个卷积层后面跟着一个最大池化层,窗口形状为 3*3、,步长为 2。此外,AlexNet 使用的卷积通道数也是LeNet中卷积通道数的几十倍。最后一个卷积层之后是两个具有 4096 个输出的全连接层。这两个巨大的全连接层带来了近 1 GB 的模型参数。由于早期显存的限制,最早的 AlexNet 采用双流设计,一个 GPU 只需要处理一半的模型。幸运的是,显卡在过去几年里已经取得了长足的进步,所以通常我们不再需要这种特殊的设计了。

2. AlexNet 将 sigmoid 激活函数更改为更简单的 ReLU 激活函数。一方面,ReLU激活函数的计算更简单,例如它没有sigmoid激活函数中的幂运算。另一方面,ReLU 激活函数使得模型在不同的参数初始化方法下更容易训练。这是因为当 sigmoid 激活函数的输出非常接近 0 或 1 时,这些区域的梯度几乎为 0,使得反向传播无法继续更新某些模型参数;而ReLU激活函数在正区间的梯度始终为1。因此,如果模型参数没有正确初始化,sigmoid函数可能在正区间内得到几乎为零的梯度,导致模型无法有效训练。

3. AlexNet 使用 dropout 方法来控制全连接层的模型复杂度。而且LeNet不使用drop方法。

4. AlexNet 引入了广泛的图像增强功能,例如翻转、裁剪和颜色变化,以进一步扩大数据集以缓解过度拟合。我们将在后面的图像增强中详细描述这种方法。

总结:

AlexNet 在结构上与 LeNet 相似,但使用更多的卷积层和更大的参数空间来拟合大规模数据集 ImageNet。它是浅层神经网络和深层神经网络的分界线。

虽然看起来 AlexNet 的实现只比 LeNet 的实现多出几行代码,但这种概念上的改变和真正好的实验结果的产生已经花费了学术界多年的成本。

2. VGG-16(2014)

AlexNet 为 LeNet 添加了 3 个卷积层。但是 AlexNet 的作者对他们的卷积窗口、输出通道的数量和构建顺序进行了很多调整。尽管 AlexNet 表示深度卷积神经网络可以取得出色的效果,但它并没有提供简单的规则来指导后来的研究人员如何设计新的网络。 VGG 的名字来源于论文作者工作的实验室 Visual Geometry Group。 VGG 提出了可以通过重用简单的构建块来构建深度模型的想法。 VGG的结构图如下:

VGG块的组成规则是:连续使用几个与1、window shape 3*3相同填充的卷积层,后跟一个stride 2、window shape 2*2 max pooling layers。卷积层保持输入高度和宽度不变,而池化层将它们减半。我们使用 vgg_block 函数来实现这个基本的 VGG 块,它指定了卷积层的数量以及输入和输出通道的数量。

对于给定的感受野(输入图像相对于输出的局部大小),使用堆叠的小卷积核比使用大卷积核更可取,因为可以增加网络深度以确保学习更复杂的模式,并且成本相对较小(参数较少)。比如在VGG中,使用3个3×3的卷积核代替了7×7的卷积核,使用了2个3×3的卷积核代替了5*5的卷积核。这样做的主要目的是保证相同的感知场。在 的条件下,网络的深度得到了提高空间自定义模块没了,神经网络的效果在一定程度上得到了提升。

与 AlexNet 和 LeNet 一样,VGG 网络由一个卷积层模块和一个全连接层模块组成。卷积层模块连接了几个 vgg_blocks,其超参数由变量 conv_arch 定义。此变量指定每个 VGG 块中的卷积层数和输入和输出通道数。全连接模块和AlexNet中的一样。

现在我们构建一个 VGG 网络。它有 5 个卷积块,前 2 个块使用单卷积层,后 3 个块使用双卷积层。第一个block的输入和输出通道分别为1(因为下面要使用的Fashion-MNIST数据的通道数是1)和64,然后输出通道数每次翻一倍,直到变成了512。因为这个网络使用了8个卷积层和3个全连接层,所以通常被称为VGG-11。

可以看到,每次我们将输入的高宽减半,直到最终的高宽变为7,然后传递到全连接层。同时,输出通道数每次翻倍,直到变为512。由于每个卷积层的窗口大小相同,因此每层的模型参数大小和计算复杂度与输入高度的乘积成正比,输入宽度,输入通道数和输出通道数。 VGG将高宽减半,通道加倍的设计,使得大部分卷积层具有相同的模型参数大小和计算复杂度。

VGG:通过重复简单的构建块来构建深度模型。块:几个相同的卷积层,1、 窗口形状为 3×3,然后是一个最大池化层,步长为 2、,窗口形状为 2×2。卷积层保持输入高度和宽度不变,而池化层将它们减半。 VGG和AlexNet的网络图对比如下:

总结:VGG-11 通过 5 个可重复使用的卷积块构建网络。可以根据每个块的卷积层数和输出通道数定义不同的VGG模型。

3. Networks in the network (NiN) LeNet, AlexNet, and VGG:首先用卷积层组成的模块来充分提取空间特征,然后用全连接层组成的模块来输出分类结果。 NiN:连接多个由卷积层和“全连接”层组成的小型网络,构建一个深度网络。我们创建了输出通道数等于标签类别数的 NiN 块,然后对每个通道中的所有元素进行全局平均池化层平均,并直接用于分类。

1×1卷积核的作用

缩放通道数:可以通过控制卷积核的数量来缩放通道数;

添加非线性。 1×1卷积核的卷积过程相当于全连接层的计算过程,增加了非线性激活函数,增加了网络的非线性;

计算参数少。

NiN块我们知道卷积层的输入和输出通常是四维数组(样本、通道、高度、宽度),而全连接层的输入和输出通常是二维数组(样本, 特征)。如果要在全连接层之后连接卷积层,则需要将全连接层的输出转化为四个维度。回想一下多输入通道和多输出通道中介绍的 1×1 卷积层。可以看成是一个全连接层,其中空间维度(高和宽)中的每个元素相当于一个样本,一个通道相当于一个特征。因此,NiN 使用 1*1 的卷积层而不是全连接层,使得空​​间信息可以自然地传递到后续层。

NiN 块是 NiN 中的基本块。它由一个卷积层和两个作为全连接层的 1*1 卷积层串联组成。第一个卷积层的超参数可以自己设置,第二个和第三个卷积层的超参数一般是固定的。

NiN 是在 AlexNet 引入后不久提出的。它们的卷积层设置是相似的。 NiN使用3*3卷积层,卷积窗口形状分别为11*11、5*5和5*5,对应的输出通道数也与AlexNet中的一致。每个 NiN 块后面都有一个最大池化层,其步幅为 2、,窗口形状为 3*3。

NiN除了使用NiN块外,还有一个与AlexNet明显不同的设计:NiN去掉了AlexNet的最后3个全连接层,取而代之的是NiN使用输出通道数等于输出通道数的NiN块标签类别,然后使用全局平均池化层对每个通道中的所有元素进行平均,直接用于分类。这里的全局平均池化层是窗口形状等于输入空间维度形状的平均池化层。 NiN 的这种设计的好处是它可以显着减小模型参数大小,从而减轻过拟合。但是,这种设计有时会增加获得有效模型的训练时间。

总结:

NiN 重复使用由卷积层和 1*1 卷积层组成的 NiN 块,而不是完全连接的层来构建深度网络。

NiN去掉了容易过拟合的全连接输出层,代之以一个NiN块和一个输出通道数等于标签类别数的全局平均池化层。

NiN的上述设计思想影响了后续一系列卷积神经网络的设计。

4. 具有并行链接的网络 (GoogLeNet)

在 2014 ImageNet 图像识别挑战赛中,一种名为 GoogLeNet 的网络架构大放异彩。虽然在名字上是对 LeNet 的致敬,但在网络结构上却很难看到 LeNet 的影子。 GoogLeNet在NiN中吸收了network concatenation network的思想,并在此基础上做了很大的改进。在随后的几年中,研究人员对 GoogLeNet 进行了多项改进,本节介绍了该模型系列的第一个版本。

由 Inception 基本块组成。

Inception 块相当于一个有 4 行的网络。它通过卷积层和大多数不同窗口形状的池化层提取信息,并使1×1卷积层减少通道数以降低模型复杂度。

可以定义的超参数是每层的输出通道数,我们用它来控制模型的复杂性。

Inception 块 GoogLeNet 中的基本卷积块称为 Inception 块,以同名电影《盗梦空间》命名。与上一节介绍的 NiN 块相比,这个基块的结构更加复杂。

Inception 块中有 4 条平行线。前 3 行使用窗口大小为 1*1、3*3 和 5*5 的卷积层来提取不同空间大小下的信息,中间 2 行将首先对输入进行 1*1 滚动。产品减少输入通道的数量以降低模型的复杂性。第四行使用 3*3 最大池化层,后跟 1*1 卷积层来改变通道数。所有 4 行都使用适当的填充来使输入和输出具有相同的高度和宽度。最后,我们将通道维度中每一行的输出连接起来,并将其馈送到下一层。 Inception 块中的一个可定制的超参数是每层的输出通道数,我们用它来控制模型的复杂性。 GoogLeNet 和 VGG 一样,在主卷积部分使用 5 个块,并使用 3*3 的最大池化层,每个块之间的步幅为 2,以减少输出的高度和宽度。

第一个模块使用 64 通道的 7*7 卷积层。

第二个模块使用 2 个卷积层:首先是 1*1 卷积层,具有 64 个通道,然后是 3*3 卷积层,具有 3 倍大的通道。它对应于 Inception 块中的第二行。

第三个模块连接了 2 个完整的 Inception 块。第一个Inception块的输出通道数为64+128+32+32=256,4行输出通道数之比为64:128:32:32=2:4:1:1。第三行二、首先将输入通道数分别减少到96/192=1/2和16/192=1/12,然后连接到第二个卷积层。第二个Inception块的输出通道数增加到128+192+96+64=480,每行输出通道数的比例为128:192:96:64 = 4:6:3:2 第三行二、首先将输入通道数分别减少到128/256=1/2和32/256=1/8。

第四个模块更复杂。串联5个Inception块,输出通道数为192+208+48+64=512、160+224+64+64=512、128+256+64+64 = 512、112+288+64+64=528 和 256+320+128+128=832。这些行的通道数分布与第三个模块类似,首先是具有 3*3 卷积层的第二行输出通道数最多,其次是只有 1*1 卷积层的第一行,然后是第二个带有 3*3 卷积层的行 5×5 卷积层的第三行和带有 1×1 最大池化层的第四行。其中,二、的第三行会先按比例减少通道数。这些比率在 Inception 块中略有不同。

第五个模块有两个Inception块,输出通道数分别为256+320+128+128=832和384+384+128+128=1024。每行通道数的分配思路与三、第四个模块中的相同,但具体取值不同。需要注意的是,第五个模块后面是输出层,它使用与NiN相同的全局平均池化层,将每个通道的高度和宽度更改为1。最后,我们将输出变成一个二维数组跟随由具有标签类别输出数量的全连接层。 GoogLeNet 模型计算复杂,不像 VGG 那样容易修改通道数。

总结:

Inception 块相当于一个有 4 行的子网。它通过不同窗口形状的卷积层和max-pooling层并行提取信息,并使用1*1卷积层减少通道数以降低模型复杂度。

GoogLeNet 连接了多个精心设计的 Inception 块和其他层。 Inception块的通道数分配比例是通过在ImageNet数据集上大量实验得到的。

GoogLeNet 及其继任者曾经是 ImageNet 上最高效的模型之一:在相似的测试精度下,它们的计算复杂度往往较低。

5、残差网络(ResNet-50)

深度学习的问题:在深度CNN网络达到一定深度后盲目增加层数不会带来分类性能的进一步提升,反而会导致网络收敛速度变慢,准确率变差。 – – -Residual Block(残差块)恒等映射:

左:f(x)=x;

右:f(x)-x=0(容易捕捉恒等映射中的细微波动)。

ResNet 沿用了 VGG 的全 3*3 卷积层的设计。在残差块中,有前 2 个 3*3 的卷积层,输出通道数相同。每个卷积层后面跟着一个批归一化层和一个 ReLU 激活函数。然后我们跳过这两个卷积操作,直接在最终的 ReLU 激活函数之前添加输入。这样的设计要求两个卷积层的输出与输入具有相同的形状,以便它们可以相加。如果要改变通道数,则需要引入额外的 1*1 卷积层,将输入转换为所需的形状,然后添加。在残差块中,输出可以通过跨层的数据线更快地向前传播。

ResNet的前两层与之前介绍的GoogLeNet相同:输出通道数为64、步长为2的7*7卷积层后面是步长为3*3的卷积层2 最大池化层。不同的是在 ResNet 的每个卷积层之后添加的批量归一化层。 ResNet-50网络结构如下:

GoogLeNet 后面是由 Inception 块组成的 4 个模块。 ResNet 使用了 4 个由残差块组成的模块,每个模块使用几个输出通道数相同的残差块。第一个模块的通道数与输入通道数相同。由于之前使用过stride为2的max pooling layer,所以不需要降低高度和宽度。每个后续块将第一个残差块中前一个块的通道数加倍,并将高度和宽度减半。

总结:

残差块可以通过跨层数据通道训练有效的深度神经网络。

ResNet 深刻影响了后来的深度神经网络的设计。

Pytorch 构建模型

1.pytorch公网

1.1 线性介绍【全连接层】

1.2 卷积简介【二维卷积层】

1.3转置卷积简介【2D反卷积层】

1.4 max pooling layer [2D pooling layer]

1.5 Batch Normalization Layer [2D Normalization Layer]

2.pytorch中创建模型的四种方法

假设创建卷积层-》Relu层-》池化层-》全连接层-》Relu层-》全连接层

2.1.自定义类型[在init中定义,在forward中转发进程]

2.2 Sequence-integrated [使用nn.Squential(顺序执行层函数)]

只能通过数字索引访问每个级别

2.3 序列添加类型【使用Squential类add_module逐层添加】

赋予每一层的名称属性

2.4 Sequence ensemble 典型[OrderDict ensemble model dictionary [‘name’: layer function]]

名称Ϊ键

3. pytorch 访问、初始化、模型参数共享

3.1 访问参数

访问层

如果使用序列集成、序列加法或字典集成,则只能使用 id 索引来访问层。例如:网[1];

如果你想通过网络名称访问,例如:net.layer_name。

访问参数【权重参数名称:层名_weight/bias】

layer.params—-访问图层参数字典;

layer.weight , layer.bias—–获取layer的weight和bias;

layer.weight.data()/grad() ——获取层权重的具体值/梯度【也使用bias】;

net.collect_params() —- 返回网络的所有参数,返回一个从参数名到实例的字典。

3.2初始化【如果不是第一次初始化,force_reinit=True】

General initialization [Network initialization]

init initializes with various distributions

init performs constant initialization of network parameters

Initialization of specific parameters

Custom initialization

Inherit the Initialize class of init and implement the function _init_weight(self,name,data)

3.3 parameter sharing

Parameter sharing, gradient sharing, but the gradient calculation is the sum of all shared layers

The gradient is shared, and the gradient is only updated once

pytorch builds actual combat in SVHN network

Build a network model: inherit the __init__ function of the nn.Module function and redefine the forward propagation function forward

Construction Optimizer

Constructing the loss function

Training Determine several epochs [if data augmentation is used, randomly augment epoch times to achieve diversity]

For each batch the loss function is backpropagated, and the optimizer updates the parameters

optimizer.zero_grad() clears the gradient

loss.backward()

optimizer.step()

4.1 Ordinary self-built network

4.2 Pre-trained model using resnet

Download 1: OpenCV-Contrib extension module Chinese version tutorial

Download 2: Python Visual Combat Project 52 Lectures

Download 3: OpenCV practical project 20 lectures

Communication group

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享
评论 抢沙发

请登录后发表评论