本篇在不需要很多机器学习相关知识以及 http://ML.NET 知识的情况下介绍一些机器学习方面的基本概念、工具以及如何利用 .NET Core 上的 http://ML.NET 机器学习框架使用一个已经训练好的机器学习模型。
2、背景人工智能(Artificial intelligence/AI)也被称做机器智能,它是一种由机器展现出的“学习”与“解决问题”的智能,与之相对应就是自然智能即由人和者其他生物展现出的智能。机器学习(Machine Learning)是实现人工智能的方式之一,而深度学习(Deep Learning)则是机器学习的其中一种方法。这三个概念的关系参考下图
我们要使用的神经网络模型名为 Tiny YOLOv2,它是一个简化版本的 YOLO 模型。这是一个用于图像中对象识别与定位的神经网络模型。关于该神经网络的深入内容有兴趣的读者可以阅读下面两篇文章,其中一篇是简要介绍另外一篇则是对应的论文。
Real-time object detection with YOLOmachinethink.net YOLO 神经网络论文arxiv.org算法有了,还需要一套训练神经网络的数据集,Tiny YOLOv2 是通过 PASCAL VOC 数据集训练得到的模型,数据集的信息可以在下面的链接找到,
PASCAL VOC datasethost.robots.ox.ac.ukTiny YOLOv2 模型的文件可以在 ONNX 项目的 GitHub 站点,这里我们要使用的是ONNX 格式的模型文件。
onnx/modelsgithub.com那什么是ONNX呢? 目前各个语言的机器学习框架的模型都有自己的模型文件格式,比如TensorFlow的.pd,Keras的.keras,CoreML的.mlmodel 等等。ONNX旨在通过提供一个开源的支持深度学习与传统机器学习模型的格式建立一个机器学习框架之间的生态,让我们可以在不同的学习框架之间分享模型,目前受到绝大多数学习框架的支持。详情可以浏览其主页。
ONNX: Open Neural Network Exchange Formatonnx.ai了解了我们所用模型,下面介绍这个模型的内容。我们可以使用一个机器学习模型可视化工具:Netron,使用它可以查看模型的具体信息,包括元数据,网络结构等等。下面是该工具的网页版。
Netronlutzroeder.github.io下图是 Tiny YOLO 模型在 Netron 中打开后显示的信息,
这里不介绍算法与原理,我们只关心这个网络的输入和输出。如图所示,这个模型的输入参数为 float32 [3x416x416],这是一个长度为519168的float32数组,其中416x416是图片的像素,每个像素由RGB三个通道组成,所以要再乘以三。
输出参数为float32 [125x13x13],13x13对应的是在处理过程中将图像分割成的grid,而125对应的是每个grid对应的5个bounding box,即25x5。对应每个bounding box 的预测信息,[ x,y,wdith,hegiht,o,p1,p2,p3.....p20 ],其中 x,y,width,height为定位信息,o 为目标的置信分数,p1....p20 分别是20类目标的分类得分,其中这个20个类别分别为:
- aeroplane/飞机
- bicycle/自行车
- bird/鸟
- boat/船
- bottle/瓶子
- bus/公共汽车
- car/汽车
- cat/猫
- chair/椅子
- cow/牛
- diningtable/餐桌
- dog/狗
- horse/马
- motorbike/摩托车
- person/人
- pottedplant/盆栽
- sheep/羊
- sofa/沙发
- train/火车
- tvmonitor/显示器
知道了该模型的功能及输入输出的含义,我们就可以开始写代码了。
上面介绍了一堆东西,简单回顾整理下:
- Tiny YOLOv2,模型的名称,是YOLOv2模型的简化版。
- ONNX,一个跨机器学习框架的模型格式,也是本文中我们使用的模型的格式。
- Netron,一个模型可视化工具,支持绝大多数机器学习框架的模型格式。
- PASCAL VOC 数据集,Tiny YOLOv2 由此数据集训练而来。
现在各种语言的机器学习框架如雨后春笋般的涌现,下面仅仅是一小部分例子。
- Python:Tensorflow、PyTorch、SciKit-Learn、Caffe、Keras
- C#:http://ML.NET、http://Accord.NET
- C++:EBLearn
- Java:Deeplearning4j、Encog
- Javascript:Convent.js
- Swift:CoreML
http://ML.NET 就是 .NET 平台上官方的机器学习框架,ML既 Machine Learning。关于 http://ML.NET 的基本信息请查看下面这篇文章,这里就不多做叙述了。
6号咸鱼:终于等到妳!.NET平台机器学习框架ML.NET介绍zhuanlan.zhihu.com 4、代码解析示例项目的源代码可以在这里下载到,也可以从GitHub站点下载。
dotnet/machinelearning-samplesgithub.com关键类型-PredictionEngine与PredictionEnginePool
PredictionEngine
输入输出参数类型的定义
根据模型的输入输出,定义相应的类型。
//所在目录~/ML/DataModels
//输入类型
public class ImageInputData
{
[ImageType(416, 416)]
public Bitmap Image { get; set; }
}
//输出类型
public class ImageObjectPrediction
{
[ColumnName("grid")]
public float[] PredictedLabels;
}
模型加载
OnnxModelConfigurator类帮助我们加载ONNX模型,配置 http://ML.NET 管道(Pipeline)并生成 http://ML.NET 的模型文件供PredictionEnginePool 类加载并使用,配置 http://ML.NET 管道的具体内容包括对输入图片的预处理。
//Startup.cs //加载onnx模型 OnnxModelConfigurator onnxModelConfigurator = new OnnxModelConfigurator(_onnxModelFilePath); //转存为ML.NET模型 onnxModelConfigurator.SaveMLNetModel(_mlnetModelFilePath); //在 ConfigureServices 方法中通过扩张方法在services中添加PredictionEngine并从文件中加载模型。 services.AddPredictionEnginePool().FromFile(_mlnetModelFilePath); //通过 IServiceCollection 扩展方法来添加服务的方式符合 ASP.NET Core 设计惯例。
OnnxModelConfigurator中包含了构建 http://ML.NET 管道的方法,管道(pipeline)是 http://ML.NET 的核心概念,它封装了数据处理与学习算法。在下面的代码中我们在管道中添加了图片的预处理方法并加载了ONNX模型。这样 OnnxModelConfigurator 就可以将其保存为 http://ML.NET 的模型文件。
//源代码文件Services/ObjectDetectionService.cs
//利用onnx模型构建ML.NET pipeline即ML.NET模型
//pipline shi ml.net de zhongdian
var pipeline = _mlContext.Transforms.ResizeImages(resizing: ImageResizingEstimator.ResizingKind.Fill, outputColumnName: "image",
imageWidth: ImageSettings.imageWidth, imageHeight: ImageSettings.imageHeight,
inputColumnName: nameof(ImageInputData.Image))//输入图片预处理,将图片调整为要求的大小
.Append(_mlContext.Transforms.ExtractPixels(outputColumnName: "image"))//将调整后的图片转换为带三个通道的像素数组
.Append(_mlContext.Transforms.ApplyOnnxModel(modelFile: onnxModelFilePath,
outputColumnNames: new[] { TinyYoloModelSettings.ModelOutput },
inputColumnNames: new[] { TinyYoloModelSettings.ModelInput }));//应用onnx模型
执行推断(Predication)
//源代码文件Controllers/ObjectDetectionController.cs //执行推断并获取最后的结果图片 _objectDetectionService.DetectObjectsUsingModel(imageInputData); var img = _objectDetectionService.DrawBoundingBox(imageFilePath);
输出的解析与过滤
模型输出的结果是 float[] 类型,我们需要将其整理为对应信息与分类预测,并获取其中的高分结果绘制到结果图片上。
YoloParser/YoloOutputParser.cs中 的 YoloParser 类解析输出的 float[] 并整理为 IList
public void DetectObjectsUsingModel(ImageInputData imageInputData)
{
var probs = model.Predict(imageInputData).PredictedLabels;
IList boundingBoxes = _parser.ParseOutputs(probs);
filteredBoxes = _parser.FilterBoundingBoxes(boundingBoxes, 5, .5F);
}
绘制结果图片
ObjectDetectionService 中的 DrawBoundingBox 方法根据上面输出的 boundingBoxes 将定位与识别信息绘制在原有的图片上并生成新的图片,最后输出到页面。
到此从图片的输入到最后识别定位结果的输出就结束了,你可以在输出中看到如下的信息。
5、结语本文介绍了机器学习的背景,并通过一个现成的ONNX模型展示了如何使用 http://ML.NET 。希望这能成为有兴趣的读者开始学习机器学习的一个起点,从使用模型开始了解机器学习并逐步深入到机器学习算法,计算pipeline的构建,模型的训练等等。
非常感谢您的阅读。



