手把手教你用PyTorch实现图像分类器(第一部分)

手把手教你用PyTorch实现图像分类器(第一部分)_第1张图片

经过几个月富有挑战性但是受益良多的学习,我最近从Udacity的Python Nanodegree program AI编程专业毕业。最后一个项目是用PyTorch创建一个102种不同类型的花的图像分类器。

在做这个final project的时候,很多同学都遇到了类似的问题和挑战。当我接近完成的时候,我决定与大家分享一些在未来对他人有益的建议和见解。

通过3篇短文,介绍如何实现图像分类器的概念基础——这是一种能够理解图像内容的算法。

本文的目标不是提供手把手的指导,而是帮助理解整个过程。如果你正在考虑学习机器学习或人工智能,你将不得不做类似的项目,并理解本系列文章中介绍的概念。

文章主要进行概念上的解释,不需要知道如何编写代码。此外,下面所包含的PyTorch细节是次要的,主要以PyTorch作为示例。

这个过程的第一步是加载一个pre-trained神经网络。在讨论这一步时,我将解释为什么要“reuse”网络(即使用“pre-trained”网络),阐明哪些部分可以重用,哪些部分不能重用,并提供如何根据需要定制pre-trained网络的指导。

加载预训练的网络

reuse是一种十分合理的策略,尤其是众所周知并且得到广泛认可的标准。在示例中,出发点是torchvision提供的一种模型结构。

本文的目标是加载其中的一个pre-trained网络,并且将其中的分类器替换为自己的分类器,从而可以训练自己的分类器。

虽然这个想法是合理的,但我发现它也会产生一些问题,因为加载一个预先训练的网络并不能节省训练分类器的时间。

“所以你可能会想,使用预训练网络有什么意义?”

当我们人类看到图像时,可以识别线条和形状。正因为如此,我们才能将图像内容与之前看到过的内容联系起来。我们希望我们的分类器能够做一些类似的事情,但是图像不是一段微不足道的数据。图像通常由数千个独立的像素组成,每个像素都有一种颜色,这种颜色由三个不同的值组合定义 : Red,Green, Blue。

手把手教你用PyTorch实现图像分类器(第一部分)_第2张图片

                                                               从左到右:原始,红色,绿色,蓝色 

如果我们希望我们的分类器能够处理该数据量,我们将需要处理每个图像中包含的所有信息,并以其可以理解的格式将其提供给分类器。这就是预训练网络发挥作用的地方。  

这些预先训练的网络主要由一组特征检测器和分类器组成,其中特征检测器被训练以从每个图像中提取信息,并且训练分类器以理解特征层提供的输入。

我们已经在已在ImageNet上培训过功能检测器,并且证明它可以有很好的表现。因此,我们希望保持原样。为了防止在我们训练分类器时,要素图层被修改,我们需要“冻结”它们。这个小代码片段可以帮助解决这个问题:  

for param in model.parameters():

    param.requires_grad = False

如果使用分类器会怎么样? 为什么我们不能重复使用它?   要回答这个问题,让我们以架构VGG16为例,来看看它的默认分类器:  

(classifier): Sequential(

  (0): Linear(in_features=25088, out_features=4096, bias=True)
  
  (1): ReLU(inplace)
  
  (3): Linear(in_features=4096, out_features=4096, bias=True)
  
  (4): ReLU(inplace)
  
  (5): Dropout(p=0.5)
          
  (6): Linear(in_features=4096, out_features=1000, bias=True)
  
)

首先,我们无法保证这一定是有效的。并且令人怀疑的是,这些默认层和元素,激活函数和丢失值对于我们的特定情况而言恰好是最佳的。  

当我们看到它的最后一层有1000个元素的输出时,情况就变得很明显了。在我们的例子中,我们处理102种不同类型的花,因此我们的分类器的输出必须是102 。

从上面VGG16中的默认分类器,我们还可以注意到它的输入层有25088个元素,因为这是此特定预训练模型中特征检测器的输出大小。我们的分类器的输入大小也必须与要素图层的输出相匹配。

结论

由上文我们可以得知,预先训练好的网络非常有益,因为它们使我们能够专注于我们的用例细节,同时重复使用众所周知的泛型来进行示例中的图像预处理。

我们还了解到,分类器输出的大小必须与我们希望能够识别的不同类型的数量相同。

最后,我们已经看到要素图层的输出和自定义分类器的输入也必须匹配大小。

在我的下一篇文章中,我们将探讨如何避免在分类器训练过程中常见的陷阱,并学习如何调整超参数以提高模块的准确性。

我的文章对你有用吗?期待你的评论!

 

你可能感兴趣的:(需要学习)