在C#中如何使用ResNet50v2进行图像识别

 更新时间:2024年07月03日 10:17:15   作者:mingupupup  
ONNX 运行时推理可以实现更快的客户体验和更低的成本,支持来自深度学习框架如 PyTorch和TensorFlow/Keras以及经典机器学习库如 scikit-learn、LightGBM、XGBoost 等的模型,这篇文章主要介绍了在C#中如何使用ResNet50v2进行图像识别,需要的朋友可以参考下

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

// 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)

到此这篇关于在C#中使用ResNet50v2进行图像识别的文章就介绍到这了,更多相关C# ResNet50v2图像识别内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • C#常用正则验证函数示例

    C#常用正则验证函数示例

    这篇文章主要介绍了C#常用正则验证函数,举例分析了C#针对IP验证、价格验证及正整数验证的相关操作技巧,需要的朋友可以参考下
    2017-01-01
  • C#对文件进行加密解密代码

    C#对文件进行加密解密代码

    本文给大家分享的是使用C#对文件进行加密解密的代码,十分的简单实用,有需要的小伙伴可以参考下。
    2015-07-07
  • C#自动给文章关键字加链接实现代码

    C#自动给文章关键字加链接实现代码

    这篇文章主要介绍了C#自动给文章关键字加链接实现代码,有需要的朋友可以参考一下
    2013-12-12
  • C# IP地址与整数之间转换的具体方法

    C# IP地址与整数之间转换的具体方法

    这篇文章介绍了C# IP地址与整数之间转换的具体方法,有需要的朋友可以参考一下
    2013-10-10
  • 采用C#代码动态设置文件权限

    采用C#代码动态设置文件权限

    在开发中,我们经常会使用IO操作,例如创建,删除文件等操作。在项目中这样的需求也较多,我们也会经常对这些操作进行编码,但是对文件的权限进行设置,这样的操作可能会手动操作,本文介绍一种采用代码动态对文件设置权限的操作。
    2016-12-12
  • C#实现汉字转拼音或转拼音首字母的方法

    C#实现汉字转拼音或转拼音首字母的方法

    这篇文章主要介绍了C#实现汉字转拼音或转拼音首字母的方法,涉及C#操作数组、遍历及正则匹配的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • C#关于类的只读只写属性实例分析

    C#关于类的只读只写属性实例分析

    这篇文章主要介绍了C#关于类的只读只写属性实例分析,对于初学者更好的理解类的只读只写属性有一定的帮助,需要的朋友可以参考下
    2014-07-07
  • 基于c#实现的九九乘法表(简单实例)

    基于c#实现的九九乘法表(简单实例)

    本文主要分享了基于c#实现的九九乘法表,代码简洁,需要的朋友可以参考下,希望对大家有所帮助
    2016-12-12
  • C#排序算法的比较分析

    C#排序算法的比较分析

    这篇文章主要介绍了C#排序算法的比较,实例分析几种比较常见的算法,并对其时间复杂度与稳定性进行了详细的分析,需要的朋友可以参考下
    2014-11-11
  • C#实现文件筛选读取并翻译的自动化工具

    C#实现文件筛选读取并翻译的自动化工具

    这篇文章主要为大家详细介绍了如何利用C#实现文件筛选及读取内容,并翻译的自动化工具,文中的示例代码讲解详细,感兴趣的小伙伴可以了解一下
    2023-03-03

最新评论