目录
日常·唠嗑
昨天写完了神经网络训练(二):基于残差连接的图片分类网络(进阶篇①),进行了概述及理论介绍,本篇继续写第三章,在传统ResNet18的基础上进行优化,对代码训练进行实际分析验证。
3 基于ResNet18的优化
原始的ResNet18模型在不使用预训练权重的情况下,很难在10分钟内达到我们的需求。在测试过程中,我们发现仅通过调整模型的超参数是不可能获得更好的结果的,因此我们针对我们的数据集进行优化改进。
3.1 初步构思
考虑到CIFAR10数据集的图片尺寸太小,ResNet18网络的7x7降采样卷积和池化操作容易丢失一部分信息,所以在实验中我们将7x7的降采样层和最大池化层去掉,替换为一个3x3的降采样卷积,同时减小该卷积层的步长和填充大小,这样可以尽可能保留原始图像的信息。对比原ResNet18模型,首层改成3x3的,步长和padding都要一并改成1,删掉最大池化层,最后一个全连接层输出改成10。此外,我们没有使用ResNet中的maxpool操作,而是直接在每个layer block中使用stride=2来进行下采样。
构建模型:
Precision | Loss |
---|---|
69.40% | 0.732 |
Precision | Loss |
---|---|
77.62% | 0.342 |
Precision | Loss |
---|---|
88.20% | 0.203 |
虽然去除了7x7降采样卷积和最大池化层,可能导致模型在提取图像特征时的感受野减小,无法捕捉到更高级的特征,导致拉低了模型的上限,但是由于数据相对简单且时间限制10分钟。因此,改动能够有效的提升模型的训练速度,训练和推理的速度会提升。此外,通过减小卷积核大小、步长和填充大小,以及去除最大池化层,模型的参数数量减少,可以降低过拟合的风险。
从Fig5和Fig6中可以得出经过架构的优化,训练的损失得到明显下降,训练的精度得到明显提高,精度相比于Base ResNet18网络提升了8.22%。一方面由于将卷积层大小调小,降低了模型的大小,使得模型更好训练;另一方面,将通道值调整成更合理的大小。从Fig6中的结果依旧不理想,再次进行架构调整。Fig7展示了二次架构调整的结果,删掉第二个layer中的一个block,模型预测精度提升明显,相比于Fig6提升了10.58%。
3.1.1 数据预处理
CIFAR-10[3]数据集由10个类的60000个32x32彩色图像组成,每个类有6000个图像。有50000个训练图像和10000个测试图像。数据集分为五个训练批次和一个测试批次,每个批次有10000个图像。测试批次包含来自每个类别的恰好1000个随机选择的图像。训练批次以随机顺序包含剩余图像,但一些训练批次可能包含来自一个类别的图像比另一个更多。总体来说,五个训练集之和包含来自每个类的正好5000张图像。以下是数据集中的类,以及来自每个类的10个随机图像。
数据预处理可以帮助提高模型的性能、泛化能力和稳健性,是机器学习和深度学习中不可或缺的一部分,我们通过上述代码进行预处理。首先,将输入图像调整大小为40x40。随机裁剪图像到32x32的大小,裁剪比例在0.64到1.0之间,宽高比为1。随机水平翻转图像。将图像转换为Tensor格式。同时对图像进行标准化,使用给定的均值和标准差来进行归一化。这些操作可以帮助模型更好地学习数据的特征,同时也有助于提高模型的鲁棒性和泛化能力。在训练过程中,transform_train会被应用在训练数据上,而transform_test会被应用在测试数据上,以保持数据预处理的一致性。
3.1.2 批量大小
批量大小是指每次迭代训练模型时一次输入给模型的样本数量。选择合适的批量大小对训练模型非常重要,它可以影响训练速度、收敛速度和模型的泛化能力等方面。
较大的批量大小可能会提高训练速度,因为在每次迭代中同时处理更多的样本,较小的批量大小有助于模型更好地泛化到未见过的数据,因为它能够更好地学习数据的细节。随着批量大小的增加,损失函数和结果函数的波动剧烈。似乎较大的批量大小使用较少的 epoch 来收敛,但在每个 epoch 中花费更多时间。较小的批量大小组使用更多的 epoch 来收敛,但在每个 epoch 中花费更少的时间。因此,使用不同的批处理大小确定训练速度是一个权衡问题。因为模型的训练限制10分钟时间,综合考量训练时间和数据集大小,后面我们设置批量大小为256。
3.1.3 参数初始化
参数初始化在深度学习中非常重要,它可以影响模型的收敛速度、局部最优解和梯度消失/爆炸等问题。合适的参数初始化可以帮助模型更快地收敛并且避免一些潜在的问题。由于网络限制训练时间10分钟,因此我们使用kaiming初始化来加快训练速度。Kaiming初始化的作用在于提供一种有效的权重初始化策略,能够帮助深度神经网络更好地训练和收敛,同时改善模型的性能和泛化能力。Kaiming初始化代码如下所示,对全连接层和卷积层的参数进行kaiming初始化。
3.1.4 optimizer
优化器是深度学习中用于调整模型参数以最小化损失函数的算法。在训练神经网络时,优化器的作用是根据损失函数计算的梯度来更新模型的参数,使得模型逐渐收敛到最优解。主要有两种优化器,随机梯度下降(Stochastic Gradient Descent, SGD):基本的优化算法,每次迭代随机选取一部分样本来计算梯度并更新参数;Adam结合了动量优化器和RMSprop的优点,在训练过程中动态调整学习率和动量。通过对比SGD优化器和Adam优化器选择更适合我们网络的优化器。
最终我们通过对比,选择了Fig13中的优化器设置方案,Adam优化器对比SGD优化器有着明显优势,同时设置了MultiStepLR学习率调度器,它可以在训练过程中根据事先设置好的milestones和gamma参数来调整学习率。
3.1.5 学习速率
学习率是深度学习中用于控制模型参数更新步长的重要超参数。在训练过程中,模型通过梯度下降算法来更新参数以最小化损失函数,而学习率就是用来调整每次参数更新的幅度的大小。学习率过大:可能导致模型在训练过程中发散,甚至出现损失函数增加的情况,参数更新幅度过大无法稳定收敛。学习率过小:导致模型收敛速度缓慢,需要更多的迭代才能达到较好的效果,同时容易陷入局部最优解。SGD优化器常用的学习率为0.1,动量设置为0.9,权重衰减的系数设置为5e-4。Adam优化器参数一般设置为:学习率: 0.001、β1: 0.9、β2: 0.999、ε(eps): 1e-8。
3.2hyper-parameter测试
3.2.1批量大小
Precision | Loss | Batch size | lr |
---|---|---|---|
77.02% | 0.401 | 256 | 0.0005(Adam) |
Precision | Loss | Batch size | lr |
---|---|---|---|
76.52% | 0.412 | 512 | 0.0005(Adam) |
Precision | Loss | Batch size | lr |
---|---|---|---|
11.40% | ----- | 128 | 0.0005(Adam) |
Precision | Loss | Batch size | lr |
---|---|---|---|
75.61% | 0.340 | 1024 | 0.0005(Adam) |
从上图中可以看出批量大小是CNN中使用的一个非常重要的参数,不同的批量大小可能会导致完全不同的结果。Fig16中批量过小导致网络的梯度爆炸/消失。从上述图中可以看出,相比于128、1024、256,批次大小256是一个更好的选择,但是由于时间限制问题,为了快速提升精度,网络依然难以收敛,损失值依然较大,测试的精度没有趋于平稳。
3.2.2 参数训练
从Fig19中我们可以看出,学习率设置的过大,导致模型参数更新过大,超过了最优解附近的范围,使得损失函数值不断增大,模型无法收敛,可能导致训练过程中的不稳定性,使得模型在不同批次或迭代中表现出不一致的结果。
从Fig20中的设置了我们最终的学习率0.001(Adam)和batch_size(256),最终取得了88.2%的测试精度。
今天完成了第三章,在传统ResNet18的基础上进行优化,对代码训练进行实际分析验证。
第四章将在后面继续更新,有兴趣的朋友敬请关注