找回密码
 立即注册
搜索

看完这个教程,你可以在任何图像数据集上构建、训练图像辨认器

点击上方关注,All in AI 中国

本教程改编自2019年的Fastai DL第1课,并添加了我的许多补充和阐明。
在本教程之后,您将可以在您选择的任何图像数据集上构建和训练图像辨认器,同时充分了解底层模型架构和训练过程。
本教程包括:

  • 数据提取
  • 数据可视化
  • 模范训练:CNN、ResNets、迁移学习
  • 结果解释
  • 模型层的冻结和解冻
  • 微调:学习速率查找器,一周期策略
本教程次要针对的是一些深度学习实际者,任何想要运用CNN和ResNets“刷”图像分类基础知识的人,或任何没有运用过fastai库并希望试用它的人。
本教程的笔记本也可以在这里找到。Fastai-iNotes-iTutorials/Image_Recognition_Basics.ipynb at master · SalChem/Fastai-iNotes-iTutorials · GitHub
要运转笔记本,您只需运用Google Colab打开它即可。
笔记本电脑都是独立的,没有bug,所以你可以按原样运转它。
进入Colab后,请务必更改以下内容以启用GPU后端,
运转时 - >更改运转时类型 - >硬件加速器 - > GPU
本教程中的代码简要阐明。有关任何类、方法等的进一步文档可以在fastai docs| fastai上找到。
让我们末尾吧…
设置IPython内核并初始化
导入必要的库,

我们做一些初始化,

bs是我们的批量大小,即一次输入模型的训练图像的数量。模型参数会在每批迭代之后更新。
例如,假如我们有640个图像,我们的批量大小为64;参数将在1个历元的过程中更新10次。
假如您在本教程中的某个时辰遇到内存不足的状况,则较小的批处理大小可以提供协助,批次大小通常是2的倍数。
运用特定的值初始化下面的伪随机数生成器可使系统波动,从而产生可重现的结果。
1.数据提取

我们将运用的数据集是Oxford-IIIT Pet Dataset,它可以运用fastai数据集模块检索。

URLs.PETS是数据集的URL,它有12个猫种类和25个狗种类,untar_data解压并将数据文件下载到我们的途径中。

get_image_files获取images目录中包含的一切文件的途径,并将它们存储到fnames中。来自fnames的实例如下所示,
PosixPath('/home/jupyter/.fastai/data/oxford-iiit-pet/images/scottish_terrier_119.jpg')
由于每个图像的标签都包含在图像文件名中,我们将运用正则表达式来提取它。正则表达式(通常缩写为正则表达式)是描画一定量文本的形式。我们提取图像标形式如下,

最后一步是特定于此数据集的。例如,假如属于同一类的图像位于同一文件夹中,我们不必担心它。
如今让我们创建我们的训练和验证数据集,

ImageDataBunch根据途径path_img中的图像创建训练数据集train_ds和验证数据集valid_ds。
from_name_re运用在编译表达式形式pat后获得的正则表达式从文件称号列表中获取标签。
df_tfms是动态运用于图像的转换。在这里,图像将调整为224x224,居中,裁剪和缩放。这种转换是数据加强的实例,曾经证明在计算机视觉中很有前景。此类转换不会更改图像外部的内容,但会更改其像素值以获得更好的模型泛化。
normalize运用ImageNet图像的标准偏向和平均值对数据停止标准化。
2.数据可视化

训练数据样本表示为
(Image (3, 224, 224), Category scottish_terrier)
其中第一个元素表示图像3RGB通道、行和列。第二个元素是图像标签。
这个实例的相应图像是,

len(data.train_ds)和len(data.valid_ds)分别输入训练和验证样本的数量5912和1478。
data.c和data.classes分别输入类及其标签的数量。有37个类别,以下标签,
['Abyssinian', 'Bengal', 'Birman', 'Bombay', 'British_Shorthair', 'Egyptian_Mau', 'Maine_Coon', 'Persian', 'Ragdoll', 'Russian_Blue', 'Siamese', 'Sphynx', 'american_bulldog', 'american_pit_bull_terrier', 'basset_hound', 'beagle','boxer', 'chihuahua', 'english_cocker_spaniel', 'english_setter', 'german_shorthaired', 'great_pyrenees', 'havanese', 'japanese_chin', 'keeshond', 'leonberger', 'miniature_pinscher', 'newfoundland', 'pomeranian', 'pug', 'saint_bernard', 'samoyed', 'scottish_terrier', 'shiba_inu', 'staffordshire_bull_terrier', 'wheaten_terrier', 'yorkshire_terrier']

show_batch在批处理中显示大批的图像。

3.模型训练


cnn_learner运用来自给定架构的预训练模型构建CNN学习器。来自预训练模型的学习参数用于初始化我们的模型,允许更快的收敛和高精度。
这里运用的CNN架构是ResNet34,它在过去几年中获得了宏大成功,照旧被以为是最先进的。
讨论CNN和ResNets非常有价值,由于这将有助于我们更好地了解我们的训练流程。我们可以?
CNNs简而言之:
首先,什么是卷积神经网络(CNN或convNet)?我们可以将ConvNet视为将图像卷转换为输入卷的图层列表,就像本教程中的状况一样,它可以是一个类得分。这些层由衔接到前一层的其他神经元的神经元组成。为了你更好的停止阅读,我这里激烈引荐斯坦福大学CS231课程的卷积神经网络。
典型的CNN架构


该图展现了一个典型的convNet架构。我们可以将一切CNN架构视为不同可微函数(卷积、下采样和仿射变换)的各种组合。上图只要很少的层,但深层网络有几十到几百层。
ResNets简而言之:
深度网络中一个非常普遍的成绩是降级成绩,其中模型精度达到饱,然后迅速降级。这是违犯直觉的,由于我们希冀附加层应该可以完成更详细和笼统的表示。这个成绩正是ResNets旨在处理的成绩,由于它们可以安全地优化训练更深层次的网络,而不必担心降级成绩。
ResNets处理降级成绩的方法是引入“身份快捷衔接”,跳过一个或多个层。跳过衔接的输入被添加到堆叠层的输入中,如下图所示。跳过衔接有效地跳过某些层上的学习过程,使深层网络在某种程度上也充当浅层网络。

Skip函数创建所谓的残差块,图中的F(x),这就是残差网这个称号的由来。传统网络的目的旨在直接学习输入H(x),而ResNets旨在学习残差F(x)。使F(x)= 0允许网络跳过该子网,如H(x)= x。
曾经表明,添加这些身份映射允许模型更深化而不降低功能,并且这种网络比普通堆叠层更容易优化。 ResNets有几种变体,例如ResNet50、ResNet101、ResNet152; ResNet编号表示ResNet网络的层数(深度)。
在本教程中,我们运用的是ResNet34,如下所示,
ResNet34的体系结构和卷积内核


在图中,底部数字表示输入或特征地图大小(高度x宽度),下面的数字表示通道数(过滤器数量)。例如,第一个左块表示输入图像(224 x 224 x 3)。图中的每个“层”都包含很少的残余块,这些残余块又包含具有不同可微函数的堆叠层,从而导致34层端到端。下面是ResNet34架构的残缺底层规划,与相似的普通架构相比;侧箭头表示身份衔接。
平面34层CNN(左)和34层ResNet(右)


您可以随意尝试任何其他resnet,只需交换模型即可。resnet34by模型。resnet50或任何其他所需的架构。请记住,添加层数将需求更多的GPU内存。
我们下面描画的运用预训练模型并使其顺应我们的数据集的内容称为迁移学习。但为什么要运用迁移学习呢?
迁移学习:
深度神经网络具有大量参数,通常在数百万的范围内。在小型数据集(一个小于参数数量的数据集)上训练此类网络会极大地影响网络的推行才能,从而导致过度拟合。因此在实际中,经过随机权重初始化从头末尾训练网络是很少见的。
预训练模型通常在非常大的数据集上训练,例如ImageNet,其包含具有1000个类别的120万个图像。因此,预训练模型曾经学会捕获其早期层中的曲线、颜色梯度和边缘等通用特征,这对于大多数其他计算机视觉分类成绩是相关且有用的。迁移学习也被证明在其他范畴也是有效的,例如NLP和语音辨认。
如今,经过迁移学习,我们的模型曾经在ImageNet上停止了预训练,我们只需求使其更详细地掌握我们数据集的细节。我们有两个选项可以做到这一点,我们只能更新最后一层的参数,或者我们可以更新一切模型的图层。第一个选项通常称为特征提取,而第二个选项称为微调。在这两种方法中,由于ImageNet预训练模型的输入层的大小为1000,因此,重要的是首先对最终层停止重新塑造,使数据集中的类数量相反。
到目前为止,我们已涵盖了许多核心概念
我们继续......
如今让我们在数据集上训练模型,

epochs数字表示模型查看整个图像集的次数。但是,在每个epoch,我们的数据添加后,相反的图像略有不同。
通常,度量误差将随着每个epoch而下降。只需验证集的精度不断提高,添加epoch数就是个好主意。但是,大量的epoch能够导致学习特定的图像而不是普通的类,这是我们想要避免的。
我们刚刚在这里停止的训练就是我们所说的特征提取,所以只更新了我们模型的头部(最后一层)的参数。接上去我们将尝试微调一切层。
恭喜!该模型已成功训练,以辨认狗和猫种类。
我们达到的准确率是≈93.5%
我们能做得更好吗?微调后我们会看到。
让我们保存当前的模型参数,以防我们稍后想要重新加载。

4.结果解释

如今让我们看看如何正确解释当前的模型结果。

Classification Interpretation提供错误分类图像的可视化。

plot_top_losses显示带有top loss的图像及其:
预测标签/实践标签/损失/实践图像类别的概率
高损得志味着对错误答案的高度信任。绘制最高损失是可视化和解释分类结果的好方法。
具有最高损失的错误分类图像



分类混淆矩阵


在混淆矩阵中,对角线元素表示预测标签等于真实标签的图像的数量,而非对角线元素是由分类器错误标记的元素。

most_confused简单地抓住预测和实践类别中最混乱的组合;换句话说,最常常出错的那些。我们可以看到它常常将斯塔福郡斗牛犬错误分类为美国斗牛梗,它们实践上看起来是有点相似的。
[('Siamese', 'Birman', 6),
('american_pit_bull_terrier', 'staffordshire_bull_terrier', 5),
('staffordshire_bull_terrier', 'american_pit_bull_terrier', 5),
('Maine_Coon', 'Ragdoll', 4),
('beagle', 'basset_hound', 4),
('chihuahua', 'miniature_pinscher', 3),
('staffordshire_bull_terrier', 'american_bulldog', 3),
('Birman', 'Ragdoll', 2),
('British_Shorthair', 'Russian_Blue', 2),
('Egyptian_Mau', 'Abyssinian', 2),
('Ragdoll', 'Birman', 2),
('american_bulldog', 'staffordshire_bull_terrier', 2),
('boxer', 'american_pit_bull_terrier', 2),
('chihuahua', 'shiba_inu', 2),
('miniature_pinscher', 'american_pit_bull_terrier', 2),
('yorkshire_terrier', 'havanese', 2)]
5.冷冻和解冻

默许状况下,在fastai中,运用预先训练的模型会冻结较早的层,以便网络只能更改最后一层的参数,如上所述。冻结第一层并仅训练较深层可以分明减少大量计算。
我们总是可以经过调用unfreeze函数来训练一切网络层,然后是fit或fit_one_cycle。这就是我们所谓的微调,由于我们正在调整整个网络的参数。我们末尾做吧,

如今的准确度比以前差一点。这是为什么?
这是由于我们以相反的速度更新一切层的参数,这不是我们想要的,由于第一层不需求像最后一层那样需求做太多改变。控制权重更新量的超参数称为学习率,也称为步长。它根据损失的梯度调整权重,目的是减少损失。例如,在最常见的梯度下降优化器中,权重和学习率之间的关系如下,

特地说一下,梯度只是一个向量,它是导数的多变量泛化。
因此,对模型停止微调的更好方法是对较低层和较高层运用不同的学习速率,通常称为差异或判别学习速率。
特地说一句,我在本教程中可以互换运用参数和权重。更准确地说,参数是权重和偏向,但我们不需求担心这里的纤细之处。但请留意,超参数和参数不同;超参数无法在训练中估计。
6.微调

为了找到最合适微调模型的学习率,我们运用学习速率查找器,其中学习速率逐渐添加并且在每批之后记录相应的损失。 fastai库在lr_find中完成了这一点。如需进一步阅读,请查看@GuggerSylvain如何找到良好的学习率。
让我们加载之前保存的模型并运转lr_find,

recorder.plot方法可用于绘制损失与学习率的关系。当损失末尾分歧时,情节会中止。

从得到的图中,我们分歧以为适当的学习率约为1e-4或更低,在损失末尾添加并且得到控制之前。我们将1e-4分配给最后的层,将1e-6分配给较早的层。异样,这是由于早期的层曾经训练有素,可以捕获通用功能,并且不需求那么多的更新。
假如您想知道我们之前的实验中运用的学习率,由于我们没有明白声明它,它是0.003,这是库中默许设置的。
在我们运用这些判别性学习率训练我们的模型之前,让我们揭开fit_one_cycle和fitmethods之间的差异,由于两者都是训练模型的合理选择。这个讨论对于了解训练过程非常有价值,但可以直接跳到结果。
fit_one_cycle vs fit:
简而言之,不同之处在于fit_one_cycle完成了Leslie Smith 1循环策略,它不是运用固定或降低的学习速率来更新网络的参数,而是在两个合理的较低和较高学习速率范围之间振荡。让我们再深化了解一下这对我们的训练有何协助。
训练中的学习率超参数
在调整我们的深度神经网络时,良好的学习率超参数是至关重要的。高学习速率允许网络更快地学习,但是太高的学习速率能够使模型无法收敛。另一方面,较小的学习率会使训练进度非常缓慢。
各种学习率对收敛的影响


在我们的案例中,我们经过查看不同窗习率下记录的损失来估算适当的学习率(lr)。在更新网络参数时,可以将此学习速率用作固定值;换句话说,将经过一切训练迭代运用相反的学习率。这就是learn.fit(lr)所做的。一种更好的方法是随着训练的停止改变学习率。有两种方法可以做到这一点,即学习速率计划(基于工夫的衰减、逐渐衰减、指数衰减等)或自顺应学习速率方法(Adagrad,RMSprop,Adam等)。有关此内容的更多信息,请查看有关参数更新的CS230 Stanford类注释。另一个很好的资源是@Sebastian Ruder对梯度下降优化算法的概述。
简而言之,一个周期策略
一个周期策略是一种学习速率调度器,其允许学习速率在合理的最小和最大边界之间振荡。这两个界限的价值是什么?下限是我们从学习速率查找器获得的,而最小界限可以小10倍。这种方法的优点是它可以克制部分极小点和鞍点,鞍点是平面上具有典型小梯度的点。理想证明,1cycle策略比其他调度或自顺应学习方法更快、更准确。 Fastai在fit_one_cycle中完成了1cycle策略,该策略在外部调用fit方法和1cycle Scheduler回调。

在fastai完成中对1cycle策略的一个小修正包括在从lr_max到0的第二阶段中的余弦退火。
1cycle策略发现
莱斯利史密斯首先发现了一种他称为循环学习率(CLR)的方法,他表明CLR在计算上并不昂贵,并且它们不需求找到最佳学习速率值,由于最佳学习速率将介于最小和最大界限之间。然后,他运用另一种规范的神经网络超参数方法来跟踪该论文:第1部分 - 学习率、批量大小、动量和权重衰减,他强调了各种回复和建议,以便加快网络训练以产生最佳结果。其中一个建议是运用仅一个周期的CLR来完成最佳和疾速的结果。作者将方法命名为1cycle策略。
下图展现了如何运用56层残差网络架构,在Cifar-10更少的迭代中,超收敛方法比典型的(分段常数)训练机制达到更高的精度。

在Cifar-10上,超收敛精度测试与具有相反架构的典型训练机制的比较[Source]
假如你选择跳过阅读莱斯利史密斯的论文,我照旧会建议阅读这篇文章@GuggerSylvain的1cycle策略。
关键时辰
如今,我们为层选择了有区别的学习率,我们可以解冻模型并相应地停止训练。

切片函数将1e-4赋值给最后一层,将1e-6赋值给第一层;中间的层在此范围内以相等的增量获得学习率。
我们看到准确度有所改善,但并不多,所以我们想知道能否需求对模型停止微调?
在微调任何模型之前一直要思索的两个关键要素,数据集的大小及其与预训练模型的数据集的相似性。查看斯坦福大学关于何时以及如何微调的CS231笔记?在我们的例子中,我们的Pet数据集相似于ImageNet中的图像,并且它相对较小,这就是为什么我们从一末尾就完成了高分类精度而没有对整个网络停止微调。
虽然如此,我们照旧可以提高我们的结果并学到很多东西,所以非常棒的工作
下图阐明了运用和微调预训练模型的三种合理方法。在本教程中,我们尝试了第一个和第三个策略。策略2在数据集较小但与预训练模型的数据集不同或者数据集较大但与预训练模型的数据集相似的状况下也很常见。
在预先训练的模型上微调策略


恭喜,我们曾经成功地运用最先进的CNN覆盖了图像分类,并具有基础结构和训练流程的坚实基础。
您已预备好在本人的数据集上构建图像辨认器。假如您还没有,可以从Google图像中删除图像并组成数据集。我为此做了一个非常简短的教程。「链接」

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

大神点评4

知识深奥,看不懂,教师,
回复

使用道具 举报

我是ZHENMI 2019-11-21 12:18:50 显示全部楼层
啥玩应呀
回复

使用道具 举报

好,很好,非常好!
回复

使用道具 举报

套牢了 2019-11-23 08:13:14 显示全部楼层
鄙视楼下的顶帖没我快,哈哈
回复

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies