Microsoft AI - Custom Vision in C#
概述
前面一篇 Microsoft AI - Custom Vision 中,我们介绍了 Azure 认知服务中的自定义影像服务:Custom Vision,也介绍了如果通过这个在线服务,可视化的完成项目创建、数据集上传和标注、模型训练、模型评估和测试。我们也提到,除了可以使用可视化在线操作的方式,Custom Vision 也提供了 SDK 来完成整个机器学习过程,两种语言供选择:C# 和 Python,今天我们针对 C# 版本来做一次实际开发操作。
开发过程
准备工作
C# Custom Vision SDK 在 GitHub 开源:Microsoft/Cognitive-CustomVision-Windows,这个 SDK 主要分为两部分:Prediction 和 Training,如果不想下载 SourceCode 自己去编译,也可以直接在 VS 中通过 Package Management 安装这两部分的 Nuget package:
- Microsoft.Cognitive.CustomVision.Prediction Install-Package Microsoft.Cognitive.CustomVision.Prediction -Version 1.2.0
- Microsoft.Cognitive.CustomVision.Training Install-Package Microsoft.Cognitive.CustomVision.Training -Version 1.2.0

实际开发
接下来我们创建一个 WPF 工程来实际操作整个 Custom Vision SDK 使用过程:
1. 通过 Nuget Package Management 的安装方式,安装 Prediction 和 Training 两个包,地址如上面准备工作中所示;来看一下包里的 namespace 组成:

除此之外,还需要安装 Microsoft.Rest.ClientRuntime 的 Nuget,因为 Custom Vision SDK 依赖于它,地址:Install-Package Microsoft.Rest.ClientRuntime -Version 2.3.11
2. Nuget 包安装完成后,在代码中引入以下 Namespace:
using Microsoft.Cognitive.CustomVision.Training; using Microsoft.Cognitive.CustomVision.Prediction; using Microsoft.Cognitive.CustomVision.Training.Models;
3. 创建一个 Custom Vision Project:
其中 ApiKey 需要替换为开发者在 CustomVision.ai 网站获取的 Training Key;另外 CreateProject 创建时,名字是必填的,描述和域都是选填的;域的类型是 GUID,我翻看了 SDK Doc 和源代码,没有发现对域的 GUID 取值的任何描述,后来在 CustomVision.ai 通过网页调试方法找到了 Domains 字段对应的 GUID,在这里也分享给大家;来看一下代码实现和实现的结果吧:
TrainingApi trainingApi = new TrainingApi() { ApiKey = "replace with your api key" };
Project demoProject = trainingApi.CreateProject(
"CsharpDemoProject01",
"It's description of our demo project.",
new System.Guid("0732100f-1a38-4e49-a514-c9b44c697ab5"));
| 项目类型 | GUID |
| General | ee85a74c-405e-4adc-bb47-ffa8ca0c9f31 |
| Food | c151d5b5-dd07-472a-acc8-15d29dea8518 |
| Landmarks | ca455789-012d-4b50-9fec-5bb63841c793 |
| Retail | b30a91ae-e3c1-4f73-a81e-c270bff27c39 |
| Adult | 45badf75-3591-4f26-a705-45678d3e9f5f |
| General(compact) | 0732100f-1a38-4e49-a514-c9b44c697ab5 |
| Landmarks(compact) | b5cfd229-2ac7-4b2b-8d0a-2b0661344894 |
| Retail(compact) | 6b4faeda-8396-481b-9f8b-177b9fa3097f |

4. 给项目的训练数据集添加标签:
示例中我们添加了两个标签 airplane 和 alarmclock
// create two tags in our demo project var airplaneTag = trainingApi.CreateTag(demoProject.Id, "airplane"); var alarmclockTag = trainingApi.CreateTag(demoProject.Id, "alarmclock");
5. 上传图片数据集到项目中:
我们在项目 Assets 文件夹存放了两个分类,每个分类各五张图片,示例代码如下:
string[] images = new string[] { "001.jpg", "002.jpg", "003.jpg", "004.jpg", "005.jpg"};
foreach (var image in images)
{
var storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appx:///Assets/airplane/{0}", image), UriKind.RelativeOrAbsolute));
using (var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
trainingApi.CreateImagesFromData(demoProject.Id, stream.AsStream(), new List<string>() { airplaneTag.Id.ToString() });
}
}
foreach (var image in images)
{
var storageFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appx:///Assets/alarmclock/{0}", image), UriKind.RelativeOrAbsolute));
using (var stream = await storageFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
trainingApi.CreateImagesFromData(demoProject.Id, stream.AsStream(), new List<string>() { alarmclockTag.Id.ToString() });
}
}
验证一下我们添加的标签和数据集

6. 数据集准备完毕,开始训练模型
var iteration = trainingApi.TrainProject(demoProject.Id);
while (iteration.Status == "Training")
{
iteration = trainingApi.GetIteration(demoProject.Id, iteration.Id);
}
iteration.IsDefault = true;
trainingApi.UpdateIteration(demoProject.Id, iteration.Id, iteration);
训练完成后,我们看看训练结果

7. 模型训练完毕,开始做模型验证
ApiKey 替换为你在 Custom Vision 对应的 Prediction Key,我们使用了一张 airplane 的图片作为测试输入,看看代码和结果:
PredictionEndpoint endpoint = new PredictionEndpoint() { ApiKey = "replace with your prediction key" };
var testFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri(string.Format("ms-appx:///Assets/airplane.jpg", ""), UriKind.RelativeOrAbsolute));
using (var testStream = await testFile.OpenAsync(Windows.Storage.FileAccessMode.Read))
{
var result = endpoint.PredictImage(demoProject.Id, testStream.AsStream());
}
可以看到,airplane 的概率为 0.98,alarmclock 为 0.01;这个结果符合我们对模型的预期。

总结
到这里就完成了 Custom Vision C# 的实现过程,因为只是简单 Demo 演示,所以训练数据集只取了 10 张图片,只是简单的把代码的实现过程讲解了一下。大家如果感兴趣,可以结合这个基本过程,把上传标签和图片的过程做的更加易交互,比如选取文件夹批量上传和管理等;模型训练的过程也可以再细化,通过代码返回结果监控训练的结果;模型测试也可以把测试结果更直观的反映出来,或者批量处理测试数据,更丰富的展示和管理测试结果,评估数据模型。
非常欢迎大家和我交流 Custom Vision 和 Azure 认知服务相关的技术问题,谢谢大家!
Microsoft AI - Custom Vision in C#的更多相关文章
- Microsoft AI - Custom Vision
概述 前几天的 Windows Developer Day 正式发布了 Windows AI Platform,而作为 Windows AI Platform 的模型定义和训练,更多还是需要借助云端来 ...
- 1小时快速搭建基于Azure Custom Vision和树莓派的鸟类分类和识别应用
1. 引言 最近在微软Learn平台学习Azure认知服务相关的内容,看到了一个有关"使用自定义视觉对濒危鸟类进行分类"的专题,该专题的主要内容就是使用 Azure Custom ...
- Add AI feature to Xamarin.Forms app
Now, AI is one of important technologies.Almost all platforms have API sets of AI. Following list is ...
- AI应用开发实战
AI应用开发实战 出发点 目前,人工智能在语音.文字.图像的识别与解析领域带来了跨越式的发展,各种框架.算法如雨后春笋一般,互联网上随处可见与机器学习有关的学习资源,各大mooc平台.博客.公开课都推 ...
- Modernizing Business Process with Cloud and AI
The world is awash with digital transformation. Every customer and partner that I talk to, across ev ...
- dynamics 365 AI 解决方案 —— 介绍
Digital transformation has been reshaping our world and artificial intelligence (AI) is one of the n ...
- Microsoft Hackathon 2019 留念
参加今年微软的 Hackathon 是 2019 年 7 月份的事情,但是后来各种各样的事情,考托.考G.网申……就给耽搁了.我本来以为自己的记忆力足够好,几个月以后也能写很多东西,然鹅……现在发现好 ...
- Microsoft 机器学习产品体系对比和介绍
Microsoft 提供多种多样的产品选项用于生成.部署和管理机器学习模型. 本文将比较这些产品,并帮助你选择所需的产品,以便最有效地开发机器学习解决方案. 机器学习产品 描述 作用 Azure云端服 ...
- MS Batch AI
微软的Batch AI服务是一项新服务,它可以帮助你在GPU pool上训练和测试机器学习模型,包括深度学习模型.它简化了在当前许多流行的深度学习框架(如TensorFlow.Microsoft认知工 ...
随机推荐
- Web渗透测试(sql注入 access,mssql,mysql,oracle,)
Access数据库注入: access数据库由微软发布的关系型数据库(小型的),安全性差. access数据库后缀名位*.mdb, asp中连接字符串应用-- "Driver={micros ...
- Linux(二)命令
Linux命令一.命令基本格式 命令行头部显示字符意义 [root@localhost ~] # root 用户名 localhost 主机名 ~ 当前目录 ~表示home目录 # 用户权限,#表示超 ...
- Access denied for user(这个几乎让我怀疑人生的异常)
昨天一时兴起,打算根据自己的某些想法,业余时间写一个简单的项目,用以巩固那些重要的知识,以及练手一些即将学习的技术. 然而才一开始,便有一盆冷水迎面而来,在搭建整个框架环境的时候竟然就被卡住了!主要是 ...
- 云摘录︱Word2Vec 作者Tomas Mikolov 的三篇代表作解析
本文来源于公众号paperweekly 谈到了word2vec作者的三篇论文: 1.Efficient Estimation of Word Representation in Vector Spac ...
- 笔记︱金融风险控制基础常识——巴塞尔协议+信用评分卡Fico信用分
每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 本笔记源于CDA-DSC课程,由常国珍老师主讲 ...
- R语言︱list用法、批量读取、写出数据时的用法
列表是一种特别的对象集合,它的元素也由序号(下标)区分,但是各元素的类型可 以是任意对象,不同元素不必是同一类型.元素本身允许是其它复杂数据类型,比如,列表 的一个元素也允许是列表.例如: > ...
- const char *p;和char * const p的区别
const char *p; const修饰*p,所以*p是一个常量,不可修改. char* const p; const修饰p,所以指针p是一个常量,不可修改. #include< ...
- 多线程下不重复读取SQL Server 表的数据
在进行一些如发送短信.邮件的业务时,我们经常会使用一个表来存储待发送的数据,由后台多个线程不断的从表中读取待发送的数据进行发送,发送完成后再将数据转移到历史表中,这样保证待发送表的数据一般情况下不会太 ...
- TortoiseSVN设置忽略文件和目录文件夹
TortoiseSVN设置忽略文件和目录文件夹 在多数项目中你总会有文件和目录不需要进行版本控制.这可能包括一些由编译器生成的文件,*.obj,*.lst,或许是一个用于存放可执行程序的输出文件夹. ...
- R语言实现二分查找法
二分查找时间复杂度O(h)=O(log2n),具备非常高的效率,用R处理数据时有时候需要用到二分查找法以便快速定位 Rbisect <- function(lst, value){ low=1 ...