Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
---
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.custom: mvc,how-to
ms.date: 04/29/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 HTTP through an Azure Functions serverless environment.

## Prerequisites

- [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.
- Use the [ML.NET Sentiment Analysis tutorial](../tutorials/sentiment-analysis.md) to build your own model.
- Download this [pre-trained sentiment analysis machine learning model](https://github.com/dotnet/samples/blob/master/machine-learning/models/sentimentanalysis/sentiment_model.zip)
- 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

Expand Down Expand Up @@ -53,23 +53,21 @@ 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 Microsoft.ML.Core.Data;
using Microsoft.ML.Data;
using MLNETServerless.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
## Create Data Models

You need to create some classes for your input data and predictions. Add a new class to your project:

Expand All @@ -82,8 +80,8 @@ 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
{
Expand All @@ -104,42 +102,65 @@ You need to create some classes for your input data and predictions. Add a new c
Remove the existing class definition and add the following code to the *SentimentPrediction.cs* file:

```csharp
public class SentimentPrediction
public class SentimentPrediction : SentimentData
{
[ColumnName("PredictedLabel")]
public bool Prediction { get; set; }
}
```

### Add Prediction Logic
`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;

// Define PredictionEngine
static PredictionEngine<SentimentData, SentimentPrediction> _predictionEngine;

// AnalyzeSentiment class constructor
static AnalyzeSentiment()
{
// Create MLContext
_mlContext = new MLContext();

// Load Model
_model = _mlContext.Model.Load("MLModels/sentiment_model.zip", out _modelSchema);

// Create Prediction Engine
_predictionEngine = _mlContext.Model.CreatePredictionEngine<SentimentData, SentimentPrediction>(_model);
}
```

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

Replace the existing implementation of *Run* method in *AnalyzeSentiment* class with the following code:

```csharp
public static async Task<IActionResult> 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<SentimentData>(requestBody);

//Create Prediction Engine
PredictionEngine<SentimentData, SentimentPrediction> predictionEngine = model.CreatePredictionEngine<SentimentData, SentimentPrediction>(mlContext);


//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";
Expand All @@ -149,22 +170,24 @@ public static async Task<IActionResult> Run(
}
```

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:

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:<PORT>/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
Invoke-RestMethod "http://localhost:<PORT>/api/AnalyzeSentiment" -Method Post -Body (@{Text="This is a very rude movie"} | ConvertTo-Json) -ContentType "application/json"
```

```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.

Expand Down