ML.NET 示例:图像分类模型训练-首选API(基于原生TensorFlow迁移学习)

ML.NET 版本API 类型状态应用程序类型数据类型场景机器学习任务算法
Microsoft.ML 1.5.0动态API最新控制台应用程序和Web应用程序图片文件图像分类基于迁移学习的TensorFlow模型再训练进行图像分类DNN架构:ResNet、InceptionV3、MobileNet等

问题

图像分类是深度学习学科中的一个常见问题。此示例演示如何通过基于迁移学习方法训练模型来创建您自己的自定义图像分类器,该方法基本上是重新训练预先训练的模型(如InceptionV3或ResNet架构),这样您就可以在自己的图像上训练自定义模型。

在这个示例应用程序中,您可以创建自己的自定义图像分类器模型,方法是使用自己的图像从ML.NET API本机训练TensorFlow模型。

图像分类器场景–使用ML.NET训练您自己的定制深度学习模型

数据集(图像集)

图像集许可证

此示例的数据集基于Tensorflow提供的“flower_photosimageset”,下载地址。此存档中的所有图像均获得Creative Commons By Attribution许可证的许可,网址为:https://creativecommons.org/licenses/by/2.0/

完整的许可证信息在license.txt文件中提供,该文件包含在作为.zip文件下载的同一图像集中。

默认情况下,示例下载的imageset有200个图像,平均分布在5个flower类中:

Images --> flower_photos_small_set -->|daisy|dandelion|roses|sunflowers|tulips

每个子文件夹的名称很重要,因为它将是模型用于分类图像的每个类/标签的名称。

机器学习任务-图像分类

为了解决这个问题,我们首先要建立一个ML模型。然后我们将在现有数据上训练模型,评估它有多好,最后我们将使用模型对新图像进行分类。


1. 将项目配置为使用GPU或CPU

默认情况下,此解决方案使用CPU进行训练和评分。但是,如果您的机器有一个兼容的GPU可用(基本上大多数NVIDIA GPU显卡),您可以配置该项目使用GPU。

:警告:请确保使用下面列出的NuGet包的正确版本。其他版本可能与Nvidia CUDA v10.0不兼容

使用CPU进行训练或推断/评分

当使用CPU时,您的项目必须引用以下redist库:

  • SciSharp.TensorFlow.Redist (1.15.0) (CPU training)

使用CPU的训练项目中的示例参考屏幕截图:


使用GPU进行训练或推断/评分

使用GPU时,项目必须引用以下redist库(并删除CPU版本引用):

  • SciSharp.TensorFlow.Redist-Windows-GPU (1.14.0) (GPU training on Windows)

  • SciSharp.TensorFlow.Redist-Linux-GPU (1.14.0) (GPU training on Linux)

使用GPU的训练项目中的示例参考屏幕截图:


2. 构建模型

构建模型包括以下步骤:

  • 将图像文件(本例中为文件路径)加载到IDataView中

  • 使用ImageClassification评估器进行图像分类(高级API)

定义数据架构,并在从files文件夹加载图像时引用该类型。

public class ImageData
{public ImageData(string imagePath, string label){ImagePath = imagePath;Label = label;}public readonly string ImagePath;public readonly string Label;
}

由于API使用内存图像,因此稍后您可以使用内存图像对模型进行评分,因此需要定义一个包含“byte[]image”类型中图像位的类,如下所示:

public class InMemoryImageData
{public InMemoryImageData(byte[] image, string label, string imageFileName){Image = image;Label = label;ImageFileName = imageFileName;}public readonly byte[] Image;public readonly string Label;public readonly string ImageFileName;
}

使用LoadImagesFromDirectory()和LoadFromEnumerable()下载imageset并加载其信息。

// 1. Download the image set and unzip
string finalImagesFolderName = DownloadImageSet(imagesDownloadFolderPath);
string fullImagesetFolderPath = Path.Combine(imagesDownloadFolderPath, finalImagesFolderName);var mlContext = new MLContext(seed: 1);// 2. Load the initial full image-set into an IDataView and shuffle so it'll be better balanced
IEnumerable<ImageData> images = LoadImagesFromDirectory(folder: fullImagesetFolderPath, useFolderNameAsLabel: true);
IDataView fullImagesDataset = mlContext.Data.LoadFromEnumerable(images);
IDataView shuffledFullImageFilePathsDataset = mlContext.Data.ShuffleRows(fullImagesDataset);

将数据加载到IDataView后,将对这些行进行混洗,以便在拆分为训练/测试数据集之前更好地平衡数据集。。

下一步非常重要。因为我们希望ML模型能够处理内存中的图像,所以我们需要将图像加载到数据集中,并通过调用fit()和ttransform()来实现。需要在初始且分离的管道中执行此步骤,以便在训练时,管道和模型不会使用文件路径来创建。

// 3. Load Images with in-memory type within the IDataView and Transform Labels to Keys (Categorical)
IDataView shuffledFullImagesDataset = mlContext.Transforms.Conversion.MapValueToKey(outputColumnName: "LabelAsKey", inputColumnName: "Label", keyOrdinality: KeyOrdinality.ByValue).Append(mlContext.Transforms.LoadRawImageBytes(outputColumnName: "Image",imageFolder: fullImagesetFolderPath,inputColumnName: "ImagePath")).Fit(shuffledFullImageFilePathsDataset).Transform(shuffledFullImageFilePathsDataset);

此外,在分割数据集之前,我们还将标签转换为键(分类)。如果您不想在第二个管道(训练管道)中转换标签时处理/匹配KeyOrdinality,那么在拆分之前执行此操作也很重要。

现在,让我们将数据集分成两个数据集,一个用于训练,另一个用于测试/验证模型的质量。

// 4. Split the data 80:20 into train and test sets, train and evaluate.
var trainTestData = mlContext.Data.TrainTestSplit(shuffledFullImagesDataset, testFraction: 0.2);
IDataView trainDataView = trainTestData.TrainSet;
IDataView testDataView = trainTestData.TestSet;

作为最重要的步骤,您可以定义模型的训练管道,在这里您可以看到如何轻松地训练一个新的TensorFlow模型,该模型基于默认体系结构(预先训练的模型)的迁移学习,例如Resnet V2 500

// 5. Define the model's training pipeline using DNN default values
//
var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(featureColumnName: "Image",labelColumnName: "LabelAsKey",validationSet: testDataView).Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumnName: "PredictedLabel",inputColumnName: "PredictedLabel"));

上面代码中的重要一行是使用mlContext.MulticlassClassification.Trainers.ImageClassification分类训练器的行,正如您所看到的,这是一个高级API,您只需要提供哪个列包含图像,带有标签的列(要预测的列)和用于在训练时计算质量度量的验证数据集,以便模型在训练时可以自我调整(更改内部超参数)。

在本质上,此模型训练基于从默认体系结构(预先训练的模型)学习的本地TensorFlow DNN迁移,例如Resnet V2 50。还可以通过配置可选的超参数来选择要从中派生的超参数。

就这么简单,您甚至不需要进行图像变换(调整大小、规格化等)。根据所使用的DNN架构,该框架在幕后进行所需的图像转换,因此您只需使用单个API即可。

可选使用高级超参数

高级用户还有另一种重载方法,您还可以指定可选的超参数,例如epoch,batchSize,learningRate,特定的DNN架构,例如Inception v3或者Resnet v2101和其他典型的DNN参数,但大多数用户都可以从简化的API开始。

以下是如何使用高级DNN参数:

// 5.1 (OPTIONAL) Define the model's training pipeline by using explicit hyper-parametersvar options = new ImageClassificationTrainer.Options()
{FeatureColumnName = "Image",LabelColumnName = "LabelAsKey",// Just by changing/selecting InceptionV3/MobilenetV2/ResnetV250// you can try a different DNN architecture (TensorFlow pre-trained model).Arch = ImageClassificationTrainer.Architecture.MobilenetV2,Epoch = 50,       //100BatchSize = 10,LearningRate = 0.01f,MetricsCallback = (metrics) => Console.WriteLine(metrics),ValidationSet = testDataView
};var pipeline = mlContext.MulticlassClassification.Trainers.ImageClassification(options).Append(mlContext.Transforms.Conversion.MapKeyToValue(outputColumnName: "PredictedLabel",inputColumnName: "PredictedLabel"));

3. 训练模型

为了开始训练过程,您需要在构建的管道上运行Fit

// 4. Train/create the ML model
ITransformer trainedModel = pipeline.Fit(trainDataView);

4. 评估模型

训练完成后,利用测试数据集对模型进行质量评价。

Evaluate函数需要一个IDataView,其中包含通过调用Transform()从测试数据集生成的预测。

// 5. Get the quality metrics (accuracy, etc.)
IDataView predictionsDataView = trainedModel.Transform(testDataset);var metrics = mlContext.MulticlassClassification.Evaluate(predictionsDataView, labelColumnName:"LabelAsKey", predictedLabelColumnName: "PredictedLabel");
ConsoleHelper.PrintMultiClassClassificationMetrics("TensorFlow DNN Transfer Learning", metrics);

最后,保存模型:

// Save the model to assets/outputs (You get ML.NET .zip model file and TensorFlow .pb model file)
mlContext.Model.Save(trainedModel, trainDataView.Schema, outputMlNetModelFilePath);

运行项目来训练模型

您应该按照以下步骤来训练您的模型:

  1. 在Visual Studio中将ImageClassification.Train设置为启动项目

  2. 在Visual Studio中按F5。几秒钟后,该过程将完成并保存一个新的ML.NET模型到文件assets/outputs/imageClassifier.zip

5. “终端用户”应用中的使用模型

GPU与CPU对模型的使用/评分对比

在使用/评分模型时,您也可以在CPU/GPU之间进行选择,但是,如果使用GPU,您还需要确保运行模型的计算机/服务器支持GPU。

设置评分/使用项目以使用GPU的方法与本readme.md开头所述的方法相同,只需使用一个或另一个redist库。

用于评分的示例控制台应用程序

在示例的解决方案中,还有第二个项目名为ImageClassifcation.Predict。这个控制台应用程序只需加载您定制的ML.NET模型,并以假设的最终用户应用程序的方式执行一些样本预测。

首先要做的是将生成的assets/outputs/imageClassifier.zip文件复制/粘贴到使用项目的inputs/MLNETModel文件夹中。

关于代码,您首先需要加载在模型训练应用执行期间创建的模型。

MLContext mlContext = new MLContext(seed: 1);
ITransformer loadedModel = mlContext.Model.Load(imageClassifierModelZipFilePath, out var modelInputSchema);

然后,您可以创建一个预测器引擎对象,并最终使用文件夹assets/inputs/images-for-predictions的第一个图像进行一些样本预测,其中只有一些图像在训练模型时没有使用。

请注意,在评分时,只需要具有内存图像的InMemoryImageData类型。

该图像也可以通过任何其他通道传输,而不是从文件中加载。例如,这个解决方案中的ImageClassification.WebApp通过HTTP获取将要用于预测的图像。

var predictionEngine = mlContext.Model.CreatePredictionEngine<InMemoryImageData, ImagePrediction>(loadedModel);//Predict the first image in the folder
IEnumerable<InMemoryImageData> imagesToPredict = LoadInMemoryImagesFromDirectory(imagesFolderPathForPredictions, false);InMemoryImageData imageToPredict = new InMemoryImageData
{Image = imagesToPredict.First().Image,ImageFileName = imagesToPredict.First().ImageFileName
};var prediction = predictionEngine.Predict(imageToPredict);// Get the highest score and its index
float maxScore = prediction.Score.Max();Console.WriteLine($"Image Filename : [{imageToPredict.ImageFileName}], " +$"Predicted Label : [{prediction.PredictedLabel}], " +$"Probability : [{maxScore}] ");

预测引擎接收InMemoryImageData类型的对象作为参数(包含2个属性:ImageImageFileName)。该模型不使用ImageFileName。您只需将它放在这里,以便在显示预测时可以将文件名打印出来。预测仅使用byte[] Image字段中的图像位。

然后,模型返回类型为ImagePrediction的对象,该对象包含所有图像类/类型的PredictedLabel和所有Scores

由于PredictedLabel已经是一个字符串,因此它将显示在控制台中。关于预测标签的分数,我们只需要取最高的分数,即预测标签的概率。

运行“最终用户应用程序”项目以尝试预测

您应该按照以下步骤来使用您的模型:

  1. 在Visual Studio中将“ImageClassification.Predict”设置为启动项目

  2. 在Visual Studio中按F5。几秒钟后,该过程将通过加载并使用自定义的imageClassifier.zip 模型来显示预测。

用于评分/推断的ASP.NET Core web应用示例

在示例的解决方案中,还有另一个名为ImageClassification.WebApp的项目,它是一个ASP.NET Core web应用程序,允许用户通过HTTP提交图像,并使用内存中的图像进行评分/预测。

此示例还使用了PredictionEnginePool,建议用于多线程和可扩展的应用程序。

您可以在下面看到该应用的屏幕截图:


TensorFlow DNN迁移学习背景信息

这个示例应用程序正在重新训练用于图像分类的TensorFlow模型。您可能认为它与另一个示例非常相似 Image classifier using the TensorFlow Estimator featurizer。不过,内部的实现方式却有很大的不同。在上述示例中,它使用的是“模型合成方法”,其中初始TensorFlow模型(即InceptionV3或ResNet)仅用于对图像进行特征化,并生成每个图像的二进制信息,以供添加在顶部的另一个ML.NET分类器训练器使用(例如LbfgsMaximumEntropy)。因此,即使该示例使用的是TensorFlow模型,您也只能使用ML.NET trainer进行训练,您不会重新训练新的TensorFlow模型,而是训练ML.NET模型。这就是为什么该示例的输出只是一个ML.NET模型(.zip文件)。

与此相反,本例在本地基于迁移学习方法对新的TensorFlow模型进行重新训练,再从指定的预训练模型(Inception V3或ResNet)派生的新TensorFlow模型进行了训练。

重要的区别在于,这种方法使用TensorFlowAPI进行内部再训练,并创建一个新的TensorFlow模型(.pb)。然后,您使用的ML.NET.zip文件模型就像是新的重新训练的TensorFlow模型的包装器。这就是为什么您还可以看到训练后生成的新.pb文件的原因:


在下面的屏幕截图中,您可以看到如何在Netron中看到重新训练的TensorFlow模型(custom_retrained_model_based_on_InceptionV3.meta.pb),因为它是本机TensorFlow模型:

好处:

  • 使用GPU进行训练和推断:当使用基于TensorFlow的本机DNN方法时,您可以使用CPU或GPU(如果可用)来获得更好的性能(减少训练和评分所需的时间)。

  • 跨多个框架和平台重用:由于您本机训练了Tensorflow模型,除了能够使用ML.NET 'wrapper'模型(.zip文件)运行/使用该模型之外,您还可以使用.pb Tensorflow冻结模型并在任何其他框架(如Python/Keras/Tensorflow)上运行它,或者Java/Android应用程序或任何支持TensorFlow的框架。

  • 灵活性和性能:由于ML.NET是在Tensorflow层上进行内部再训练的,因此ML.NET团队将能够进一步优化并采取多种方法,如在最后一层上进行训练或跨Tensorflow模型在多个层上进行训练,并获得更好的质量水平。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/302740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

算法证明:女生遇到心动的男人一定要追!

全世界有3.14 % 的人已经关注了数据与算法之美我来讲恋爱中的博弈&#xff0c;不&#xff0c;我来讲恋爱中的算法&#xff0c;不&#xff0c;我来讲算法&#xff01;&#xff01;有个著名的问题&#xff0c;叫做 stable matching。早年是一个可爱的俄罗斯老头在图论课上教我的&…

记一次 .NET 某教育系统 异常崩溃分析

一&#xff1a;背景 1. 讲故事这篇文章起源于 搬砖队大佬 的精彩文章 WinDBg定位asp.net mvc项目异常崩溃源码位置 &#xff0c;写的非常好&#xff0c;不过美中不足的是通览全文之后&#xff0c;总觉得有那么一点不过瘾&#xff0c;就是没有把当时抛异常前的参数给找出来。。。…

Json.Net系列教程 3.Json.Net序列化和反序列化设置

上节补充首先补充一点,Json.Net是支持序列化和反序列化DataTable,DataSet,Entity Framework和NHibernate的.我举例说明DataTable的序列化和反序列化.创建一个DataTable对象,如下: DataTable dt new DataTable();DataColumn dcName new DataColumn("Name");DataColu…

5道谷歌面试题:即使是天才也要怀疑自己能力了(附答案)

全世界只有3.14 % 的人关注了数据与算法之美谷歌&#xff0c;美国的跨国科技企业&#xff0c;致力于互联网搜索、云计算、广告技术等领域&#xff0c;开发并提供大量基于互联网的产品与服务。这样一家实力雄厚前景无量的公司是众多求职者梦寐以求的地方&#xff0c;然而&#x…

[Abp vNext 源码分析] - 18. 单元测试

简介ABP vNext 框架使用 xUnit 作为单元测试组件&#xff0c;官方的所有模块都编写了大量的 单元/集成测试 确保功能正常。由于 ABP vNext 模块化系统的原因&#xff0c;开发人员在建立单元测试项目的时候需要集成 Volo.Abp.UnitTest 项目&#xff0c;这样在执行单元测试的时候…

php表格单元格怎么实现排序,javascript实现对表格元素进行排序操作

我们在上网中都能看到很多能够排序的&#xff0c;如大小、时间、价格等现在我们也试一下排序功能&#xff1a;排序的函数代码&#xff1a;里面含有点击之后排序--还原&#xff0c;和排升序和降序。function sortAge(){//对年龄进行排序&#xff0c;要先进行获得每一行对象&…

【10.29周一电商,已好】中国日历的至高境界,377张震撼级插画,美到爆!

每段时光都有属于每段时光的回忆它们是童年的纸飞机是校园时代的试卷与课本是第一次离开家乡时的兴奋与忐忑是跟某个人眼神交汇时的慌乱...回忆如此珍贵&#xff0c;以致于令我们频频回想&#xff0c;渴望着回到过去&#xff0c;与美好再度相逢。还记得文先生给大家推荐过的新一…

设置润乾报表鼠标移到格子上就显示提示内容

为了达到一定的交互性和易用性,我们一般喜欢将鼠标移动到格子上就能显示出一定的提示信息,比方说这个格子大小固定了但是里面内容超出格子了,这样我们希望鼠标移动过去后能自动提示所有的内容。用润乾报表可以这样设计&#xff1a; 比方说一个格子里面有如下内容 “这是一个很长…

ASP.NET Core 单元测试:如何Mock Url.Page()

点击上方蓝字关注“汪宇杰博客”导语在 ASP.NET Core 中&#xff0c;当你在 UrlHelperExtensions 类上使用扩展方法时&#xff0c;很难在单元测试中编写Mock。因为Moq框架不支持模拟扩展方法。问题例如&#xff0c;我的博客代码中使用了 Url.Page() 方法&#xff1a;var callba…

“甜橙金融杯”数据建模大赛发布,8万重金寻找大数据金融人才!

全世界有3.14 % 的人已经关注了数据与算法之美随着互联网概念不断发展&#xff0c;越来越多的商家进入这一市场。为了在竞争中拉取新用户&#xff0c;培养用户的消费习惯&#xff0c;各种类型的营销和补贴活动层出不穷。为正常用户带来福利的同时&#xff0c;也催生了一批“羊毛…

常用加解密工具集合|视频图片加解密方案

最近工作需要做视频加密解密&#xff0c;大概需求就是摄像头录制好的视频实时加密存储到本地&#xff0c;防止别人拔掉存储卡把视频拷贝走。大胆设想一下&#xff0c;假如现在很多网约车车内都有摄像头&#xff0c;这些对着乘客和司机的车内摄像头都是实时录制视频并存储到本地…

修炼九阴真经Windows Phone开发 (7):本地化应用程序栏Localizing an Application Bar 下...

本节介绍另一个本地化的方法&#xff1a; 在项目中添加资源文件&#xff1a;&#xff08;这个文件将包含应用程序的默认语言的资源&#xff09; 将要名称和值添加进去。&#xff08;作为应用程序中向用户显示字符串值&#xff09;. 重复上面的方法&#xff0c;向项目中添加更多…

统治世界的十大算法

全世界有3.14 % 的人已经关注了数据与算法之美软件正在统治世界。而软件的核心则是算法。算法千千万万&#xff0c;又有哪些算法属于“皇冠上的珍珠”呢&#xff1f;Marcos Otero 给出了他的看法。什么是算法&#xff1f;通俗而言&#xff0c;算法是一个定义明确的计算过程&…

Hosting in .NET Core

在.NET Core中&#xff0c;Host负责应用程序的启动和生命周期管理。除此之外&#xff0c;在Host中还可以设置日志(Logging)、配置(Configuration)和依赖关系注入(Dependency Injection)等。Host将一个常规的控制台应用程序(Console Application)变成了一个可以长时间运行的服务…

如何用大数据找女朋友?

全世界有3.14 % 的人已经关注了数据与算法之美导读找女朋友不仅需要好眼力&#xff0c;还需要一些技术含量。比如眼下正热的大数据&#xff0c;可以认真钻研&#xff0c;用数据分析来实现自己的“脱单计划”。小猿25岁&#xff0c;单身男&#xff0c;热衷大数据&#xff0c;并决…

ASP.NET Core 单元测试:如何 Mock HttpContext.Features.Get()

点击上方蓝字关注“汪宇杰博客”导语在 ASP.NET Core 里&#xff0c;如果你想单元测试 HttpContext.Features.Get<SomeType>()&#xff0c;这个技巧一定不要错过。问题我有个 Error 页面&#xff0c;需要取得异常的详细信息。我使用 HttpContext.Features.Get<IExcept…

mini api

大部分主流语言都支持web框架&#xff0c;并且实现起来相对轻便&#xff0c;简捷&#xff0c;比如&#xff1a;go的gin包package main import "github.com/gin-gonic/gin" func main() {r : gin.Default()r.GET("/ping", func(c *gin.Context) {c.JSON(200…

edge robert matlab,哪位熟悉matlab的大神路过瞄一眼哈

cxfx(believe truth believe me)UID240430帖子100精华积分1755蛋蛋币1755 枚威望0BT积分0阅读权限60性别男在线时间125 小时注册时间2013-3-27鸵鸟蛋主楼大中小发表于 2013-5-13 21:30 只看该作者哪位熟悉matlab的大神路过瞄一眼哈求大神指点迷津那&#xff01;谁来帮着看一下这…

php 图片 3d旋转图片,html5实现图片的3D旋转效果

我们先来看一下实现效果&#xff1a;(学习视频分享&#xff1a;html视频教程)H5旋转3D相册&#xff0c;鼠标放置暂停&#xff0c;图片灰度级为0&#xff0c;有放大效果。该实例运用H5和CSS3动画效果&#xff0c;未用javascript。提高了本人对CSS3 新属性的了解及掌握。完整代码…

数据这么多,且看R语言怎么处理!

随着科技的不断进步&#xff0c;数据处理量的不断增大&#xff0c;对数据进行处理、分析、统计建模、数据挖掘以及可视化的重要性日渐突出。如果说有一门简单易学、通俗易懂并且集上述功能为一体的编程语言让科研人员从中解脱出来&#xff0c;R语言当仁不让。作为一种统计分析软…