I added a demo using ML.Net in a Github.
The demo is available in this repository :
https://github.com/toreaurstadboss/ImageClassificationMLNetBlazorDemo
A screenshot shows the application running below :
ML.Net is Microsoft's machine learning library. It is combined with tooling inside VS 2022 an easy way to locally use machine learning models on your CPU or GPU, or hosted in Azure cloud services.
The website for ML.Net is available here for more information about ML.Net and documentation:
https://dotnet.microsoft.com/en-us/apps/ai/ml-dotnet
In the demo above I have trained the model to recognize either
horses or
mooses. These species are both mammals and herbivores and somewhat are similar in appearance. I have trained the machine learning model in this demo only with ten images of each category, then again with ten other test images that checks if the model recognizes correctly if we see a horse or a moose.
Already with just ten images, it did not miss once, and of course a better example for a real world machine learning model would have scoured over tens of thousand of images to handle all edge cases.
ML.Net is very easy to run, it can be run locally on your own machine, using the CPU or GPU. The GPU must be CUDA compatible. That actually means you need a NVIDIA card with 8-series. I got such a card on a laptop of mine and have tested it.
The following links points to download pages of NVIDIA for downloading the necessary software as of March 2025 to run ML.Net image classification functionality on GPUs :
Download Cuda 10.1
Cuda 10.1 can be downloaded from here:
https://developer.nvidia.com/cuda-10.1-download-archive-base
CuDnn 7.6.4
CuDnn can be downloaded from here:
https://developer.nvidia.com/rdp/cudnn-archive
Getting started with image classification using ML.Net
It is easiest to use VS 2022 to add a ML.Net machine learning model.
Inside VS 2022, right click your project and choose
Add and choose
Machine Learning Model
In case you do not see this option, hit the start menu and type in
Visual Studio installer
Now, hit the button
Modify for your VS installation. Choose
Individual Components
Search for 'ml'. Select the
ML.NET Model Builder. There are also a package called
ML.NET Model Builder 2022, I also chose that.
Choosing the scenario
Now, after adding the
Machine Learning model, the first page asks for a scenario. I choose
Image Classification here, below
Computer Vision scenario category.
Choosing the environment
Then I hit the button
Local.
In the next step, I select
Local (CPU).
Note that I have tested also Nvidia Cuda-compatible graphics card / GPU on another laptop and it also worked great and should be preferred if you have a GPU compatible and have installed Cuda 10.1 and Cdnn 7.6.4 as shown in links above.
Hit the button
Next Step.
Choosing the Data
It is time to train the machine learning model with data !
I have gathered ten sample images of mooses and horses each. By pointing to a folder with images where each category of images are gathered in subfolders of this folder.
Next step is
Train
Training the model
Here you can hit the button
Train again. When you have trained enough here the model, you can hit the button
Next step
.
Training the machine learning will take some time depending on you using CPU or GPU and the number of input images here.
Usually it takes a few seconds, but not many minutes to churn through a couple of images as shown here, 20 images in total.
Loading up the image data and using the machine learning model
Note that ML.Net demands support to
renderinteractive rendering of web apps, pure Blazor WASM apps are not supported.
The following file shows how the Blazor serverside app is set up.
Program.cs
using ImageClassificationMLNetBlazorDemo.Components;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddRazorComponents()
.AddInteractiveServerComponents();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (!app.Environment.IsDevelopment())
{
app.UseExceptionHandler("/Error", createScopeForErrors: true);
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAntiforgery();
app.MapRazorComponents<App>()
.AddInteractiveServerRenderMode();
app.Run();
InteractiveServer is set up inside the
App.razor using the
HeadOutlet.
App.razor
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<base href="/" />
<link rel="stylesheet" href="app.css" />
<link rel="stylesheet" href="lib/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="ImageClassificationMLNetBlazorDemo.styles.css" />
<link rel="icon" type="image/png" href="favicon.png" />
<HeadOutlet @rendermode="InteractiveServer" />
</head>
<body>
<Routes @rendermode="InteractiveServer" />
<script src="_framework/blazor.web.js"></script>
</body>
</html>
The following codebehind of the razor component
Home.razor in the demo repo shows how a file uploaded using the
InputFile control in
Blazor serverside.
Home.razor.cs
@code {
private string? _base64ImageSource = null;
private string? _predictedLabel = "No classification";
private IOrderedEnumerable<KeyValuePair<string, float>>? _predictedLabels = null;
private int? _assessedPredictionQuality = null;
private string? _errorMessage = null;
private async Task LoadFileAsync(InputFileChangeEventArgs e)
{
try
{
ResetPrivateFields();
if (e.File.Size <= 0 || e.File.Size >= 2 * 1024 * 1024)
{
_errorMessage = "Sorry, the uploaded image but be between 1 byte and 2 MB!";
return;
}
byte[] imageBytes = await GetImageBytes(e.File);
_base64ImageSource = GetBase64ImageSourceString(e.File.ContentType, imageBytes);
PredictImageClassification(imageBytes);
}
catch (Exception err)
{
Console.WriteLine(err);
}
}
private void ResetPrivateFields()
{
_base64ImageSource = null;
_predictedLabel = null;
_predictedLabels = null;
_assessedPredictionQuality = null;
}
private int GetAssesPrediction()
{
int result = 1;
if (_predictedLabel != null && _predictedLabels != null)
{
foreach (var label in _predictedLabels)
{
if (label.Key == _predictedLabel)
{
result = label.Value switch
{
<= 0.50f => 1,
<= 0.70f => 2,
<= 0.80f => 3,
<= 0.85f => 4,
<= 0.90f => 5,
<= 1.0f => 6,
_ => 1 //default to dice we get some other score here..
};
}
}
}
return result;
}
private void PredictImageClassification(byte[] imageBytes)
{
var input = new ModelInput
{
ImageSource = imageBytes
};
ModelOutput output = HorseOrMooseImageClassifier.Predict(input);
_predictedLabel = output.PredictedLabel;
_predictedLabels = HorseOrMooseImageClassifier.PredictAllLabels(input);
_assessedPredictionQuality = GetAssesPrediction(); //check how good the prediction is, give a score from 1-6 (dice score!)
StateHasChanged();
}
private async Task<byte[]> GetImageBytes(IBrowserFile file)
{
using MemoryStream memoryStream = new();
var stream = file.OpenReadStream(2 * 1024 * 1024, CancellationToken.None);
await stream.CopyToAsync(memoryStream);
return memoryStream.ToArray();
}
private string GetBase64ImageSourceString(string contentType, byte[] bytes)
{
string preAmble = $"data:{contentType};base64,";
return $"{preAmble}{(Convert.ToBase64String(bytes))}";
}
}
As the code shows above, using the machine learning model is quite convenient, we just use the methods
Predict to get the
Label that is decided exists in the loaded image. This is the
image classiciation that the machine learning found. Note that using the method
PredictAllLabels get the confidence of the different labels show in this demo.
There are no limitations on the number of categories here in the image classification labels that one could train a model to look after.
A benefit with ML.Net is the option to use it on-premise servers and get fairly good result on just a few sample images. But the more sample images you obtain for a label, the more precise the machine learning model will become. It is possible to download a pre-trained model such as
Inceptionv3 that is compatible with
Tensorflow used here that supports up to 1000 categories.
More information is available here from Microsoft about using a pre-trained model such as InceptionV3:
https://learn.microsoft.com/en-us/dotnet/machine-learning/tutorials/image-classification