微软Microsoft Azure 机器学习工作室的案例之Image Classification using DenseNet


Microsoft Azure Machine Learning Studio是微软强大的机器学习平台,在设计器中,微软内置了15个场景案例,但网上似乎没有对这15个案例深度刨析的分析资料,所以我就计划写一个系列来完成。

既然是深度刨析,就不再是简单的介绍操作,而是深入每一个细节,宁愿过度详细扩展,也不简单扫过。


微软MVP实验室研究员

图片

王豫翔,Leo

微软圈内人称王公子。微软10年+MVP,大龄程序员。目前核心工作是使用微软AI技术设计可以落地的解决方案,也就是写PPT。虽然热爱代码,但只有午夜时分才是自由敲代码的时间。喜欢微软技术,不喜欢无脑照抄。


这次我们刨析的案例是:使用 DenseNet 进行的图像分类

预备知识

▌PIL

Python Image Library,是 python 的第三方图像处理库,PIL 库支持图像存储,显示和处理,几乎能够处理几乎所有的图片格式,所以已经算得上是 Python 平台事实上的图像处理标准库了。但是由于 PIL 仅支持到 Python 2.7,所以在3.X Python下,你应该使用 PIL 的硬分叉 Pillow ,由于 Pillow 兼容 PIL 的绝大多数语法同时因为 PIL 的巨大影响力,所以我们一般还是叫 PIL 图片处理。还有一点要注意 Pillow 和 PIL 不能共存在相同的环境中。

使用PIL可以帮我们对训练样本进行扩充,这意思就是使用PIL库对样本文件随机调整大小的裁剪、随机裁剪、随机水平翻转、随机垂直翻转、随机旋转、随机仿射、随机灰度、随机透视、随机擦除。

▌DenseNet

密集连接的卷积网络(Densely Connected Convolutional Networks),一种监督学习的分类算法。在 DenseNet 出现之前,CNN 的进化一般通过层数的加深(ResNet)或者加宽(Inception)的思想进行,。2017年的 DenseNet脱离了加深网络层数(ResNet)和加宽网络结构(Inception)来提升网络性能的定式思维,从特征的角度考虑,通过特征重用和旁路(Bypass)设置,既大幅度减少了网络的参数量,又在一定程度上缓解了梯度消亡(gradient vanishing)问题的产生。结合信息流和特征复用的假设,DenseNet当之无愧成为2017年计算机视觉顶会(CVPR)的年度最佳论文(Best Paper)。

简单的说,在DenseNet之前,有一个问题:有没有一种方法可以让网络又深梯度又不会消失?

DenseNet给出了一个简单优雅的答案:直接通过将前面所有层与后面的层建立密集连接来对特征进行重用来解决这个问题。

作者主要提出了四种网络架构分别是DenseNet121、DenseNet169、DenseNet201以及DenseNet264,现在已经有了大概11中网络架构,densenet121, densenet161, densenet169, densenet201, resnet18, resnet34, resnet50, resnet101, resnet152, vgg16, vgg19。Microsoft Azure Machine Learning Studio 提供的是原始恶4种网络结构,一般我们选择 DenseNet201 或者 DenseNet169。

▌PyTorch

pytorch是一个基于Python的科学计算包,它主要有两个用途:

  • 类似于Numpy但是能利用GPU加速
  • 一个非常灵活和快速用于深度学习的研究平台

所以说PyTorch既可以看作加入了GPU支持的numpy,同时也可以看成一个拥有自动求导功能的强大的深度神经网络。PyTorch的优点到底是啥呢?PyTorch不仅仅是定义网络结构简单,而且还很直观灵活。静态图的网络定义都是声明式的,而动态图可以随意的调用函数。

PyTorch更有利于研究人员、爱好者、小规模项目等快速搞出原型。而TensorFlow更适合大规模部署,特别是需要跨平台和嵌入式部署时。

深入分析

这套案例一共十二个工作节点,但其中有两组五个节点是一样的。这个案例种不需要我们进行编码,但提供了我们关于图片分类训练的最佳实践,值得我们认真了解。我们逐个分析每一个节点中值得关注的细节和核心信息。

▌Animal Images Dataset

节点这个节点是数据的输入,核心有两个信息

  • Datastore name:azureml_globaldatasets是一个链接,点击可以跳转到数据存储的位置
  • Relative path:描述在Datastore中当前文件的位置,默认是Images/Animals_Images_Dataset

点击azureml_globaldatasets将跳转到Datastore浏览器,您可以在这个浏览器下观察到您存储的数据。大致的界面如下

图片

点击这些图片可以预览

  • Cat:前缀为0的是各种喵星人的玉照,各种颜色,各种卖萌。其中还有一只和人类一起同框的一脸惊讶的黑色喵星人。(10张图片)
  • Dog:前缀为1的是汪星人,同样是各种姿态各种萌。(10张图片)
  • Frog:前缀为2的生物以我浅薄的生物知识我一下子无法归纳,不知道是青蛙,还是癞蛤蟆还是蟾蜍。反正就是蛙类生物就行了。(10张图片)

合计一共30张图片样本。这些文件在存储的时候是以如下命名结构方式存储:

Your_image_folder_name/Category_1/xxx.png
Your_image_folder_name/Category_1/xxy.jpg
Your_image_folder_name/Category_1/xxz.jpeg

Your_image_folder_name/Category_2/123.png
Your_image_folder_name/Category_2/nsdf3.png
Your_image_folder_name/Category_2/asd932_.png

文件夹的名称被视为图像分类等任务的标签。目前支持“.jpg”,“.jpeg”,“.png”,“.ppm”,“.bmp”,“.pgm”,“.tif”,“.tiff”,“.webp”类型文件,可以在一个文件夹中拥有多种类型的图像。不必在每个类别文件夹中包含相同数量的图像。

对了,你还可以使用扩展名为“.zip”,“.tar”,“.gz”和“.bz2”的文件夹或压缩文件。

▌Convert to Image Directory节点

将图像数据集转换为“图像目录”数据类型,这是 Azure 机器学习设计器中的图像分类等与图像相关的任务中的标准化数据格式。这个节点是把所有的图片文件放到一个目录下,不在通过目录名称将图片分类

图片

但会用images.lst的文件描述了图片的标签,类似这样的信息

{"image_info": {"file_name": "image/1_134.jpg"}, "category": "dog", "id": 134}
{"image_info": {"file_name": "image/0_91.jpg"}, "category": "cat", "id": 91}
{"image_info": {"file_name": "image/0_74.jpg"}, "category": "cat", "id": 74}
{"image_info": {"file_name": "image/0_60.jpg"}, "category": "cat", "id": 60}
{"image_info": {"file_name": "image/0_14.jpg"}, "category": "cat", "id": 14}
{"image_info": {"file_name": "image/1_197.jpg"}, "category": "dog", "id": 197}
{"image_info": {"file_name": "image/1_172.jpg"}, "category": "dog", "id": 172}

这个工作你可以看成是Convert to Image Directory组件将指定位置的图片读取并输入给之后的处理。

▌Split Image Directory节点

Split Image Directory节点有两个,分布用于训练模型和验证

  • 第一次拆分:将90%的样本用于训练,将10%的样本用于验证。拆分后用于训练的文件有29张图片,用于验证的图片有3张
  • 第二次拆分:将用于训练的样本再次拆分,依然还是90%用于训练,10%用于验证。拆分后用于训练的文件有24张图片,用于验证的图片有3张

这两次拆分非常重要,请认真理解两次拆分的目的。经过这两次拆分,真正最后用于测试的样本占比在81%。

▌Init Image Transformation节点

初始化图像转换是一个非常重要的工作,因为采集大量的图片样本是一个成本很高的工作,所以通过将PIL图片做各种变形转换,相当于我们又给样本集加入了很多样本。比如我们对原始图片进行放大,缩小,裁剪部分,旋转,变成黑白等等。

要注意的是,Init Image Transformation对我们刚才拆分的三份样本都做了转换,这样我们就得到了很多新的样本。图像转换就是使用PIL帮助我们完成。对图像做大量随机转换,是图像机器学习种重要初始化工作,图片样本进行了大量的扩充后才提交给DenseNet训练。

  • 调整大小(Resize):将输入 PIL 图像的大小调整为给定大小, 如果选择“True”,则可以在 Size 中指定所需的输出图像大小,默认情况下为 256。
  • 居中裁剪(Center crop):如果选择“True”,则可以在裁剪大小(Crop size)中指定所需的作物输出图像大小,默认是224。
  • 边框填充(Pad):如果选择True:则可以在“Padding”中的每个边框上指定填充要添加的像素数。
  • 颜色抖动(Color jitter):指定是否随机更改图像的亮度、对比度和饱和度。
  • 灰度(Grayscale),指定是否将图像转换为灰度。
  • 随机调整大小(Random resized crop):对于随机调整大小的裁剪,指定是否将给定的 PIL 图像裁剪为随机大小和纵横比。生成原始大小的随机大小(范围从 0.08 到 1.0)和原始纵横比的随机纵横比(范围从 3/4 到 4/3)的裁剪。此裁剪最终调整为给定大小。这通常用于训练Inception网络。如果选择“True:则可以以随机大小指定每个边的预期输出大小。可以在随机裁剪大小(Random resized crop size)中指定所需的裁剪输出大小, 默认为 256。
  • 随机裁剪(Random crop),指随机位置裁剪给定的 PIL 图像。如果选择“True”,则可以在随机裁剪大小(Random crop size)中指定所需的裁剪输出大小, 默认为 224。
  • 随机水平翻转(Random horizontal flip),指定是否以概率 0.5 随机水平翻转给定的 PIL 图像。
  • 随机垂直翻转(Random vertical flip),指定是否以概率 0.5 随机垂直翻转给定的 PIL 图像。
  • 随机旋转(Random rotation),指定是否按角度旋转图像。如果选择“True:则可以通过设置随机旋转度(Random rotation degrees)(来指定度范围,默认情况下为 0。
  • 随机仿射(Random affine),指定是否对图像进行随机仿射变换以保持中心不变。如果选择“True:则可以在随机仿射度数(Random affine degrees)中指定可供选择的度数范围,默认情况下为0。
  • 随机灰度(Random grayscale),指定是否将图像随机转换为概率为 0.1 的灰度。
  • 随机透视(Random perspective),指定是否以概率 0.5 随机执行给定 PIL 图像的透视变换。

▌Apply Image Transformation节点

我们存储图片的目录也有了,转换图片的能力也有了,现在可以通过Apply Image Transformation指出每一个目录如何使用Image Transformation。我们有两种定义

  • 用于训练(For training):被设定的目录里的图形将全面使用nit Image Transformation设置的能力。
  • 用于推理(For inference):被设定的目录里的图形将排除随机创建新样本等转换。这是因为随机创建新样本(如“随机水平翻转”)的转换操作用于训练中的数据增强,这应该在推理中删除,因为推理样本需要固定以进行准确的预测和评估。

Apply Image Transformation节点有三个,分布对应了Split Image Directory拆分出的三部分图片。

▌DenseNet节点

有了预备知识中的DenseNet内容,你就非常容易理解这个节点的任务。使用DenseNet模型对样本进行训练。

我们需要选择

  • 模型名称(Model name):内置了121、161、169和201.一般我们可以选择201或者161.
  • 预训练(Pretrained):指定是否使用在 ImageNet 上预先训练的模型。建议选择True。
  • 内存效率(Memory efficient):定是否使用检查点,检查点的内存效率要高得多,但速度较慢。模式是False。

总体来说,DenseNet不需要我们做很多干预。

▌Train PyTorch Model节点

Train PyTorch Model节点要求三个输入:模型、训练数据集和验证数据集。其中模型只接受DenseNet 或 ResNet(这一点如果有错误,我以后会修正)

  • 时期(Epochs)循环访问整个数据集的次数,默认是5次
  • 批大小(Batch size)指定在一个批次中训练的实例数,默认为 16 个。
  • 学习率(Learning rate):将输出误差反向传播给网络参数,以此来拟合样本的输出。本质上是最优化的一个过程,逐步趋向于最优解。但是每一次更新参数利用多少误差,就需要通过一个参数来控制,这个参数就是学习率,也称为步长。设置的学习率越小,模型测试就越频繁,而且可能会陷入局部停滞。设置的学习率越大,收敛速度就越快,而且有可能会超过实际最小值。
  • 随机种子(Random seed)可以选择键入一个整数值,将其用作种子。
  • 耐性(Patience)所有的标准深度学习神经网络结构如全连接多层感知机都很容易过拟合:当网络在训练集上表现越来越好,错误率越来越低的时候,实际上在某一刻,它在测试集的表现已经开始变差。如发现 loss 相比上一个 epoch 训练没有下降,则经过 patience 个 epoch 后停止训练。默认是3

▌Score Image Model节点

为图像模型评分。这个节点没有需要配置的内容。

▌Evaluate Model节点

评估模型。评估模型返回的指标取决于您正在评估的模型类型:

  • 分类模型
  • 回归模型
  • 聚类分析模型

我们先了解下错误率和精度

image.png

  • 错误率:分类错误的样本数占样本总数的比例。
  • 精度:分类正确的样本数占样本总数的比例。
  • 查准率:在所有的预测为正例的结果中,真正例所占的比率。真正例/(真正例+假正例)
  • 召回率:在所有的正例中有多少被成功预测出来了。真正例/(真正例+假反例)

对应我们的模型,给出的结果是:

  • 总体准确率(Overall Accuracy):每个类别的每个准确度的平均值
  • 多分类微观查准率(Micro Precision):所有类别预测对的数目/测试集的总数
  • 多分类微观召回率(micro recall):所有类别预测对的数目/测试集的总数宏观查准率(macro precision):该类别预测对的数目/预测为该类别的所有数目
  • 宏观召回率(macro recall):该类别预测对的数目/该类别所有的数目

结束语

到这里,Image Classification using DenseNet案例的分析我们完成了,在这个过程中,我们详细的了解到各个节点的核心信息和相关的概念。从数据源、图片分类、图片预处理到训练。也同时接触到了大量的机器学习概念,本篇非常值得推荐作为Microsoft Azure Machine Learning Studio和机器学习的入门和深入读物。

在这之后,我将继续编写其他Microsoft Azure Machine Learning Studio案例。每一篇案例都可以独立阅读,因此有些概念会重复出现在每一篇中。


微软最有价值专家(MVP)

图片

微软最有价值专家是微软公司授予第三方技术专业人士的一个全球奖项。29年来,世界各地的技术社区领导者,因其在线上和线下的技术社区中分享专业知识和经验而获得此奖项。

MVP是经过严格挑选的专家团队,他们代表着技术最精湛且最具智慧的人,是对社区投入极大的热情并乐于助人的专家。MVP致力于通过演讲、论坛问答、创建网站、撰写博客、分享视频、开源项目、组织会议等方式来帮助他人,并最大程度地帮助微软技术社区用户使用 Microsoft 技术。

更多详情请登录官方网站:
https://mvp.microsoft.com/zh-cn


点击这里加入微软MVP~

你可能感兴趣的:(微软Microsoft Azure 机器学习工作室的案例之Image Classification using DenseNet)