- 实验目的
- 了解图像分类的基本概念
- 了解ResNet设计思想
- 了解ResNet-50残差网络的实现
二、实验环境
Windows系统、百度飞奖AI Studio平台
三、实验内容
1、残差块(Residual block)
在ResNet神经网络中,到处都会有残差块,用于学习输入与期望输出之间的残差(即差异)。这种设计有助于解决深度神经网络训练过程中出现的梯度消失和梯度爆炸等问题。
残差单元的核心思想是引入了一个跨层的连接(shortcut connection),允许网络直接学习残差映射。这意味着,网络可以学习将输入信号与期望输出之间的差异进行拟合,而不是学习整个映射函数。这种设计使得网络更容易训练,并且有助于加速收敛。
残差单元通常由两个分支组成:主要的卷积路径和跨层连接(shortcut)。主要的卷积路径用于学习特征表示,而跨层连接直接将输入或特征映射绕过一到多个卷积层并加到输出上,从而形成了残差连接。
接下来便是残差块的代码实现:
在 __init__ 方法中,我们可以看到这个 BottleneckBlock 包含了三个卷积层:一个 1x1 的卷积层 conv0,一个 3x3 的卷积层 conv1,以及一个 1x1 的卷积层 conv2。这三个卷积层分别用于不同尺寸的卷积操作,并通过 ConvBNLayer 来实现卷积和批量归一化操作。
接着是对是否需要添加 shortcut 进行了判断。如果 shortcut 为 True,则直接将输入跟最后一个卷积层的输出相加;如果 shortcut 为 False,则需要添加一个额外的 1x1 卷积层 short,将输入调整成与最后一个卷积层输出一致的形状。
在 forward 方法中,首先通过 conv0 进行卷积操作,然后经过 conv1 和 conv2 的处理得到最终的特征表示。之后根据 shortcut 的取值,决定是否需要进行 shortcut 操作,将最终的输出与之前的输入相加,然后经过 relu 激活函数得到最终的输出结果。
在这段代码中,short 变量在这段代码中体现了残差单元中的瓶颈结构。在残差网络中,瓶颈结构通过使用 1x1 的卷积核来减少通道数,降低计算复杂度,并且引入了瓶颈特征表达。
如果 shortcut 为 False,即需要添加额外的 1x1 卷积层来调整输入的形状与最后一个卷积层的输出一致,那么就会使用 short 这个变量来表示通过 1x1 卷积层处理后的输入。
这个瓶颈结构的设计能够有效地减少参数数量和计算量,同时提高网络的表达能力。通过使用较小的卷积核进行降维和升维操作,可以在保持网络深度的同时减少计算资源的消耗,提升模型的性能和效率。
2、ResNet-50残差网络
ResNet-50 是由多个残差模块构成的深度卷积神经网络。整个网络分为几个阶段,每个阶段包含多个残差模块,用于提取图像的特征。
首先是网络的输入层,接着是一个最大池化层,用于对输入图像进行下采样。然后,通过四个阶段的残差模块进行特征提取。
每个阶段包含多个残差模块,其中第一个阶段的残差模块更简单,后面的阶段则采用更复杂的瓶颈结构。这些残差模块通过残差连接(即跳跃连接)的方式,将输入直接传递到输出上,从而使得网络可以学习残差映射。
具体来说,在 ResNet-50 中,每个残差模块由多个瓶颈块组成。瓶颈块由三个卷积层组成,分别是 1x1、3x3 和 1x1 的卷积层。中间的 3x3 卷积层是残差模块的核心部分,用于学习特征映射。
整个 ResNet-50 网络的最后部分是全局平均池化层和一个全连接层,用于将提取到的特征映射映射到分类类别上。
以下便是ResNet-50残差神经网络的结构图:
根据结构图我们可以看到,刚开始就是通过卷积加池化的方式将图像的分辨率降下来,然后经过一系列的残差单元,最后通过一个全局的池化和全连接层的实现,交给softmax进行分类
接下来便是ResNet-50残差网络的代码实现:
在这段代码中首先定义了一个ResNet类,继承自paddle.nn.Layer,表示这是一个基于PaddlePaddle框架的神经网络模型。
__init__方法中初始化了ResNet模型的各个组件,包括卷积层、池化层、残差块等。通过layers参数选择ResNet的层数,class_dim参数指定分类标签的类别数。
根据所选的层数,确定了每个阶段包含的残差块数量和输出通道数。这些参数会影响整个ResNet的结构。
创建了ResNet的第一个模块,包含一个卷积层和一个最大池化层,用于提取图像特征并进行下采样。
创建了ResNet的第二到第五个模块,每个模块包含若干个残差块(BottleneckBlock),并根据设定的规则设置不同的步长和通道数,用于构建深层特征表示。
在最后一个残差模块的输出特征图上使用全局平均池化,将特征图的每个通道上的特征求平均,得到一个特征向量。
创建一个全连接层,将全局平均池化得到的特征向量映射到类别数目大小的输出。
forward方法定义了数据在模型中的前向传播过程,按照顺序执行各个组件,并返回最终的分类结果。
- ResNet-50残差神经网络的简洁实现
百度飞奖平台提供的高级API可以让我们直接调用其中的ResNet-50残差神经网络,可以用以下语句直接调用:
这样子可以大大减少我们编写底层代码的时间
- 利用百度飞奖提供的高级API在Cifar10数据集上的训练
这段代码中从paddle.vision.datasets模块中导入了Cifar10数据集,用于训练和验证模型。
导入了优化器Momentum、正则化器L2Decay、损失函数CrossEntropyLoss和评估指标Accuracy等。
调用paddle.vision.set_image_backend('cv2')设置图像数据加载的后端为OpenCV。
使用resnet50(pretrained=False, num_classes=10)创建了一个ResNet50模型,并指定了预训练参数为False和分类类别数为10。
创建了训练集和验证集的数据集对象train_dataset和val_dataset,并通过Cifar10(mode='train', transform=Transpose())指定了数据集的模式为训练集,使用了转置变换Transpose()来对图像进行预处理。
定义了优化器optimizer,设置学习率、动量和权重衰减等参数。
使用model.prepare(optimizer, CrossEntropyLoss(), Accuracy(topk=(1, 5)))对模型进行准备,指定了优化器、损失函数和评估指标。
使用model.fit()方法启动训练过程,指定了训练数据集、验证数据集、训练轮数、批大小、保存路径和工作线程数等参数。
训练结果:
这个知识训练结果的一部分,因为训练的时间实在太长,所以我只截取了一部分,但是我们可以看到能够成功的进行训练,就说明飞奖提供ResNet-50残差神经网络能够正常提取特征进行训练
四、实验小结
ResNet残差网络结构通过引入跳跃连接(shortcut connection)来解决深层神经网络训练困难的问题。残差连接允许信息在网络中直接传递,避免了信息在深层网络中逐层传递时的信息丢失和梯度消失问题。ResNet的结构简单,易于理解和实现,适用于各种规模的网络。解决了深层网络训练困难的问题。传统的深层神经网络存在梯度消失或梯度爆炸等问题,导致训练过程变得困难。
并且ResNet网络结构它并没有增加参数,只不过是多了一些相对廉价和快速的加法计算。
通过学习ResNet残差神经网络让我体会到深度学习这门课程是多么的有意义,激发我的学习兴趣。