本文将使用ML.NET创建机器学习分类模型,通过ASP.NET Core Web API公开它,将其打包到Docker容器中,并通过Azure Container Instances将其部署到云中。

先决条件

本文假设您对Docker有一定的了解。构建和部署示例应用程序还需要以下软件/依赖项。重要的是要注意应用程序是在Ubuntu 16.04 PC上构建的,但所有软件都是跨平台的,应该适用于任何环境。

设置项目

我们要做的第一件事是为我们的解决方案创建一个文件夹。

mkdir mlnetacidemo

然后,我们想在新创建的文件夹中创建一个解决方案。

cd mlnetacidemo
dotnet new sln

建立模型

在我们的解决方案文件夹中,我们想要创建一个新的控制台应用程序,这是我们构建和测试我们的机器学习模型的地方。

设置模型项目

首先,我们要创建项目。从解决方案文件夹输入:

dotnet new console -o model

现在我们要将这个新项目添加到我们的解决方案中。

dotnet sln mlnetacidemo.sln add model/model.csproj

添加依赖项

由于我们将使用ML.NET框架,我们需要将其添加到我们的model项目中。

cd model
dotnet add package Microsoft.ML
dotnet restore

在我们开始训练模型之前,我们需要下载我们将用于训练的数据。我们通过创建一个名为data的目录并将数据文件下载到那里来实现。

mkdir data
curl -o data/iris.txt https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data

如果我们看一下数据文件,它看起来应该是这样的:

5.1,3.5,1.4,0.2,Iris-setosa
4.9,3.0,1.4,0.2,Iris-setosa
4.7,3.2,1.3,0.2,Iris-setosa
4.6,3.1,1.5,0.2,Iris-setosa
5.0,3.6,1.4,0.2,Iris-setosa
5.4,3.9,1.7,0.4,Iris-setosa
4.6,3.4,1.4,0.3,Iris-setosa
5.0,3.4,1.5,0.2,Iris-setosa
4.4,2.9,1.4,0.2,Iris-setosa
4.9,3.1,1.5,0.1,Iris-setosa

训练模型

现在我们已经设置了所有依赖项,现在是构建模型的时候了。我利用了ML.NET入门网站上使用的演示。

定义数据结构

在我们model项目的根目录中,让我们创建两个被调用的类IrisDataIrisPrediction它们将分别定义我们的特性和预测属性。它们都将用于Microsoft.ML.Runtime.Api添加属性属性。

这是我们IrisData的样子:

using Microsoft.ML.Runtime.Api;

namespace model
{
public class IrisData
{
[Column("")]
public float SepalLength; [Column("")]
public float SepalWidth; [Column("")]
public float PetalLength; [Column("")]
public float PetalWidth; [Column("")]
[ColumnName("Label")]
public string Label;
}
}

同样,这是IrisPrediction

using Microsoft.ML.Runtime.Api;

namespace model
{
public class IrisPrediction
{
[ColumnName("PredictedLabel")]
public string PredictedLabels;
}
}

构建LearningPipeLine

using Microsoft.ML.Data;
using Microsoft.ML;
using Microsoft.ML.Runtime.Api;
using Microsoft.ML.Trainers;
using Microsoft.ML.Transforms;
using Microsoft.ML.Models;
using System;
using System.Threading.Tasks; namespace model
{
class Model
{ public static async Task<PredictionModel<IrisData,IrisPrediction>> Train(LearningPipeline pipeline, string dataPath, string modelPath)
{
// Load Data
pipeline.Add(new TextLoader(dataPath).CreateFrom<IrisData>(separator:',')); // Transform Data
// Assign numeric values to text in the "Label" column, because
// only numbers can be processed during model training
pipeline.Add(new Dictionarizer("Label")); // Vectorize Features
pipeline.Add(new ColumnConcatenator("Features", "SepalLength", "SepalWidth", "PetalLength", "PetalWidth")); // Add Learner
pipeline.Add(new StochasticDualCoordinateAscentClassifier()); // Convert Label back to text
pipeline.Add(new PredictedLabelColumnOriginalValueConverter() {PredictedLabelColumn = "PredictedLabel"}); // Train Model
var model = pipeline.Train<IrisData,IrisPrediction>(); // Persist Model
await model.WriteAsync(modelPath); return model;
}
}
}

除了构建LearningPipLine并训练我们的机器学习模型之外,该模型还序列化并保存在名为model.zip的文件中以供将来使用。

测试我们的模型

现在是时候测试所有内容以确保它正常工作。

using System;
using Microsoft.ML; namespace model
{
class Program
{
static void Main(string[] args)
{ string dataPath = "model/data/iris.txt"; string modelPath = "model/model.zip"; var model = Model.Train(new LearningPipeline(),dataPath,modelPath).Result; // Test data for prediction
var prediction = model.Predict(new IrisData()
{
SepalLength = 3.3f,
SepalWidth = 1.6f,
PetalLength = 0.2f,
PetalWidth = 5.1f
}); Console.WriteLine($"Predicted flower type is: {prediction.PredictedLabels}");
}
}
}

全部设定运行。我们可以通过从解决方案目录输入以下命令来完成此操作:

dotnet run -p model/model.csproj

运行应用程序后,控制台上将显示以下输出。

Automatically adding a MinMax normalization transform, use 'norm=Warn' or
'norm=No' to turn this behavior off.Using threads to train.
Automatically choosing a check frequency of .Auto-tuning parameters: maxIterations = .
Auto-tuning parameters: L2 = 2.667734E-05.
Auto-tuning parameters: L1Threshold (L1/L2) = .Using best model from iteration .
Not training a calibrator because it is not needed.
Predicted flower type is: Iris-virginica

公开模型

此外,您会注意到在我们model项目的根目录中创建了一个名为model.zip的文件。这个持久化模型现在可以在我们的应用程序之外用于进行预测,我们接下来将通过API执行操作。

一旦构建了机器学习模型,您就希望部署它以便开始进行预测。一种方法是通过REST API。它的核心部分需要做的是接受来自客户端的数据输入并回复预测。为了帮助我们这样做,我们将使用ASP.NET Core API。

设置API项目

我们要做的第一件事是创建项目。

dotnet new webapi -o api

然后我们想将这个新项目添加到我们的解决方案中

dotnet sln mlnetacidemo.sln add api/api.csproj

添加依赖项

因为我们将加载我们的模型并通过我们的API进行预测,所以我们需要将ML.NET包添加到我们的api项目中。

cd api
dotnet add package Microsoft.ML
dotnet restore

引用模型

在我们构建机器学习模型的上一步中,它被保存到一个名为的文件中model.zip。这是我们将在API中引用的文件,以帮助我们进行预测。要在我们的API中引用它,只需将它从模型项目目录复制到我们的api项目目录中。

创建数据模型

我们的模型是使用数据结构构建的IrisDataIrisPrediction用于定义特征以及预测属性。因此,当我们的模型通过我们的API进行预测时,它也需要引用这些数据类型。因此,我们需要在项目内部定义IrisDataIrisPredictionapi。类的内容几乎与model项目中的内容相同,唯一的例外是我们的命名空间从更改modelapi

using Microsoft.ML.Runtime.Api;

namespace api
{
public class IrisData
{
[Column("")]
public float SepalLength; [Column("")]
public float SepalWidth; [Column("")]
public float PetalLength; [Column("")]
public float PetalWidth; [Column("")]
[ColumnName("Label")]
public string Label;
}
}
using Microsoft.ML.Runtime.Api;

namespace api
{
public class IrisPrediction
{
[ColumnName("PredictedLabel")]
public string PredictedLabels;
}

构建控制器

现在我们的项目已经建立,是时候添加一个控制器来处理来自客户端的预测请求了。在Controllers我们api项目的目录中,我们可以创建一个PredictController使用单个POST端点调用的新类。该文件的内容应如下所示:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.ML; namespace api.Controllers
{
[Route("api/[controller]")]
public class PredictController : Controller
{
// POST api/predict
[HttpPost]
public string Post([FromBody] IrisData instance)
{
var model = PredictionModel.ReadAsync<IrisData,IrisPrediction>("model.zip").Result;
var prediction = model.Predict(instance);
return prediction.PredictedLabels;
}
}
}

测试API

当我们的predict控制器完成编码,就可以来测试它了。从我们mlnetacidemo解决方案的根目录中,输入以下命令。

dotnet run -p api/api.csproj

我们的请求的正文应该类似于下面的代码段:在POSTMAN或Insomnia等客户端中,向端点发送HHTP POST请求http://localhost:5000/api/predict

{
"SepalLength": 3.3,
"SepalWidth": 1.6,
"PetalLength": 0.2,
"PetalWidth": 5.1,
}

打包应用程序

如果成功,返回的输出应该Iris-virginica与我们的控制台应用程序相同。大!现在我们的应用程序已在本地成功运行,现在是时候将它打包到Docker容器中并将其推送到Docker Hub。

创建Dockerfile

在我们的mlnetacidemo解决方案目录中,使用以下内容创建一个Dockerfile:

FROM microsoft/dotnet:2.0-sdk AS build
WORKDIR /app # copy csproj and restore as distinct layers
COPY *.sln .
COPY api/*.csproj ./api/
RUN dotnet restore # copy everything else and build app
COPY api/. ./api/
WORKDIR /app/api
RUN dotnet publish -c release -o out FROM microsoft/aspnetcore:2.0 AS runtime
WORKDIR /app
COPY api/model.zip .
COPY --from=build /app/api/out ./
ENTRYPOINT ["dotnet", "api.dll"]

构建镜像

我们需要在命令提示符中输入以下命令。这需要一段时间,因为它需要下载.NET Core SDK和ASP.NET Core运行时Docker镜像。

docker build -t <DOCKERUSERNAME>/<IMAGENAME>:latest .

本地测试镜像

我们需要在本地测试我们的镜像,以确保它可以在云上运行。为此,我们可以使用该docker run命令。

docker run -d -p : <DOCKERUSERNAME>/<IMAGENAME>:latest

要停止容器,请使用Ctrl + C。虽然API暴露了端口80,但我们将其绑定到本地端口5000只是为了保持我们先前的API请求不变。向http://localhost:5000/api/predict适当的主体发送POST请求时,应该再次响应同样的结果Iris-virginica。

推送到Docker Hub

现在Docker镜像在本地成功运行,是时候推送到Docker Hub了。同样,我们使用Docker CLI来执行此操作。

docker login
docker push <DOCKERUSERNAME>/<IMAGENAME>:latest

部署到云

现在,最后一步是向全世界部署和展示我们的机器学习模型和API。我们的部署将通过Azure容器实例进行,因为它几乎不需要配置或管理服务器。

准备部署清单

尽管可以在命令行中执行部署,但通常最好将所有配置放在文件中以备文档,并节省时间,而不必每次都输入参数。使用Azure,我们可以通过JSON文件来实现。

{
"$schema":
"https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
"contentVersion": "1.0.0.0",
"parameters": {
"containerGroupName": {
"type": "string",
"defaultValue": "mlnetacicontainergroup",
"metadata": {
"description": "Container Group name."
}
}
},
"variables": {
"containername": "mlnetacidemo",
"containerimage": "<DOCKERUSERNAME>/<IMAGENAME>:latest"
},
"resources": [
{
"name": "[parameters('containerGroupName')]",
"type": "Microsoft.ContainerInstance/containerGroups",
"apiVersion": "2018-04-01",
"location": "[resourceGroup().location]",
"properties": {
"containers": [
{
"name": "[variables('containername')]",
"properties": {
"image": "[variables('containerimage')]",
"resources": {
"requests": {
"cpu": ,
"memoryInGb": 1.5
}
},
"ports": [
{
"port":
}
]
}
}
],
"osType": "Linux",
"ipAddress": {
"type": "Public",
"ports": [
{
"protocol": "tcp",
"port": ""
}
]
}
}
}
],
"outputs": {
"containerIPv4Address": {
"type": "string",
"value":
"[reference(resourceId('Microsoft.ContainerInstance/containerGroups/', parameters('containerGroupName'))).ipAddress.ip]"
}
}
}

现在我们可以使用这个模板并将其保存到我们mlnetacidemo解决方案根目录下的文件azuredeploy.json中。唯一需要改变的是containerimage的配置,将其替换为您的Docker Hub用户名和刚刚推送到Docker Hub的镜像的名称。

部署

为了部署我们的应用程序,我们需要确保登录我们的Azure帐户。要通过Azure CLI执行此操作,请在命令提示符下键入:

az login

按照提示登录。登录后,是时候为容器创建资源组了。

az group create --name mlnetacidemogroup --location eastus

成功创建组后,就可以部署我们的应用程序了。

az group deployment create --resource-group mlnetacidemogroup --template-file azuredeploy.json

完成后,可以使用以下命令清理资源:

az group delete --name mlnetacidemogroup

为部署初始化需要消耗几分钟的时间。如果部署成功,您应该在命令行上看到一些输出。寻找ContainerIPv4Address主机,这是可以访问容器的IP地址,更换URL后再次做一个POST请求到http://<ContainerIPv4Address>/api/predict,ContainerIPv4Address是在部署后命令行中找到的值。如果成功,响应内容应该像以前的请求一样返回Iris-virginica

小结

在本文中,我们构建了一个分类机器学习模型,使用ML.NET该模型预测鸢尾花的分类,给出了四种分类的预测功能,通过ASP.NET Core REST API公开它,将其打包到容器中并使用Azure Container Instances将其部署到云中。虽然随着模型的变化,这些操作变得更加复杂,但是目前介绍的内容已经足够标准化,扩展此示例仅需要进行很少量的修改即可。

使用ML.NET + ASP.NET Core + Docker + Azure Container Instances部署.NET机器学习模型的更多相关文章

  1. 使用ML.NET + Azure DevOps + Azure Container Instances打造机器学习生产化

    介绍 Azure DevOps,以前称为Visual Studio Team Services(VSTS),可帮助个人和组织更快地规划,协作和发布产品.其中一项值得注意的服务是Azure Pipeli ...

  2. ASP.NET Core在Azure Kubernetes Service中的部署和管理

    目录 ASP.NET Core在Azure Kubernetes Service中的部署和管理 目标 准备工作 注册 Azure 账户 AKS文档 进入Azure门户(控制台) 安装 Azure Cl ...

  3. ASP.NET Core &amp; Docker 实战经验分享

    一.前言 最近一直在研究和实践ASP.NET Core.Docker.持续集成.在ASP.NET Core 和 Dcoker结合下遇到了一些坑,在此记录和分享,希望对大家有一些帮助. 二.中间镜像 我 ...

  4. ASP.NET Core Docker jexus nginx部署-CentOS实践版

    本文用图文的方式记录了我自己搭建centos+asp.net core + docker + jexus + nginx的整个过程,希望对有同样需求的朋友有一定的参考作用. 本文主要内容如下: cen ...

  5. ASP.NET Core &amp; Docker &amp; Jenkins 零基础持续集成实战

    原文:ASP.NET Core & Docker & Jenkins 零基础持续集成实战 一.本系列教程说明 源代码管理工具:Gogs 持续集成工具:Jenkins 容器:Docker ...

  6. ASP.NET Core使用Docker-Swarm集群部署实现负载均衡实战演练

    一.需求背景 人生苦短,我用.NET Core!阿笨对Docker是这样评价的:Docker在手,环境我有!Docker出手,集群我有!前面的Doc基础课程我们学习了如何使用Docker来部署搭建单机 ...

  7. ASP.NET Core的配置(2):配置模型详解

    在上面一章我们以实例演示的方式介绍了几种读取配置的几种方式,其中涉及到三个重要的对象,它们分别是承载结构化配置信息的Configuration,提供原始配置源数据的ConfigurationProvi ...

  8. [亲测]ASP.NET Core 2.0怎么发布/部署到Ubuntu Linux服务器并配置Nginx反向代理实现域名访问

    前言 ASP.NET Core 2.0 怎么发布到Ubuntu服务器?又如何在服务器上配置使用ASP.NET Core网站绑定到指定的域名,让外网用户可以访问呢? 步骤 第1步:准备工作 一台Liun ...

  9. ASP.NET Core 共享第三方依赖库部署的正常打开方式

    曾经: 写了一篇: ASP.Net Core on Linux (CentOS7) 共享第三方依赖库部署 当第二次想做相同的事,却遇上了Bug,于是有了第二篇: ASP.NET Core 共享第三方依 ...

随机推荐

  1. Entity Framework 6 Recipes 2nd Edition(13-9)译 -&gt; 避免Include

    问题 你想不用Include()方法,立即加载一下相关的集合,并想通过EF的CodeFirst方式实现. 解决方案 假设你有一个如Figure 13-14所示的模型: Figure 13-14. A ...

  2. 数据摘要算法的测试效率(SHA、MD5和CRC32)

    1.算法概述 数据摘要算法是密码学算法中非常重要的一个分支,它通过对所有数据提取指纹信息以实现数据签名.数据完整性校验等功能,由于其不可逆性,有时候会被用做敏感信息的加密.数据摘要算法也被称为哈希(H ...

  3. jquery 调用数据

    <body> <div id="aa" style="">hello</div> <div class="b ...

  4. 用java实现冒泡排序法

    一.基本思路: 冒泡排序是一种简单的交换类排序.其基本思路是,从头开始扫描待排序的元素,在扫描过程中依次对相邻元素进行比较,将关键字值大的元素后移.每经过一趟排序后,关键字值最大的元素将移到末尾,此时 ...

  5. 基于lua+nginx的abtest系统

    指定一个参数 这个参数可以标识客户端唯一id的,比如用户id等 拿到这个id根据系统的hash算法会hash出一个bucket,目前支持的桶总数为10 根据后台设定的map关系(redis或配置文件) ...

  6. 3.21 采购订单导入MDS

    3.21.1   业务方案描述 同一企业集团内部的不同法人之间,双方间内部往来业务频繁.受集团财务各自独立核算的要求,买方和卖方间采用买卖方式进行业务运作和财务结算. 对于买方,按照内部商定的协议价格 ...

  7. Python学习入门基础教程(learning Python)--6.3 Python的list切片高级

    上节"6.2 Python的list访问索引和切片"主要学习了Python下的List的访问技术:索引和切片的基础知识,这节将就List的索引index和切片Slice知识点做进一 ...

  8. Storm入门(一)原理介绍

    问题导读:1.hadoop有master与slave,Storm与之对应的节点是什么?2.Storm控制节点上面运行一个后台程序被称之为什么?3.Supervisor的作用是什么?4.Topology ...

  9. C++初始化列表(good)

    本文转载自http://www.cnblogs.com/graphics/archive/2010/07/04/1770900.html 感谢作者分享 何谓初始化列表 与其他函数不同,构造函数除了有名 ...

  10. PAT-7-14 电话聊天狂人

    ps: 真不明白为什么水题不能一次ac 7-14 电话聊天狂人(25 分) 给定大量手机用户通话记录,找出其中通话次数最多的聊天狂人. 输入格式: 输入首先给出正整数N(≤10​5​​),为通话记录条 ...