ONNX Runtime简介

ONNX Runtime 是一个跨平台的推理和训练机器学习加速器。ONNX 运行时推理可以实现更快的客户体验和更低的成本,支持来自深度学习框架(如 PyTorch 和 TensorFlow/Keras)以及经典机器学习库(如 scikit-learn、LightGBM、XGBoost 等)的模型。 ONNX 运行时与不同的硬件、驱动程序和操作系统兼容,并通过利用硬件加速器(如果适用)以及图形优化和转换来提供最佳性能。

ResNet50v2简介

ResNet50v2 是一种深度卷积神经网络架构,是 ResNet(Residual Network,残差网络)系列的一部分。ResNet 是由何凯明等人在 2015 年提出的,它通过引入残差块(Residual Block)解决了深度神经网络训练过程中梯度消失和梯度爆炸的问题,使得构建非常深的网络成为可能。ResNet50v2 被广泛应用于各种计算机视觉任务,如图像分类、目标检测、图像分割等。由于其深度和强大的特征学习能力,ResNet50v2 在众多基准测试中表现出色,是许多研究和应用中的首选模型之一。

示例

这个示例代码在

https://github.com/microsoft/onnxruntime/tree/main/csharp/sample/Microsoft.ML.OnnxRuntime.ResNet50v2Sample

fork一份,克隆到本地,在本地打开这个项目,项目结构如下所示:

依赖的包除了OnnxRuntime还有ImageSharp。

ImageSharp简介

ImageSharp 是一个新的、功能齐全、完全托管的跨平台 2D 图形库。ImageSharp 旨在简化图像处理,为您带来一个非常强大而又非常简单的 API。

ImageSharp 从头开始设计,具有灵活性和可扩展性。该库为常见的图像处理操作提供了 API 端点,并为开发其他操作提供了构建块。

ImageSharp 针对 .NET 8 构建,可用于设备、云和嵌入式/IoT 方案。

下载 ResNet50 v2 ONNX 模型,下载地址在:

https://github.com/onnx/models/blob/main/validated/vision/classification/resnet/model/resnet50-v2-7.onnx

读取路径

首先,源代码中是通过程序参数读取模型的路径和要测试的图像的路径,也可以直接赋值:

// Read paths
//string modelFilePath = args[0];
//string imageFilePath = args[1];
string modelFilePath = @"你的路径\Microsoft.ML.OnnxRuntime.ResNet50v2Sample\resnet50-v2-7.onnx";
string imageFilePath = @"你的路径\Microsoft.ML.OnnxRuntime.ResNet50v2Sample\狮子.jpg";

读取图像

接下来,我们将使用跨平台图像库 ImageSharp 读取图像:

 // Read image
using Image<Rgb24> image = Image.Load<Rgb24>(imageFilePath);

调整图像大小

接下来,我们将图像大小调整为模型期望的适当大小;224 像素 x 224 像素:

using Stream imageStream = new MemoryStream();
image.Mutate(x =>
{
x.Resize(new ResizeOptions
{
Size = new Size(224, 224),
Mode = ResizeMode.Crop
});
});
image.Save(imageStream, format);

预处理图像

接下来,我们将根据模型的要求对图像进行预处理,具体要求见:

https://github.com/onnx/models/tree/main/validated/vision/classification/resnet#preprocessing

// We use DenseTensor for multi-dimensional access to populate the image data
var mean = new[] { 0.485f, 0.456f, 0.406f };
var stddev = new[] { 0.229f, 0.224f, 0.225f };
DenseTensor<float> processedImage = new(new[] { 1, 3, 224, 224 });
image.ProcessPixelRows(accessor =>
{
for (int y = 0; y < accessor.Height; y++)
{
Span<Rgb24> pixelSpan = accessor.GetRowSpan(y);
for (int x = 0; x < accessor.Width; x++)
{
processedImage[0, 0, y, x] = ((pixelSpan[x].R / 255f) - mean[0]) / stddev[0];
processedImage[0, 1, y, x] = ((pixelSpan[x].G / 255f) - mean[1]) / stddev[1];
processedImage[0, 2, y, x] = ((pixelSpan[x].B / 255f) - mean[2]) / stddev[2];
}
}
});

在这里,我们正在创建一个所需大小 (batch-size, channels, height, width) 的张量,访问像素值,对其进行预处理,最后将它们分配给适当指示的张量。

设置输入

接下来,我们将创建模型的输入:

using var inputOrtValue = OrtValue.CreateTensorValueFromMemory(OrtMemoryInfo.DefaultInstance,
processedImage.Buffer, new long[] { 1, 3, 224, 224 }); var inputs = new Dictionary<string, OrtValue>
{
{ "data", inputOrtValue }
}

要检查 ONNX 模型的输入节点名称,您可以使用 Netron 可视化模型并查看输入/输出名称。在本例中,此模型具有 data 作为输入节点名称。

运行推理

接下来,我们将创建一个推理会话并通过它运行输入:

using var session = new InferenceSession(modelFilePath);
using var runOptions = new RunOptions();
using IDisposableReadOnlyCollection<OrtValue> results = session.Run(runOptions, inputs, session.OutputNames);

后处理输出

接下来,我们需要对输出进行后处理以获得 softmax 向量,因为这不是由模型本身处理的:

var output = results[0].GetTensorDataAsSpan<float>().ToArray();
float sum = output.Sum(x => (float)Math.Exp(x));
IEnumerable<float> softmax = output.Select(x => (float)Math.Exp(x) / sum);

其他型号可能会在输出之前应用 Softmax 节点,在这种情况下,您不需要此步骤。同样,您可以使用 Netron 查看模型输出。

提取前10个预测结果

IEnumerable<Prediction> top10 = softmax.Select((x, i) => new Prediction { Label = LabelMap.Labels[i], Confidence = x })
.OrderByDescending(x => x.Confidence)
.Take(10);

打印结果

Console.WriteLine("Top 10 predictions for ResNet50 v2...");
Console.WriteLine("--------------------------------------------------------------");
foreach (var t in top10)
{
Console.WriteLine($"Label: {t.Label}, Confidence: {t.Confidence}");
}

本例的示例图片是一只狮子,如下所示:

查看预测结果:

在LabelMap类中可以查看该模型可以识别的物体:

例如cock是公鸡的意思,我们可以现场找一张公鸡的图片,查看效果。

找到的一张公鸡图片如下所示:

修改测试图片为这种图片,再次运行,结果如下所示:

成功识别出了公鸡。

总结

以上就完成了ONNX Runtime的入门示例,可以根据兴趣与需求尝试使用其他的模型。

参考

1、Image recognition with ResNet50v2 in C# | onnxruntime

2、models/validated/vision/classification/resnet/model/resnet50-v2-7.onnx at main · onnx/models (github.com)

3、microsoft/onnxruntime: ONNX Runtime: cross-platform, high performance ML inferencing and training accelerator (github.com)

4、SixLabors/ImageSharp: A modern, cross-platform, 2D Graphics library for .NET (github.com)

ONNX Runtime入门示例:在C#中使用ResNet50v2进行图像识别的更多相关文章

  1. Optimum + ONNX Runtime: 更容易、更快地训练你的 Hugging Face 模型

    介绍 基于语言.视觉和语音的 Transformer 模型越来越大,以支持终端用户复杂的多模态用例.增加模型大小直接影响训练这些模型所需的资源,并随着模型大小的增加而扩展它们.Hugging Face ...

  2. [WCF编程]1.WCF入门示例

    一.WCF是什么? Windows Communication Foundation(WCF)是由微软开发的一系列支持数据通信的应用程序框架,整合了原有的windows通讯的 .net Remotin ...

  3. Spring MVC 入门示例讲解

    在本例中,我们将使用Spring MVC框架构建一个入门级web应用程序.Spring MVC 是Spring框架最重要的的模块之一.它以强大的Spring IoC容器为基础,并充分利用容器的特性来简 ...

  4. Linq to NHibernate入门示例

    Linq to NHibernate入门示例 NHibernate相关: 09-08-25连贯NHibernate正式发布1.0候选版 09-08-17NHibernate中一对一关联的延迟加载 09 ...

  5. Spring MVC 入门示例讲解 - howtodoinjava

    在本例中,我们将使用Spring MVC框架构建一个入门级web应用程序.Spring MVC 是Spring框架最重要的的模块之一.它以强大的Spring IoC容器为基础,并充分利用容器的特性来简 ...

  6. 微软推出了Cloud Native Application Bundles和开源ONNX Runtime

    微软的Microsoft Connect(); 2018年的开发者大会 对Azure和IoT Edge服务进行了大量更新; Windows Presentation Foundation,Window ...

  7. Maven入门示例(3):自动部署至外部Tomcat

    Maven入门示例(3):自动部署至外部Tomcat 博客分类:  maven 2012原创   Maven入门示例(3):自动部署至外部Tomcat 上一篇,介绍了如何创建Maven项目以及如何在内 ...

  8. 1.【转】spring MVC入门示例(hello world demo)

    1. Spring MVC介绍 Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于 ...

  9. 【java开发系列】—— spring简单入门示例

    1 JDK安装 2 Struts2简单入门示例 前言 作为入门级的记录帖,没有过多的技术含量,简单的搭建配置框架而已.这次讲到spring,这个应该是SSH中的重量级框架,它主要包含两个内容:控制反转 ...

  10. Couchbase之个人描述及入门示例

    本文不打算抄袭官方或者引用他人对Couchbase的各种描述,仅仅是自己对它的一点理解(错误之处,敬请指出),并附上一个入门示例. ASP.NET Web项目(其他web开发平台也一样)应用规模小的时 ...

随机推荐

  1. 如何查看Navicat已有连接的密码(简单清晰)

    1.打开Navicat,File > Export Connections 2.选择你想查看的数据库,并勾选下方的 [导出密码],导出 3.去文件里找到Password 4.打开网址 https ...

  2. SAP集成技术(五)集成风格

    上一节介绍了各种集成架构,这一节将介绍各种集成风格(Style).我们在日常工作中使用这些集成风格来分类不同类型的集成场景.本文将遵循SAP的集成解决方案咨询方法(ISA - M)使用的方法,将集成风 ...

  3. Arrays类的常用方法

    Arrays类的常用方法 Array数组的工具类java.util.Arrays Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象来调用 Ar ...

  4. 🔥🔥v1.9.2-httpsok快速申请免费谷歌SSL证书

    v1.9.2-httpsok快速申请免费谷歌SSL证书 介绍 httpsok 是一个便捷的 HTTPS 证书自动续签工具,专为 Nginx .OpenResty 服务器设计.已服务众多中小企业,稳定. ...

  5. 热烈祝贺 Splashtop 赢得最佳远程桌面用户满意度得分

    在 G2 的 2021 年冬季远程桌面网格报告中,Splashtop 的净发起人得分(NPS)为 93,是所有远程桌面工具中最高的. 在一份分析用户对 30 多种远程桌面解决方案的评论的报告中,Spl ...

  6. 4G EPS 的网络协议栈

    目录 文章目录 目录 前文列表 LTE/EPC 协议栈 E-UTRAN 空中接口协议栈 用户平面协议 PHY 层 MAC 层 RLC 层 PDCP 层 控制平面协议 RRC 层 NAS 层 EPC 核 ...

  7. OpenNESS & OpenVINO Demo 部署

    目录 文章目录 目录 部署架构 部署 Edge Controller 基础配置 配置 Proxy 配置防火墙 Install necessary package Install MySQL Insta ...

  8. vmware迁移虚拟机

    迁移 1.打开"VMware",点击"虚拟机详细信息"可以看到虚拟机的储存路径. 2. 按照储存路径找到虚拟机文件位置,将整个虚拟机文件复制,粘贴到需要转移的路 ...

  9. 自研WPF插件系统(沙箱运行及热插拔)

    前言 插件化的需求主要源于对软件架构灵活性的追求,特别是在开发大型.复杂或需要不断更新的软件系统时,插件化可以提高软件系统的可扩展性.可定制性.隔离性.安全性.可维护性.模块化.易于升级和更新以及支持 ...

  10. 鸿蒙HarmonyOS实战-Stage模型(开发卡片事件)

    一.开发卡片事件 HarmonyOS元服务卡片页面(Metaservice Card Page)是指在HarmonyOS系统中,用于展示元服务的页面界面.元服务是指一组提供特定功能或服务的组件,例如天 ...