教程:从预先训练的 TensorFlow 模型生成 ML.NET 图像分类模型Tutorial: Generate an ML.NET image classification model from a pre-trained TensorFlow model

了解如何将现有 TensorFlow 模型中的知识传输到新的 ML.NET 图像分类模型中。Learn how to transfer the knowledge from an existing TensorFlow model into a new ML.NET image classification model.

TensorFlow 模型经过训练,可以将图像分为一千个类别。The TensorFlow model was trained to classify images into a thousand categories. ML.NET 模型在其管道中使用 TensorFlow 模型的一部分来训练一个模型,以将图像分为 3 个类别。The ML.NET model makes use of part of the TensorFlow model in its pipeline to train a model to classify images into 3 categories.

从头开始定型图像分类模型需要设置数百万个参数、大量已标记的定型数据和海量计算资源(数百个 GPU 小时)。Training an Image Classification model from scratch requires setting millions of parameters, a ton of labeled training data and a vast amount of compute resources (hundreds of GPU hours). 虽然不如从头开始定型自定义模型有效,但借助迁移学习,可以通过处理数千张图像(与数百万张已标记的图像相比)来简化此过程,并非常快速地生成自定义模型(在没有 GPU 的计算机上一小时内完成)。While not as effective as training a custom model from scratch, transfer learning allows you to shortcut this process by working with thousands of images vs. millions of labeled images and build a customized model fairly quickly (within an hour on a machine without a GPU). 本教程进一步缩小了该过程,只使用十二个训练图像。This tutorial scales that process down even further, using only a dozen training images.

在本教程中,你将了解:In this tutorial, you learn how to:

  • 了解问题Understand the problem
  • 将经过预先训练的 TensorFlow 模型合并到 ML.NET 管道中Incorporate the pre-trained TensorFlow model into the ML.NET pipeline
  • 训练和评估 ML.NET 模型Train and evaluate the ML.NET model
  • 对测试图像进行分类Classify a test image

可以在 dotnet/samples 存储库中找到本教程的源代码。You can find the source code for this tutorial at the dotnet/samples repository. 请注意在本教程中,.NET 项目配置默认面向 .NET core 2.2。Note that by default, the .NET project configuration for this tutorial targets .NET core 2.2.

什么是迁移学习?What is transfer learning?

迁移学习是使用在解决一个问题时所获得的知识并将其应用于不同但相关的问题的过程。Transfer learning is the process of using knowledge gained while solving one problem and applying it to a different but related problem.

在本教程中,在可将图像分为 3 个类别的 ML.NET 模型中使用 TensorFlow 模型的一部分,该模型经过训练,可将图像分为一千个类别。For this tutorial, you use part of a TensorFlow model - trained to classify images into a thousand categories - in an ML.NET model that classifies images into 3 categories.

先决条件Prerequisites

选择正确的机器学习任务Select the right machine learning task

深度学习Deep learning

深度学习是机器学习的一部分,颠覆了计算机视觉和语音识别等领域。Deep learning is a subset of Machine Learning, which is revolutionizing areas like Computer Vision and Speech Recognition.

深度学习模型是使用包含多个学习层的大量已标记的数据神经网络来定型。Deep learning models are trained by using large sets of labeled data and neural networks that contain multiple learning layers. 深度学习:Deep learning:

  • 执行计算机视觉等一些任务的效果更好。Performs better on some tasks like Computer Vision.
  • 需要大量训练数据。Requires huge amounts of training data.

图像分类是常见的机器学习任务,可用于将图像自动分类为多个类别,例如:Image Classification is a common Machine Learning task that allows us to automatically classify images into categories such as:

  • 检测图像中是否有人脸。Detecting a human face in an image or not.
  • 检测是猫还是狗。Detecting cats vs. dogs.

或者在以下图像中,确定图像是食物、玩具还是家用电器:Or as in the following images, determining if an image is a(n) food, toy, or appliance:

披萨图像 泰迪熊图像 烤面包机图像pizza image teddy bear image toaster image

备注

上面的图像属于维基共享资源,并按如下方式进行属性化:The preceding images belong to Wikimedia Commons and are attributed as follows:

Inception model 经过训练,可将图像分类为一千个类别,但在本教程中,你只需要在更小的类别集中分类图像。The Inception model is trained to classify images into a thousand categories, but for this tutorial, you need to classify images in a smaller category set, and only those categories. 输入 transfer learningtransfer 部分。Enter the transfer part of transfer learning. 可以将 Inception model 的识别和分类图像功能迁移到自定义图像分类器的新受限类别。You can transfer the Inception model's ability to recognize and classify images to the new limited categories of your custom image classifier.

  • 食物Food
  • 玩具Toy
  • 家用电器Appliance

本教程使用 TensorFlow Inception 模型深入学习模型,该模型是在 ImageNet 数据集上经过训练的常用图像识别模型。This tutorial uses the TensorFlow Inception model deep learning model, a popular image recognition model trained on the ImageNet dataset. TensorFlow 模型将整个图像分为一千个类别,例如“伞”、“运动衫”和“洗碗机”。The TensorFlow model classifies entire images into a thousand classes, such as “Umbrella”, “Jersey”, and “Dishwasher”.

由于 Inception model 已预先在数千个不同图像上进行过训练,因此内部包含图像识别所需的图像特征Because the Inception model has already been pre trained on thousands of different images, internally it contains the image features needed for image identification. 可以在模型中使用这些内部图像特征,用更少的类训练一个新模型。We can make use of these internal image features in the model to train a new model with far fewer classes.

如下图中所示,在 .NET Core 或 .NET Framework 应用中添加对 ML.NET NuGet 包的引用。As shown in the following diagram, you add a reference to the ML.NET NuGet packages in your .NET Core or .NET Framework applications. 实际上,ML.NET 包括并引用本机 TensorFlow 库,可用于编写代码来加载已训练的现有 TensorFlow 模型文件。Under the covers, ML.NET includes and references the native TensorFlow library that allows you to write code that loads an existing trained TensorFlow model file.

TensorFlow 转换 ML.NET 体系结构图

多类分类Multiclass classification

使用 TensorFlow Inception 模型提取适合作为经典机器学习算法输入的特征后,我们添加了一个 ML.NET 多类分类器After using the TensorFlow inception model to extract features suitable as input for a classical machine learning algorithm, we add an ML.NET multi-class classifier.

此例中使用的特定训练者是多项式逻辑回归算法The specific trainer used in this case is the multinomial logistic regression algorithm.

此训练者实现的算法可以很好地处理大量特征存在的问题,这是深度学习模型对图像数据进行操作时遇到的情况。The algorithm implemented by this trainer performs well on problems with a large number of features, which is the case for a deep learning model operating on image data.

数据Data

数据源有两个:.tsv 文件和图像文件。There are two data sources: the .tsv file, and the image files. tags.tsv 文件包含两个列:第一列定义为 ImagePath,第二列是与图像对应的 LabelThe tags.tsv file contains two columns: the first one is defined as ImagePath and the second one is the Label corresponding to the image. 下面的示例文件没有标题行,如下所示:The following example file doesn't have a header row, and looks like this:

broccoli.jpg    food
pizza.jpg   food
pizza2.jpg  food
teddy2.jpg  toy
teddy3.jpg  toy
teddy4.jpg  toy
toaster.jpg appliance
toaster2.png    appliance

定型图像和测试图像位于下载 zip 文件的资产文件夹中。The training and testing images are located in the assets folders that you'll download in a zip file. 这些图像属于维基共享资源。These images belong to Wikimedia Commons.

维基共享资源,免费媒体存储库。 Wikimedia Commons, the free media repository. 检索时间:2018 年 10 月 17 日 10:48 检索位置: https://commons.wikimedia.org/wiki/Pizza https://commons.wikimedia.org/wiki/Toaster https://commons.wikimedia.org/wiki/Teddy_bearRetrieved 10:48, October 17, 2018 from: https://commons.wikimedia.org/wiki/Pizza https://commons.wikimedia.org/wiki/Toaster https://commons.wikimedia.org/wiki/Teddy_bear

安装Setup

创建项目Create a project

  1. 创建名为“TransferLearningTF”的 .NET Core 控制台应用程序Create a .NET Core Console Application called "TransferLearningTF".

  2. 安装“Microsoft.ML NuGet 包” :Install the Microsoft.ML NuGet Package:

    • 在“解决方案资源管理器”中,右键单击项目,然后选择“管理 NuGet 包” 。In Solution Explorer, right-click on your project and select Manage NuGet Packages.
    • 选择“nuget.org”作为“包源”,选择“浏览”选项卡,再搜索“Microsoft.ML” 。Choose "nuget.org" as the Package source, select the Browse tab, search for Microsoft.ML.
    • 单击“版本”下拉列表,选择列表中的“1.4.0”包,然后选择“安装”按钮 。Click on the Version drop-down, select the 1.4.0 package in the list, and select the Install button.
    • 选择“预览更改”对话框中的“确定”按钮 。Select the OK button on the Preview Changes dialog.
    • 如果同意所列包的许可条款,请选择“接受许可” 对话框中的“我接受” 按钮。Select the I Accept button on the License Acceptance dialog if you agree with the license terms for the packages listed.
    • 对“Microsoft.ML.ImageAnalytics v1.4.0”和“SciSharp.TensorFlow.Redist v1.15.0”、和“Microsoft.ML.TensorFlow v1.4.0”重复这些步骤 。Repeat these steps for Microsoft.ML.ImageAnalytics v1.4.0, SciSharp.TensorFlow.Redist v1.15.0 and Microsoft.ML.TensorFlow v1.4.0.

下载资产Download assets

  1. 下载并解压缩项目资产目录 zip 文件Download The project assets directory zip file, and unzip.

  2. 将“assets”目录复制到“TransferLearningTF” 项目目录中。Copy the assets directory into your TransferLearningTF project directory. 此目录及其子目录包含本教程所需的数据和支持文件(Inception 模型除外,将在下一步中下载并添加此模型)。This directory and its subdirectories contain the data and support files (except for the Inception model, which you'll download and add in the next step) needed for this tutorial.

  3. 下载并解压缩 Inception 模型Download the Inception model, and unzip.

  4. 将刚刚解压缩的“inception5h”目录的内容复制到 TransferLearningTF 项目的“assets/inception”目录中。Copy the contents of the inception5h directory just unzipped into your TransferLearningTF project assets/inception directory. 此目录包含本教程所需的模型和其他支持文件,如下图所示:This directory contains the model and additional support files needed for this tutorial, as shown in the following image:

    Inception 目录内容

  5. 在“解决方案资源管理器”中,右键单击资产目录和子目录中的每个文件,再选择“属性” 。In Solution Explorer, right-click each of the files in the asset directory and subdirectories and select Properties. 在“高级”下,将“复制到输出目录”的值更改为“如果较新则复制” 。Under Advanced, change the value of Copy to Output Directory to Copy if newer.

创建类和定义路径Create classes and define paths

  1. 将以下附加的 using 语句添加到“Program.cs” 文件顶部:Add the following additional using statements to the top of the Program.cs file:

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using Microsoft.ML;
    using Microsoft.ML.Data;
    
  2. 将以下代码添加到 Main 方法正上方的行中,以指定资产路径:Add the following code to the line right above the Main method to specify the asset paths:

    static readonly string _assetsPath = Path.Combine(Environment.CurrentDirectory, "assets");
    static readonly string _imagesFolder = Path.Combine(_assetsPath, "images");
    static readonly string _trainTagsTsv = Path.Combine(_imagesFolder, "tags.tsv");
    static readonly string _testTagsTsv = Path.Combine(_imagesFolder, "test-tags.tsv");
    static readonly string _predictSingleImage = Path.Combine(_imagesFolder, "toaster3.jpg");
    static readonly string _inceptionTensorFlowModel = Path.Combine(_assetsPath, "inception", "tensorflow_inception_graph.pb");
    
  3. 为输入数据和预测结果创建类。Create classes for your input data, and predictions.

    public class ImageData
    {
        [LoadColumn(0)]
        public string ImagePath;
    
        [LoadColumn(1)]
        public string Label;
    }
    

    ImageData 是输入图像数据类,包含以下 String 字段:ImageData is the input image data class and has the following String fields:

    • ImagePath 包含图像文件名。ImagePath contains the image file name.
    • Label 包含图像标签值。Label contains a value for the image label.
  4. 向项目添加 ImagePrediction 的新类:Add a new class to your project for ImagePrediction:

    public class ImagePrediction : ImageData
    {
        public float[] Score;
    
        public string PredictedLabelValue;
    }
    

    ImagePrediction 是图像预测类,包含以下字段:ImagePrediction is the image prediction class and has the following fields:

    • Score 包含给定图像分类的置信度百分比。Score contains the confidence percentage for a given image classification.
    • PredictedLabelValue 包含预测出的图像分类标签的值。PredictedLabelValue contains a value for the predicted image classification label.

    ImagePrediction 是在定型模型后用于预测的类。ImagePrediction is the class used for prediction after the model has been trained. 它包含图像路径的 string (ImagePath)。It has a string (ImagePath) for the image path. Label 用于重用和训练模型。The Label is used to reuse and train the model. PredictedLabelValue 在预测和评估过程中使用。The PredictedLabelValue is used during prediction and evaluation. 对于计算,将使用带定型数据的输入、预测值和模型。For evaluation, an input with training data, the predicted values, and the model are used.

在 Main 中初始化变量Initialize variables in Main

  1. 使用 MLContext 的新实例初始化 mlContext 变量。Initialize the mlContext variable with a new instance of MLContext. 用下面 Main 方法中的代码替换 Console.WriteLine("Hello World!") 行:Replace the Console.WriteLine("Hello World!") line with the following code in the Main method:

    MLContext mlContext = new MLContext();
    

    执行所有 ML.NET 操作都是从 MLContext 类开始,初始化 mlContext 可创建一个新的 ML.NET 环境,可在模型创建工作流对象之间共享该环境。The MLContext class is a starting point for all ML.NET operations, and initializing mlContext creates a new ML.NET environment that can be shared across the model creation workflow objects. 从概念上讲,它与实体框架中的 DBContext 类似。It's similar, conceptually, to DBContext in Entity Framework.

为 Inception 模型参数创建结构Create a struct for Inception model parameters

  1. Inception 模型具有多个需要传入的参数。The Inception model has several parameters you need to pass in. 紧跟在 Main() 方法后面,使用以下代码创建结构,以将参数值映射到易记名称:Create a struct to map the parameter values to friendly names with the following code, just after the Main() method:

    private struct InceptionSettings
    {
        public const int ImageHeight = 224;
        public const int ImageWidth = 224;
        public const float Mean = 117;
        public const float Scale = 1;
        public const bool ChannelsLast = true;
    }
    

创建显示实用工具方法Create a display utility method

由于将多次显示图像数据和相关预测,请创建显示实用工具方法,用于处理图像和预测结果的显示。Since you'll display the image data and the related predictions more than once, create a display utility method to handle displaying the image and prediction results.

  1. 紧跟在 InceptionSettings 结构后面,使用下面的代码创建 DisplayResults() 方法:Create the DisplayResults() method, just after the InceptionSettings struct, using the following code:

    private static void DisplayResults(IEnumerable<ImagePrediction> imagePredictionData)
    {
    
    }
    
  2. 填充 DisplayResults 方法的主体:Fill in the body of the DisplayResults method:

    foreach (ImagePrediction prediction in imagePredictionData)
    {
        Console.WriteLine($"Image: {Path.GetFileName(prediction.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score.Max()} ");
    }
    

创建 .tsv 文件实用工具方法Create a .tsv file utility method

  1. 使用下面的代码紧随 DisplayResults() 方法后创建 ReadFromTsv() 方法:Create the ReadFromTsv() method, just after the DisplayResults() method, using the following code:

    public static IEnumerable<ImageData> ReadFromTsv(string file, string folder)
    {
    
    }
    
  2. 填充 ReadFromTsv 方法的主体:Fill in the body of the ReadFromTsv method:

    return File.ReadAllLines(file)
     .Select(line => line.Split('\t'))
     .Select(line => new ImageData()
     {
         ImagePath = Path.Combine(folder, line[0])
     });
    

    代码分析整个 tags.tsv 文件,以将文件路径添加到 ImagePath 属性的图像文件名中,并将它和 Label 加载到 ImageData 对象中。The code parses through the tags.tsv file to add the file path to the image file name for the ImagePath property and load it and the Label into an ImageData object.

创建用于进行预测的方法Create a method to make a prediction

  1. 使用下面的代码在 DisplayResults() 方法前创建 ClassifySingleImage() 方法:Create the ClassifySingleImage() method, just before the DisplayResults() method, using the following code:

    public static void ClassifySingleImage(MLContext mlContext, ITransformer model)
    {
    
    }
    
  2. 创建 ImageData 对象,其中包含单个 ImagePath 的完全限定路径和图像文件名。Create an ImageData object that contains the fully qualified path and image file name for the single ImagePath. 将以下代码添加为 ClassifySingleImage() 方法的接下来几行:Add the following code as the next lines in the ClassifySingleImage() method:

    var imageData = new ImageData()
    {
        ImagePath = _predictSingleImage
    };
    
  3. 通过添加以下代码作为 ClassifySingleImage 方法中的下一行,进行单一预测:Make a single prediction, by adding the following code as the next line in the ClassifySingleImage method:

    // Make prediction function (input = ImageData, output = ImagePrediction)
    var predictor = mlContext.Model.CreatePredictionEngine<ImageData, ImagePrediction>(model);
    var prediction = predictor.Predict(imageData);
    

    若要获得预测,请使用 Predict() 方法。To get the prediction, use the Predict() method. PredictionEngine 是一个简便 API,可使用它对单个数据实例执行预测。The PredictionEngine is a convenience API, which allows you to perform a prediction on a single instance of data. PredictionEngine 不是线程安全型。PredictionEngine is not thread-safe. 可以在单线程环境或原型环境中使用。It's acceptable to use in single-threaded or prototype environments. 为了在生产环境中提高性能和线程安全,请使用 PredictionEnginePool 服务,这将创建一个在整个应用程序中使用的 PredictionEngine 对象的 ObjectPoolFor improved performance and thread safety in production environments, use the PredictionEnginePool service, which creates an ObjectPool of PredictionEngine objects for use throughout your application. 请参阅本指南,了解如何在 ASP.NET Core Web API 中使用 PredictionEnginePoolSee this guide on how to use PredictionEnginePool in an ASP.NET Core Web API.

    备注

    PredictionEnginePool 服务扩展目前处于预览状态。PredictionEnginePool service extension is currently in preview.

  4. ClassifySingleImage() 方法的下一行代码用于显示预测结果:Display the prediction result as the next line of code in the ClassifySingleImage() method:

    Console.WriteLine($"Image: {Path.GetFileName(imageData.ImagePath)} predicted as: {prediction.PredictedLabelValue} with score: {prediction.Score.Max()} ");
    

构造 ML.NET 模型管道Construct the ML.NET model pipeline

ML.NET 模型管道是一个估算器链。An ML.NET model pipeline is a chain of estimators. 请注意,管道构造过程中不会发生任何执行。Note that no execution happens during pipeline construction. 估算器对象已创建,但不会执行。The estimator objects are created but not executed.

  1. 添加生成模型的方法Add a method to generate the model

    此方法是教程的核心。This method is the heart of the tutorial. 它为模型创建管道,并训练管道以生成 ML.NET 模型。It creates a pipeline for the model, and trains the pipeline to produce the ML.NET model. 它还针对某些以前看不到的测试数据评估模型。It also evaluates the model against some previously unseen test data.

    紧跟在 InceptionSettings 结构后面且恰好在 DisplayResults() 方法前面,使用以下代码创建 GenerateModel() 方法:Create the GenerateModel() method, just after the InceptionSettings struct and just before the DisplayResults() method, using the following code:

    public static ITransformer GenerateModel(MLContext mlContext)
    {
    
    }
    
  2. 添加估算器以从图像数据加载、调整和提取像素:Add the estimators to load, resize and extract the pixels from the image data:

    IEstimator<ITransformer> pipeline = mlContext.Transforms.LoadImages(outputColumnName: "input", imageFolder: _imagesFolder, inputColumnName: nameof(ImageData.ImagePath))
                    // The image transforms transform the images into the model's expected format.
                    .Append(mlContext.Transforms.ResizeImages(outputColumnName: "input", imageWidth: InceptionSettings.ImageWidth, imageHeight: InceptionSettings.ImageHeight, inputColumnName: "input"))
                    .Append(mlContext.Transforms.ExtractPixels(outputColumnName: "input", interleavePixelColors: InceptionSettings.ChannelsLast, offsetImage: InceptionSettings.Mean))
    

    图像数据需要处理成 TensorFlow 模型所需的格式。The image data needs to be processed into the format that the TensorFlow model expects. 在本例中,图像将加载到内存中,将其调整为一致大小,并将像素提取成一个数值矢量。In this case, the images are loaded into memory, resized to a consistent size, and the pixels are extracted into a numeric vector.

  3. 添加估算器以加载 TensorFlow 模型并进行评分:Add the estimator to load the TensorFlow model, and score it:

    .Append(mlContext.Model.LoadTensorFlowModel(_inceptionTensorFlowModel).
        ScoreTensorFlowModel(outputColumnNames: new[] { "softmax2_pre_activation" }, inputColumnNames: new[] { "input" }, addBatchDimensionInput: true))
    

    管道中的此阶段将 TensorFlow 模型加载到内存中,然后通过 TensorFlow 模型网络处理像素值的矢量。This stage in the pipeline loads the TensorFlow model into memory, then processes the vector of pixel values through the TensorFlow model network. 将输入应用于深度学习模型并使用该模型生成输出的过程称为评分Applying inputs to a deep learning model, and generating an output using the model, is referred to as Scoring. 当作为一个整体使用模型时,评分将做出推理或预测。When using the model in its entirety, scoring makes an inference, or prediction.

    在本例中,将使用除最后一层(这是进行推理的层)之外的全部 TensorFlow 模型。In this case, you use all of the TensorFlow model except the last layer, which is the layer that makes the inference. 倒数第二层的输出标有 softmax_2_preactivationThe output of the penultimate layer is labeled softmax_2_preactivation. 此层的输出实际上是特征矢量,用于描述原始输入图像的特征。The output of this layer is effectively a vector of features that characterize the original input images.

    TensorFlow 模型生成的此特征矢量将用作 ML.NET 训练算法的输入。This feature vector generated by the TensorFlow model will be used as input to an ML.NET training algorithm.

  4. 添加估算器以将训练数据中的字符串标签映射到整数键值:Add the estimator to map the string labels in the training data to integer key values:

    .Append(mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelKey", inputColumnName: "Label"))
    

    接下来追加的 ML.NET 训练者要求其标签采用 key 格式,而不是任意字符串。The ML.NET trainer that is appended next requires its labels to be in key format rather than arbitrary strings. 键是一个数字,一对一映射到字符串值。A key is a number that has a one to one mapping to a string value.

  5. 添加 ML.NET 训练算法:Add the ML.NET training algorithm:

    .Append(mlContext.MulticlassClassification.Trainers.LbfgsMaximumEntropy(labelColumnName: "LabelKey", featureColumnName: "softmax2_pre_activation"))
    
  6. 添加估算器以将预测的键值映射回字符串:Add the estimator to map the predicted key value back into a string:

    .Append(mlContext.Transforms.Conversion.MapKeyToValue("PredictedLabelValue", "PredictedLabel"))
    .AppendCacheCheckpoint(mlContext);
    

定型模型Train the model

  1. 使用 LoadFromTextFile 包装器加载训练数据。Load the training data using the LoadFromTextFile wrapper. 将以下代码作为下一行添加到 GenerateModel() 方法中:Add the following code as the next line in the GenerateModel() method:

    IDataView trainingData = mlContext.Data.LoadFromTextFile<ImageData>(path:  _trainTagsTsv, hasHeader: false);
    

    ML.NET 中的数据表示为 IDataView 类Data in ML.NET is represented as an IDataView class. IDataView 是用于描述表格数据(数字和文本)的一种灵活且有效的方法。IDataView is a flexible, efficient way of describing tabular data (numeric and text). 可从文本文件或实时(例如,SQL 数据库或日志文件)将数据加载到 IDataView 对象。Data can be loaded from a text file or in real time (for example, SQL database or log files) to an IDataView object.

  2. 用上面加载的数据训练模型:Train the model with the data loaded above:

    ITransformer model = pipeline.Fit(trainingData);
    

    Fit() 方法通过将训练数据集应用于管道来训练模型。The Fit() method trains your model by applying the training dataset to the pipeline.

评估模型的准确性Evaluate the accuracy of the model

  1. 通过将以下代码添加到 GenerateModel 方法的下一行,加载并转换测试数据:Load and transform the test data, by adding the following code to the next line of the GenerateModel method:

    IDataView testData = mlContext.Data.LoadFromTextFile<ImageData>(path: _testTagsTsv, hasHeader: false);
    IDataView predictions = model.Transform(testData);
    
    // Create an IEnumerable for the predictions for displaying results
    IEnumerable<ImagePrediction> imagePredictionData = mlContext.Data.CreateEnumerable<ImagePrediction>(predictions, true);
    DisplayResults(imagePredictionData);
    

    可以使用几个示例图像来评估模型。There are a few sample images that you can use to evaluate the model. 与训练数据类似,需要将这些数据加载到 IDataView 中,以便模型可以对其进行转换。Like the training data, these need to be loaded into an IDataView, so that they can be transformed by the model.

  2. 若要评估模型,请将以下代码添加到 GenerateModel() 方法:Add the following code to the GenerateModel() method to evaluate the model:

    MulticlassClassificationMetrics metrics =
        mlContext.MulticlassClassification.Evaluate(predictions,
          labelColumnName: "LabelKey",
          predictedLabelColumnName: "PredictedLabel");
    

    在你设置预测后,Evaluate() 方法便能:Once you have the prediction set, the Evaluate() method:

    • 评估模型(将预测的值与测试数据集 labels 进行比较)。Assesses the model (compares the predicted values with the test dataset labels).
    • 返回模型性能指标。Returns the model performance metrics.
  3. 显示模型准确性指标Display the model accuracy metrics

    使用下面的代码显示指标、共享结果,然后处理它们:Use the following code to display the metrics, share the results, and then act on them:

    Console.WriteLine($"LogLoss is: {metrics.LogLoss}");
    Console.WriteLine($"PerClassLogLoss is: {String.Join(" , ", metrics.PerClassLogLoss.Select(c => c.ToString()))}");
    

    下面是图像分类评估指标:The following metrics are evaluated for image classification:

    • Log-loss - 请参阅对数损失Log-loss - see Log Loss. 通常会希望对数损失尽可能接近 0。You want Log-loss to be as close to zero as possible.
    • Per class Log-lossPer class Log-loss. 建议每类别的对数损失尽可能接近 0。You want per class Log-loss to be as close to zero as possible.
  4. 添加以下代码,将经过训练的模型作为下一行代码返回:Add the following code to return the trained model as the next line:

    return model;
    

运行应用程序!Run the application!

  1. 创建 MLContext 类后,添加对 Main 方法中 GenerateModel 的调用:Add the call to GenerateModel in the Main method after the creation of the MLContext class:

    ITransformer model = GenerateModel(mlContext);
    
  2. 将对 ClassifySingleImage() 方法的调用添加为 Main 方法的下一行代码:Add the call to the ClassifySingleImage() method as the next line of code in the Main method:

    ClassifySingleImage(mlContext, model);
    
  3. 运行控制台应用 (Ctrl + F5)。Run your console app (Ctrl + F5). 结果应如以下输出所示。Your results should be similar to the following output. 你可能会看到警告或处理消息,为清楚起见,这些消息已从以下结果中删除。You may see warnings or processing messages, but these messages have been removed from the following results for clarity.

    =============== Training classification model ===============
    Image: broccoli2.jpg predicted as: food with score: 0.8955513
    Image: pizza3.jpg predicted as: food with score: 0.9667718
    Image: teddy6.jpg predicted as: toy with score: 0.9797683
    =============== Classification metrics ===============
    LogLoss is: 0.0653774699265059
    PerClassLogLoss is: 0.110315812569315 , 0.0204391272836966 , 0
    =============== Making single image classification ===============
    Image: toaster3.jpg predicted as: appliance with score: 0.9646884
    

祝贺你!Congratulations! 现在,通过在 ML.NET 中对 TensorFlow 模型应用迁移学习,已成功生成了用于图像分类的机器学习模型。You've now successfully built a machine learning model for image classification by applying transfer learning to a TensorFlow model in ML.NET.

可以在 dotnet/samples 存储库中找到本教程的源代码。You can find the source code for this tutorial at the dotnet/samples repository.

在本教程中,你将了解:In this tutorial, you learned how to:

  • 了解问题Understand the problem
  • 将经过预先训练的 TensorFlow 模型合并到 ML.NET 管道中Incorporate the pre-trained TensorFlow model into the ML.NET pipeline
  • 训练和评估 ML.NET 模型Train and evaluate the ML.NET model
  • 对测试图像进行分类Classify a test image

请查看机器学习示例 GitHub 存储库,以探索扩展的图像分类示例。Check out the Machine Learning samples GitHub repository to explore an expanded image classification sample.