在 C# 中使用便携式 ONNX AI 模型





5.00/5 (4投票s)
在本文中,我简要概述了 ONNX Runtime 和 ONNX 格式。
在本系列关于在 2020 年使用便携式神经网络的文章中,您将学习如何在 x64 架构上安装 ONNX 并在 C# 中使用它。
Microsoft 与 Facebook 和 AWS 共同开发了 ONNX。ONNX 格式和 ONNX Runtime 都获得行业支持,以确保所有重要框架都能将它们的图导出到 ONNX,并且这些模型可以在任何硬件配置上运行。
ONNX Runtime 是一个用于运行已转换为 ONNX 格式的机器学习模型的引擎。传统机器学习模型和深度学习模型(神经网络)都可以导出到 ONNX 格式。该运行时可以在 Linux、Windows 和 Mac 上运行,并可以在各种芯片架构上运行。它还可以利用 GPU 和 TPU 等硬件加速器。但是,并非所有操作系统、芯片架构和加速器的组合都有安装包,因此如果您使用的是非通用组合,则可能需要从源代码构建运行时。请查看 ONNX Runtime 网站 以获取您需要的组合的安装说明。本文将展示如何在具有默认 CPU 的 x64 架构以及具有 GPU 的 x64 架构上安装 ONNX Runtime。
除了能够在多种硬件配置上运行外,运行时还可以从大多数流行编程语言中调用。本文的目的是展示如何在 C# 中使用 ONNX Runtime。我将演示如何安装 onnxruntime 包。一旦 ONNX Runtime 安装完成,我将加载先前导出的 MNIST 模型到 ONNX Runtime 中并使用它进行预测。
安装和导入 ONNX Runtime
在使用 ONNX Runtime 之前,您需要安装 Microsoft.ML.OnnxRuntime,这是一个 NuGet 包。如果您还没有 .NET CLI,还需要安装它。以下命令将在具有默认 CPU 的 x64 架构上安装运行时
dotnet add package microsoft.ml.onnxruntime
要在具有 GPU 的 x64 架构上安装运行时,请使用此命令
dotnet add package microsoft.ml.onnxruntime.gpu
运行时安装完成后,可以使用以下 using
语句将其导入到您的 C# 代码文件中
using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
拉入 Tensor 工具的 using
语句将帮助我们创建 ONNX 模型的输入并解释 ONNX 模型的输出(预测)。
加载 ONNX 模型
下面的代码片段展示了如何在 ONNX Runtime 中加载 ONNX 模型并在 C# 中运行。此代码创建一个会话对象,可用于进行预测。这里使用的模型是从 PyTorch 导出的 ONNX 模型。
这里有几点值得注意。首先,您需要查询会话以获取其输入。这是通过会话的 InputMetadata
属性完成的。我们的 MNIST 模型只有一个输入参数:一个包含 784 个浮点数的数组,代表 MNIST 数据集中的一个图像。如果您的模型有多个输入参数,则 InputMetadata
将为每个参数提供一个条目。
Utilities.LoadTensorData();
string modelPath = Directory.GetCurrentDirectory() + @"/pytorch_mnist.onnx";
using (var session = new InferenceSession(modelPath))
{
float[] inputData = Utilities.ImageData[imageIndex];
string label = Utilities.ImageLabels[imageIndex];
Console.WriteLine("Selected image is the number: " + label);
var inputMeta = session.InputMetadata;
var container = new List<NamedOnnxValue>();
foreach (var name in inputMeta.Keys)
{
var tensor = new DenseTensor<float>(inputData, inputMeta[name].Dimensions);
container.Add(NamedOnnxValue.CreateFromTensor<float>(name, tensor));
}
// Run code omitted for brevity.
}
上面的代码中未显示读取原始 MNIST 图像并将每个图像转换为 784 个浮点数数组的实用程序。每个图像的标签也从 MNIST 数据集中读取,以便确定预测的准确性。这段代码是标准的 .NET 代码,但仍鼓励您进行检查和使用。如果您需要读取与 MNIST 数据集类似的图像,这将为您节省时间。
使用 ONNX Runtime 进行预测
下面的函数展示了如何使用我们在加载 ONNX 模型时创建的 ONNX 会话
{
// Load code not shown for brevity.
// Run the inference
using (var results = session.Run(container))
{
// Get the results
foreach (var r in results)
{
Console.WriteLine("Output Name: {0}", r.Name);
int prediction = MaxProbability(r.AsTensor<float>());
Console.WriteLine("Prediction: " + prediction.ToString());
}
}
}
大多数神经网络不会直接返回预测。它们返回每个输出类的概率列表。就我们的 MNIST 模型而言,每个图像的返回值将是 10 个概率的列表。概率最高的条目就是预测。一个有趣的测试是比较 ONNX 模型返回的概率与原始模型在创建它的框架内运行时返回的概率。理想情况下,模型格式和运行时的更改不应改变产生的任何概率。这将是一个很好的单元测试,在每次模型发生更改时运行。
总结和后续步骤
在本文中,我简要概述了 ONNX Runtime 和 ONNX 格式。然后,我演示了如何在 ONNX Runtime 中使用 C# 加载和运行 ONNX 模型。
本文的代码示例包含一个可运行的控制台应用程序,演示了此处展示的所有技术。此代码示例是 GitHub 存储库的一部分,该存储库探索了使用神经网络预测 MNIST 数据集中数字的应用。具体来说,有一些示例展示了如何在 Keras、PyTorch、TensorFlow 1.0 和 TensorFlow 2.0 中创建神经网络。
如果您想了解更多关于导出到 ONNX 格式和使用 ONNX Runtime 的信息,请查看本系列的更多文章。
参考文献
- https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code
- https://docs.microsoft.com/en-us/nuget/quickstart/install-and-use-a-package-using-the-dotnet-cli
- https://vscode.js.cn/docs/setup/mac
- https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet
- https://msdocs.cn/onnxruntime/
- https://github.com/microsoft/onnxruntime/blob/master/docs/CSharp_API.md#getting-started
- https://github.com/keithpij/onnx-lab