图像分类性能提升方案


1 数据方面的改进

1.1 使用EDA+图像预处理

每一个机器学习/深度学习解决方案都从原始数据开始。在数据处理管道中有两个基本步骤。

第一步是探索性数据分析 (EDA)。它帮助我们分析整个数据集并总结它的主要特征,比如类分布、大小分布等等。通常使用可视化方法来显示这种分析的结果。

第二步是图像预处理,目的是对原始图像提高图像数据(也称为图像特征)的质量,通过抑制不必要的扭曲,缩放,增强重要的特征,使数据更适合模型并提高性能。

你可以钻研这些Kaggle笔记本,看看一些图像预处理技术:

1.2 使用数据增强

数据增强可以通过从现有的训练样本中生成更多的训练数据来扩展我们的数据集。通过大量的随机转换生成新的样本,这些转换不仅可以生成可信的图像,而且还反映了真实的场景。

通常,当一个模型在训练数据上表现很好,但在验证数据上表现很差时,我们称之为过拟合。为了解决这个问题,我们通常会尝试获取新数据,如果没有可用的新数据,则可以使用数据增强。

注:一般的经验法则是始终使用数据增强技术,因为它有助于使我们的模型见识更多的变化并更好地泛化。即使我们有一个很大的数据集,也要使用数据增强,但这是以较慢的训练速度为代价的,因为增强是在线完成的(即在训练期间)。

此外,对于每个任务或数据集,我们必须使用反映可能的现实场景的增强技术(例如,如果我们有一个猫/狗探测器,我们可以使用水平翻转、剪裁、亮度和对比度),因为这些增强匹配不同的照片拍摄方式。

Pytroch图像增强方法。使用pytorch中的图像预处理包torchvision.transforms,一般用Compose把多个步骤整合到一起,常见步骤有:

1.裁剪—Crop

中心裁剪:transforms.CenterCrop

随机裁剪:transforms.RandomCrop

随机长宽比裁剪:transforms.RandomResizedCrop

上下左右中心裁剪:transforms.FiveCrop

上下左右中心裁剪后翻转,transforms.TenCrop

2.翻转和旋转—Flip and Rotation

依概率p水平翻转:transforms.RandomHorizontalFlip(p=0.5)

依概率p垂直翻转:transforms.RandomVerticalFlip(p=0.5)

随机旋转:transforms.RandomRotation

3.图像变换

resize:transforms.Resize

标准化:transforms.Normalize

转为tensor,并归一化至[0-1]:transforms.ToTensor

填充:transforms.Pad

修改亮度、对比度和饱和度:transforms.ColorJitter

转灰度图:transforms.Grayscale

线性变换:transforms.LinearTransformation()

仿射变换:transforms.RandomAffine

依概率p转为灰度图:transforms.RandomGrayscale

将数据转换为PILImage:transforms.ToPILImage

transforms.Lambda:Apply a user-defined lambda as a transform.

4.对transforms操作,使数据增强更灵活

transforms.RandomChoice(transforms),从给定的一系列transforms中选一个进行操作

transforms.RandomApply(transforms, p=0.5),给一个transform加上概率,依概率进行操作

transforms.RandomOrder,将transforms中的操作随机打乱

这里是一些Kaggle笔记本,你可以查看流行的数据增强技术:

2 模型的改进

2.1 先开发一个基线

在这里,我们使用一个非常简单的架构创建一个基本的模型,没有任何正则化或dropout层,看看我们是否能超过50%的准确率基线。尽管我们不可能总能达到这个目标,但如果我们在尝试了多种合理的架构后不能超过基线,那么输入数据可能不包含模型进行预测所需的信息。

用Jeremy Howard的名言:
“你应该能够在15分钟内使用50%或更少的数据集快速测试你是否正在朝着一个有希望的方向前进,如果没有,你必须重新考虑一切。”

2.2 试着开发一个足够大过拟合的模型

一旦我们的基线模型有足够的能力超过基线分数,我们就可以增加基线模型的能力,直到它在数据集上过拟合为止,然后我们就开始应用正则化。

我们可以通过以下方式增加模块容量:

  1. 添加更多层
  2. 使用更好的结构
  3. 更完善的训练流程

2.3 模型结构调整

根据文献,以下架构的改进提高了模型的容量,但几乎没有改变计算复杂度。

  • Residual Networks

  • Wide Residual Networks

  • Inception

  • EfficientNet

  • Swish activation

  • Residual Attention Network

大多数时候,模型容量和精度是正相关的 —— 随着容量的增加,精度也会增加,反之亦然。

2.4 改进训练过程

下面是一些你可以用来调整你的模型的训练过程,通过实例项目来看看它们是如何工作的:

  • Mixed-Precision Training

  • Large Batch-Size Training

  • Cross-Validation Set

  • Weight Initialization

  • Self-Supervised Training(Knowledge Distillation)

  • Learning Rate Scheduler

  • Learning Rate Warmup

  • Early Stopping

  • Differential Learning Rates

  • Ensemble

  • Transfer Learning

  • Fine-Tuning

2.5 超参数的调试

与参数不同,hyperparameters是由你在配置模型时指定的(即学习率、epoch的数量、hidden units的数量、batch size大小等)。

你可以通过使用hyperparameter调优库,比如Scikit learn Grid Search,Keras Tuner来自动化这个过程,而不是去手动配置。这些库会在你指定的范围内尝试所有的hyperparameter组合,返回表现最好的模型。

需要调优的超参数越多,过程就越慢,因此最好选择模型超参数的最小子集进行调优。

并不是所有的模型超参数都同样重要。一些超参数会对机器学习算法的行为产生巨大的影响,进而影响其性能。你应该小心地选择那些对模型性能影响最大的参数,并对它们进行调优以获得最佳性能。

2.6 添加正则化

这种方法迫使模型学习有意义和具有泛化能力的数据表示,通过对记忆/过拟合和欠拟合进行惩罚来实现,使模型对于它没见过的数据更鲁棒。

解决上述问题的一个简单方法是获得更多的训练数据,因为一个模型训练的数据越多,自然就会泛化得越好。

这里有一些技巧你可以试着减轻过拟合和欠拟合,项目如下:

2.7 改进损失函数

损失函数也被称为成本函数或目标函数,用于查找目标输出的模型之间的差异,并帮助模型最小化它们之间的距离。

这里是一些最流行的损失函数与项目实例,你会发现一些技巧,以提高你的模型的能力:

  • Label smoothing

  • Focal loss

  • SparseMax loss and Weighted cross-entropy

  • BCE loss, BCE with logits loss and Categorical cross-entropy loss

  • Additive Angular Margin Loss for Deep Face Recognition

3 对模型进行评估+错误分析

在这里,我们做消融研究,并分析我们的实验结果。我们确定了我们的模型的弱点和长处,并确定了未来需要改进的地方。

在这个阶段,你可以使用以下技术,并在链接的示例中查看它们是如何实现的:

有许多实验跟踪和管理工具,采取最小设置为你自动保存所有数据,这使消融研究更容易。

有许多方法来调整你的模型,并且新的想法总是会出现。深度学习是一个快速发展的领域,没有什么灵丹妙药。我们必须做很多实验,足够的试验和错误会带来突破。

4 寻找创新策略

4.1 迁移学习-微调

迁移学习将从源数据集学到的知识迁移到目标数据集。常见的迁移学习方法有:

1.载入权重后训练所有参数。

2.载入权重后只训练最后几层参数。

3.载入权重后在原网络基础上再添加一层全连接层,仅训练最后一个全连接层。

注意:使用别人预训练模型时,要和它的预处理方式保持一致。

微调(迁移学习的常用技术)的步骤:

1.在源数据集(如ImageNet数据集)上预训练一个神经网络模型,即源模型。

2.创建一个新的神经网络模型,即目标模型。它复制了源模型上除了输出层外的所有模型设计及其参数。我们假设这些模型参数包含了源数据集上学习到的知识,且这些知识同样适用于目标数据集。我们还假设源模型的输出层与源数据集的标签紧密相关,因此在目标模型中不予采用。

3.为目标模型添加一个输出大小为目标数据集类别个数的输出层,并随机初始化该层的模型参数。

4.在目标数据集上训练目标模型。我们将从头训练输出层,而其余层的参数都是基于源模型的参数微调得到的。

4.2 知识蒸馏

知识蒸馏是将一个已经训练好的网络迁移到另外一个新网络,常采用teacher-student学习策略,已经被广泛应用在模型压缩迁移学习中。

例如,MEAL V2是通过知识蒸馏提升ResNet50在ImageNet上的分类准确度,MEAL V2不需要修改网络结构,也不需要其他特殊的训练策略和数据增强就可以使原始ResNet50的Top-1准确度提升至80%+。

MEAL V2主要的思路是将多个模型的集成效果通过知识蒸馏迁移到一个单一网络中,整个设计非常简单,只包括三个重要的部分:teacher模型集成,KL散度loss以及一个判别器。

MEAL V2采用对抗学习来防止student在训练数据上过拟合,即不让student过分学习teacher的输出,这其实是一种正则化手段。

有一点需要注意,在蒸馏时,ResNet50不是随机初始化的,而是从预训练好的ImageNet模型进行初始化,就是说student也需要一个好的初始化,如果是随机初始化可能需要更长的训练时长。

在最新的无监督方法研究如谷歌的SimCLRv2和Noisy Student均有知识蒸馏的身影。

参考:

1.MEAL V2: Boosting Vanilla ResNet-50 to 80%+ Top-1 Accuracy on ImageNet without Tricks∗

2.MEAL: Multi-Model Ensemble via Adversarial Learning

3.Distilling the Knowledge in a Neural Network

4.szq0214/MEAL-V2

一些项目实例

这里从Kaggle比赛中挑选出了好的Kaggle kernel。这些比赛是:


文章作者: BoBoRing
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 BoBoRing !
评论
  目录