From 0a4cbb5c0f9f443f6e891688f18067b5a62ba341 Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Wed, 24 Apr 2019 17:17:18 -0400 Subject: [PATCH 1/7] Performance improvements and 1.0 preview --- ...model-serverless-azure-functions-ml-net.md | 113 ++++++++++-------- 1 file changed, 64 insertions(+), 49 deletions(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index bf2984ac1840b..28425ec6a5b59 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -1,19 +1,16 @@ --- -title: Deploy ML.NET Model to Azure Functions +title: "How-To: Deploy ML.NET machine learning model to Azure Functions" description: Serve ML.NET sentiment analysis machine learning model for prediction over the internet using Azure Functions -ms.date: 03/08/2019 +ms.date: 04/24/2019 +author: luisquintanilla +ms.author: luquinta ms.custom: mvc,how-to #Customer intent: As a developer, I want to use my ML.NET Machine Learning model to make predictions through the internet using Azure Functions --- -# How-To: Use ML.NET Model in Azure Functions +# How-To: Deploy ML.NET machine learning model to Azure Functions -This how-to shows how individual predictions can be made using a pre-built ML.NET machine learning model through the internet in a serverless environment such as Azure Functions. - -> [!NOTE] -> This topic refers to ML.NET, which is currently in Preview, and material may be subject to change. For more information, visit [the ML.NET introduction](https://www.microsoft.com/net/learn/apps/machine-learning-and-ai/ml-dotnet). - -This how-to and related sample are currently using **ML.NET version 0.10**. For more information, see the release notes at the [dotnet/machinelearning github repo](https://github.com/dotnet/machinelearning/tree/master/docs/release-notes). +Learn how to deploy a pre-trained ML.NET machine learning model for predictions over the internet through an Azure Functions serverless environment. ## Prerequisites @@ -64,9 +61,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Microsoft.ML; -using Microsoft.ML.Core.Data; -using Microsoft.ML.Data; -using MLNETServerless.DataModels; +using SentimentAnalysisFunctionsApp.DataModels; ``` ### Create Data Models @@ -78,65 +73,85 @@ You need to create some classes for your input data and predictions. Add a new c 2. In Solution Explorer, right-click the *DataModels* directory, and then select **Add > New Item**. 3. In the **Add New Item** dialog box, select **Class** and change the **Name** field to *SentimentData.cs*. Then, select the **Add** button. The *SentimentData.cs* file opens in the code editor. Add the following using statement to the top of *SentimentData.cs*: - ```csharp - using Microsoft.ML.Data; - ``` +```csharp +using Microsoft.ML.Data; +``` - Remove the existing class definition and add the following code to the SentimentData.cs file: +Remove the existing class definition and add the following code to the *SentimentData.cs* file: - ```csharp - public class SentimentData - { - [LoadColumn(0)] - public bool Label { get; set; } - [LoadColumn(1)] - public string Text { get; set; } - } - ``` +```csharp +public class SentimentData +{ + [LoadColumn(0)] + public bool Label { get; set; } + [LoadColumn(1)] + public string Text { get; set; } +} +``` 4. In Solution Explorer, right-click the *DataModels* directory, and then select **Add > New Item**. 5. In the **Add New Item** dialog box, select **Class** and change the **Name** field to *SentimentPrediction.cs*. Then, select the **Add** button. The *SentimentPrediction.cs* file opens in the code editor. Add the following using statement to the top of *SentimentPrediction.cs*: - ```csharp - using Microsoft.ML.Data; - ``` +```csharp +using Microsoft.ML.Data; +``` + +Remove the existing class definition and add the following code to the *SentimentPrediction.cs* file: + +```csharp +public class SentimentPrediction : SentimentData +{ + [ColumnName("PredictedLabel")] + public bool Prediction { get; set; } +} +``` + +`SentimentPrediction` inherits from `SentimentData` which provides access to the original data in the `Text` property as well as the output generated by the model. + +### Load the model into the function + +Insert the following code inside the *AnalyzeSentiment* class: + +```csharp +// Define MLContext +static MLContext _mlContext; + +// Define model +static ITransformer _model; + +// Define model's DataViewSchema +static DataViewSchema _modelSchema; + +// AnalyzeSentiment class constructor +static AnalyzeSentiment() +{ + // Create MLContext + _mlContext = new MLContext(); - Remove the existing class definition and add the following code to the *SentimentPrediction.cs* file: + // Load Model + _model = _mlContext.Model.Load("MLModels/sentiment_model.zip", out _modelSchema); +} +``` - ```csharp - public class SentimentPrediction - { - [ColumnName("PredictedLabel")] - public bool Prediction { get; set; } - } - ``` +The constructor contains initialization logic for the [`MLContext`](xref:Microsoft.ML.MLContext) and model so that it can be shared throughout the lifecycle of the function instance. This approach reduces having to load the model from disk each time the `Run` method is executed. -### Add Prediction Logic +### Use the model to make predictions Replace the existing implementation of *Run* method in *AnalyzeSentiment* class with the following code: ```csharp public static async Task Run( - [HttpTrigger(AuthorizationLevel.Function,"post", Route = null)] HttpRequest req, - ILogger log) +[HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, +ILogger log) { log.LogInformation("C# HTTP trigger function processed a request."); - //Create Context - MLContext mlContext = new MLContext(); - - //Load Model - using (var fs = File.OpenRead("MLModels/sentiment_model.zip")) - { - model = mlContext.Model.Load(fs); - } - //Parse HTTP Request Body string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); SentimentData data = JsonConvert.DeserializeObject(requestBody); //Create Prediction Engine - PredictionEngine predictionEngine = model.CreatePredictionEngine(mlContext); + PredictionEngine predictionEngine = _mlContext.Model.CreatePredictionEngine(_model); //Make Prediction SentimentPrediction prediction = predictionEngine.Predict(data); From fecc2161669ebbd751aa937e656a1cebbd53b7f0 Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Wed, 24 Apr 2019 17:31:47 -0400 Subject: [PATCH 2/7] Updated headings --- .../serve-model-serverless-azure-functions-ml-net.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index 28425ec6a5b59..b9ef7b0ec0833 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -64,7 +64,7 @@ using Microsoft.ML; using SentimentAnalysisFunctionsApp.DataModels; ``` -### Create Data Models +## Create Data Models You need to create some classes for your input data and predictions. Add a new class to your project: @@ -108,7 +108,7 @@ public class SentimentPrediction : SentimentData `SentimentPrediction` inherits from `SentimentData` which provides access to the original data in the `Text` property as well as the output generated by the model. -### Load the model into the function +## Load the model into the function Insert the following code inside the *AnalyzeSentiment* class: @@ -135,7 +135,7 @@ static AnalyzeSentiment() The constructor contains initialization logic for the [`MLContext`](xref:Microsoft.ML.MLContext) and model so that it can be shared throughout the lifecycle of the function instance. This approach reduces having to load the model from disk each time the `Run` method is executed. -### Use the model to make predictions +## Use the model to make predictions Replace the existing implementation of *Run* method in *AnalyzeSentiment* class with the following code: From 6199155916c3b2733590c22ea752c4f09583e22c Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Wed, 24 Apr 2019 17:34:33 -0400 Subject: [PATCH 3/7] Update to constructor explanation --- .../serve-model-serverless-azure-functions-ml-net.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index b9ef7b0ec0833..4b98ec1014985 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -133,7 +133,7 @@ static AnalyzeSentiment() } ``` -The constructor contains initialization logic for the [`MLContext`](xref:Microsoft.ML.MLContext) and model so that it can be shared throughout the lifecycle of the function instance. This approach reduces having to load the model from disk each time the `Run` method is executed. +The constructor contains initialization logic for the [`MLContext`](xref:Microsoft.ML.MLContext) and model so that it can be shared throughout the lifecycle of the function instance. This approach reduces the need to load the model from disk each time the `Run` method executes. ## Use the model to make predictions From ef4c0d3452d1c9f9574693bece49fae028c71352 Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Wed, 24 Apr 2019 17:49:38 -0400 Subject: [PATCH 4/7] Added description of Run method --- ...e-model-serverless-azure-functions-ml-net.md | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index 4b98ec1014985..6d0b014052c85 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -122,6 +122,9 @@ static ITransformer _model; // Define model's DataViewSchema static DataViewSchema _modelSchema; +// Define PredictionEngine +static PredictionEngine _predictionEngine; + // AnalyzeSentiment class constructor static AnalyzeSentiment() { @@ -130,10 +133,13 @@ static AnalyzeSentiment() // Load Model _model = _mlContext.Model.Load("MLModels/sentiment_model.zip", out _modelSchema); + + // Create Prediction Engine + _predictionEngine = _mlContext.Model.CreatePredictionEngine(_model); } ``` -The constructor contains initialization logic for the [`MLContext`](xref:Microsoft.ML.MLContext) and model so that it can be shared throughout the lifecycle of the function instance. This approach reduces the need to load the model from disk each time the `Run` method executes. +The constructor contains initialization logic for the [`MLContext`](xref:Microsoft.ML.MLContext), model and [`PredictionEngine`](xref:Microsoft.ML.PredictionEngine%602) so that it can be shared throughout the lifecycle of the function instance. This approach reduces the need to load the model from disk each time the `Run` method executes. ## Use the model to make predictions @@ -149,12 +155,9 @@ ILogger log) //Parse HTTP Request Body string requestBody = await new StreamReader(req.Body).ReadToEndAsync(); SentimentData data = JsonConvert.DeserializeObject(requestBody); - - //Create Prediction Engine - PredictionEngine predictionEngine = _mlContext.Model.CreatePredictionEngine(_model); - + //Make Prediction - SentimentPrediction prediction = predictionEngine.Predict(data); + SentimentPrediction prediction = _predictionEngine.Predict(data); //Convert prediction to string string isToxic = Convert.ToBoolean(prediction.Prediction) ? "Toxic" : "Not Toxic"; @@ -164,6 +167,8 @@ ILogger log) } ``` +When the `Run` method executes, the incoming data from the HTTP request is deserialized and used as input for the [`PredictionEngine`](xref:Microsoft.ML.PredictionEngine%602). The [`Predict`](xref:Microsoft.ML.PredictionEngineBase%602.Predict*) method is then called to generate a prediction and return the result to the user. + ## Test Locally Now that everything is set up, it's time to test the application: From 04605936119503f38be7f5d54f182aceed6ba98b Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Mon, 29 Apr 2019 17:25:37 -0400 Subject: [PATCH 5/7] Updated based on feedback --- ...model-serverless-azure-functions-ml-net.md | 96 ++++++++++--------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index 6d0b014052c85..ec25917f19f53 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -1,16 +1,17 @@ --- title: "How-To: Deploy ML.NET machine learning model to Azure Functions" description: Serve ML.NET sentiment analysis machine learning model for prediction over the internet using Azure Functions -ms.date: 04/24/2019 +ms.date: 04/29/2019 author: luisquintanilla ms.author: luquinta -ms.custom: mvc,how-to +ms.topic: how-to +ms.custom: mvc #Customer intent: As a developer, I want to use my ML.NET Machine Learning model to make predictions through the internet using Azure Functions --- # How-To: Deploy ML.NET machine learning model to Azure Functions -Learn how to deploy a pre-trained ML.NET machine learning model for predictions over the internet through an Azure Functions serverless environment. +Learn how to deploy a pre-trained ML.NET machine learning model for predictions over HTTP through an Azure Functions serverless environment. ## Prerequisites @@ -19,6 +20,9 @@ Learn how to deploy a pre-trained ML.NET machine learning model for predictions - Powershell - Pre-trained model. - Use the [ML.NET Sentiment Analysis tutorial](../tutorials/sentiment-analysis.md) to build your own model. + + or + - Download this [pre-trained sentiment analysis machine learning model](https://github.com/dotnet/samples/blob/master/machine-learning/models/sentimentanalysis/sentiment_model.zip) ## Create Azure Functions Project @@ -50,19 +54,19 @@ Create a class to predict sentiment. Add a new class to your project: The *AnalyzeSentiment.cs* file opens in the code editor. Add the following `using` statement to the top of *GitHubIssueData.cs*: -```csharp -using System; -using System.IO; -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Azure.WebJobs; -using Microsoft.Azure.WebJobs.Extensions.Http; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.Logging; -using Newtonsoft.Json; -using Microsoft.ML; -using SentimentAnalysisFunctionsApp.DataModels; -``` + ```csharp + using System; + using System.IO; + using System.Threading.Tasks; + using Microsoft.AspNetCore.Mvc; + using Microsoft.Azure.WebJobs; + using Microsoft.Azure.WebJobs.Extensions.Http; + using Microsoft.AspNetCore.Http; + using Microsoft.Extensions.Logging; + using Newtonsoft.Json; + using Microsoft.ML; + using SentimentAnalysisFunctionsApp.DataModels; + ``` ## Create Data Models @@ -73,38 +77,38 @@ You need to create some classes for your input data and predictions. Add a new c 2. In Solution Explorer, right-click the *DataModels* directory, and then select **Add > New Item**. 3. In the **Add New Item** dialog box, select **Class** and change the **Name** field to *SentimentData.cs*. Then, select the **Add** button. The *SentimentData.cs* file opens in the code editor. Add the following using statement to the top of *SentimentData.cs*: -```csharp -using Microsoft.ML.Data; -``` + ```csharp + using Microsoft.ML.Data; + ``` Remove the existing class definition and add the following code to the *SentimentData.cs* file: - -```csharp -public class SentimentData -{ - [LoadColumn(0)] - public bool Label { get; set; } - [LoadColumn(1)] - public string Text { get; set; } -} -``` + + ```csharp + public class SentimentData + { + [LoadColumn(0)] + public bool Label { get; set; } + [LoadColumn(1)] + public string Text { get; set; } + } + ``` 4. In Solution Explorer, right-click the *DataModels* directory, and then select **Add > New Item**. 5. In the **Add New Item** dialog box, select **Class** and change the **Name** field to *SentimentPrediction.cs*. Then, select the **Add** button. The *SentimentPrediction.cs* file opens in the code editor. Add the following using statement to the top of *SentimentPrediction.cs*: -```csharp -using Microsoft.ML.Data; -``` + ```csharp + using Microsoft.ML.Data; + ``` -Remove the existing class definition and add the following code to the *SentimentPrediction.cs* file: + Remove the existing class definition and add the following code to the *SentimentPrediction.cs* file: -```csharp -public class SentimentPrediction : SentimentData -{ - [ColumnName("PredictedLabel")] - public bool Prediction { get; set; } -} -``` + ```csharp + public class SentimentPrediction : SentimentData + { + [ColumnName("PredictedLabel")] + public bool Prediction { get; set; } + } + ``` `SentimentPrediction` inherits from `SentimentData` which provides access to the original data in the `Text` property as well as the output generated by the model. @@ -176,15 +180,15 @@ Now that everything is set up, it's time to test the application: 1. Run the application 1. Open PowerShell and enter the code into the prompt where PORT is the port your application is running on. Typically the port is 7071. -```powershell -Invoke-RestMethod "http://localhost:/api/AnalyzeSentiment" -Method Post -Body (@{Text="This is a very rude movie"} | ConvertTo-Json) -ContentType "application/json" -``` + ```powershell + Invoke-RestMethod "http://localhost:/api/AnalyzeSentiment" -Method Post -Body (@{Text="This is a very rude movie"} | ConvertTo-Json) -ContentType "application/json" + ``` If successful, the output should look similar to the text below: -```powershell -Toxic -``` + ```powershell + Toxic + ``` Congratulations! You have successfully served your model to make predictions over the internet using an Azure Function. From ab007e940f1c724cde8c041f412009d92080c5f7 Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Mon, 29 Apr 2019 18:55:25 -0400 Subject: [PATCH 6/7] Minor formatting updates --- ...erve-model-serverless-azure-functions-ml-net.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index ec25917f19f53..b01fd94322821 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -18,7 +18,7 @@ Learn how to deploy a pre-trained ML.NET machine learning model for predictions - [Visual Studio 2017 15.6 or later](https://visualstudio.microsoft.com/downloads/?utm_medium=microsoft&utm_source=docs.microsoft.com&utm_campaign=inline+link&utm_content=download+vs2017) with the ".NET Core cross-platform development" workload and "Azure development" installed. - [Azure Functions Tools](/azure/azure-functions/functions-develop-vs#check-your-tools-version) - Powershell -- Pre-trained model. +- Pre-trained model - Use the [ML.NET Sentiment Analysis tutorial](../tutorials/sentiment-analysis.md) to build your own model. or @@ -81,7 +81,7 @@ You need to create some classes for your input data and predictions. Add a new c using Microsoft.ML.Data; ``` -Remove the existing class definition and add the following code to the *SentimentData.cs* file: + Remove the existing class definition and add the following code to the *SentimentData.cs* file: ```csharp public class SentimentData @@ -184,11 +184,11 @@ Now that everything is set up, it's time to test the application: Invoke-RestMethod "http://localhost:/api/AnalyzeSentiment" -Method Post -Body (@{Text="This is a very rude movie"} | ConvertTo-Json) -ContentType "application/json" ``` -If successful, the output should look similar to the text below: - - ```powershell - Toxic - ``` + If successful, the output should look similar to the text below: + + ```powershell + Toxic + ``` Congratulations! You have successfully served your model to make predictions over the internet using an Azure Function. From e5a8b49a10e7ec7b406ce13370ff9612872e070b Mon Sep 17 00:00:00 2001 From: Luis Quintanilla Date: Mon, 29 Apr 2019 19:06:52 -0400 Subject: [PATCH 7/7] Updated ms.topic --- .../serve-model-serverless-azure-functions-ml-net.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md index b01fd94322821..0f29f3157d63b 100644 --- a/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md +++ b/docs/machine-learning/how-to-guides/serve-model-serverless-azure-functions-ml-net.md @@ -4,8 +4,7 @@ description: Serve ML.NET sentiment analysis machine learning model for predicti ms.date: 04/29/2019 author: luisquintanilla ms.author: luquinta -ms.topic: how-to -ms.custom: mvc +ms.custom: mvc, how-to #Customer intent: As a developer, I want to use my ML.NET Machine Learning model to make predictions through the internet using Azure Functions ---