C# ONNX使用入门教程

背景

有新入坑的老哥不太了解C# onnx 运行的机理,我这边详细介绍一下,之前直接放官方的样例有点草率了。

准备[python环境]

1、要使用onnx,首先我们就自己生成一个onnx文件,请大家准备一下以下需要的[python]环境

python 版本>=3.8 我的机子比较老,只能装3.8
安装torch,可以使用命令行pip install torch
安装netron,可以使用命令行pip install netron
安装onnx,可以使用命令行pip install onnx

2、做好以上准备工作,我们就可以编写一个py文件,命名为create_onnx.py,内容如下:

#======================================================================#

# 导入依赖库
import torch

#======================================================================#

# 打印pytorch基本信息
print("pytorch版本:",torch.__version__)
print("已安装pytorch版本是否支持英伟达显卡",torch.cuda.is_available())

# 自定义网络必须直接或间接继承自torch.nn.Module
class Net(torch.nn.Module):
    def __init__(self):
        super(self.__class__,self).__init__()
        self.linear=torch.nn.Linear(1,1)

    def forward(self,x):
        return self.linear(x)

#======================================================================#

# 训练自定义网络

# 实例化一个自定义网络对象,用于以下训练
net=Net()

# 选择平方差为标准损失函数
critision=torch.nn.MSELoss()
# 选择随机梯度下降的优化器,学习率设为0.01
optimizer=torch.optim.Adam(net.parameters(),lr=0.01)

# 训练的输入
x=torch.FloatTensor([[0],[1],[2],[3]])
# 训练的输出
y=torch.FloatTensor([[5],[7],[9],[11]])

# 训练3000轮
for epoch in range(1,3001):
    Y=net(x)
    loss=critision(Y,y)
    # 每训练100轮打印一次损失值以便于观察是否收敛
    if epoch%100==0:
        print(f"epoch:{epoch},loss:{loss.item()}")
    # 自动求导
    optimizer.zero_grad()
    # 反向传播
    loss.backward()
    # 更新参数
    optimizer.step()

#======================================================================#

# 保存模型为onnx格式,方便c#调用

# 输入参数格式为1行1列的数组
input_parameter=torch.randn(1,1)
# 导出onnx格式前务必先调用eval函数
net.eval()
with torch.no_grad():
    torch.onnx.export(net,# 自定义的网络对象
                      input_parameter, # 输入参数格式
                      "linear.onnx", # 导出onnx格式文件名称
                      opset_version=11, # 导出onnx指定算子版本
                      input_names=["input"], # 输入参数名称
                      output_names=["output"]) # 输出参数名称
#======================================================================#

命令行直接运行它,过一会它训练完毕,就会给我们生成onnx文件,名称为linear.onnx

3、编写另一个py文件,命名为watch_onnx.py,内容如下:

import netron
netron.start("linear.onnx")

 命令行直接运行它,过一会浏览器会直接显示出此onnx文件的推理图全过程参数

 4、观察此onnx文件的输入输出,其输入为1x1的数组,输出也是1x1的数组。同时注意到它的意义,输入是[[x]],输出是[[y]],于是我们可以开始编写C#程序了。

正题[C#调用onnx]

1、新建一个DotNet控制台项目,千万别选成了DotNetFramework,命名为UseOnnx

2、NuGet中安装onnxruntime,由于只是简单入门介绍 ,这里我们选择cpu版本的onnx运行时安装即可,图中就是cpu的onnx运行时库

3、项目和依赖都准备好了,开始着手C#程序的编写,把Program.cs内容改为:

using Microsoft.ML.OnnxRuntime;
using Microsoft.ML.OnnxRuntime.Tensors;
using System;
using System.Collections.Generic;

namespace UseOnnx
{
    class Program
    {
        static void Main(string[] args)
        {
            //onnx文件路径,注意把onnx文件放到我们生成程序同级目录下
            string onnx_path = @"linear.onnx";
            //根据onnx文件路径实例化一个推理对象
            using InferenceSession session = new InferenceSession(onnx_path);

            //稠密张量,其维度与模型的输入参数格式一致,1x1==>>new int[]{1,1}
            DenseTensor<float> tensor = new DenseTensor<float>(new int[] { 1, 1 });

            //测试的输入为101
            float x = 101f;

            //把输入赋值到张量中
            tensor[0, 0] = x;

            //构建输入
            List<NamedOnnxValue> inputs = new List<NamedOnnxValue>()
            {
                //onnx推理图的输入名称为input,参数格式为1x1,因此这样构建输入
                NamedOnnxValue.CreateFromTensor("input",tensor)
            };

            //进行推理,得到结果
            using IDisposableReadOnlyCollection<DisposableNamedOnnxValue> outputs = session.Run(inputs);

            //输出是二维数组
            float[,] results = (float[,])outputs[0].Value;

            //输出只有一个,它就是onnx推理结果
            float y = results[0, 0];

            Console.WriteLine($"when x is {x} , onnx calculate y is {y:0.0}");
        }
    }
}

开始运行,如果没报错的话,应该可以看到近似结果

207.0

由于我的系统是win7,跑程序的时候报错没找到onnxruntime.dll,就算把这个动态链接库拷贝到同级目录下也报同样错误,所以没法最后一步截图演示了。希望win10、win11的小伙伴知悉。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

探索设计模式的魅力:揭秘享元模式-轻松实现资源高效利用的秘密武器

设计模式专栏&#xff1a;http://t.csdnimg.cn/U54zu 目录 引言&#xff1a; 一、简介 二、实现资源的极致利用 公共自行车与享元模式的智慧共享 HOW 三、案例探讨 3.1 场景 3.2 不用模式实现&#xff1a;一坨坨代码实现 3.3 痛点 3.4 解决方案分析 注意 四、深入享…

Qt多线程与SocketTCP的简单实现

1.相关说明 多线程实现Qt的socket编程实现客户端发送文件&#xff0c;服务端接收文件&#xff0c;并且在客户端设置了心跳&#xff0c;用于监控服务端是否存活。因为Qt中socket套接字发送数据&#xff0c;会先把数据发送至缓冲区中&#xff0c;在发送数据过程中&#xff0c;soc…

寒假学习第24天---PythonPoc基础编写(二)

提示&#xff1a;所分享内容仅用于每一个爱好者之间的技术讨论及教育目的&#xff0c;所有渗透及工具的使用都需获取授权&#xff0c;禁止用于违法途径&#xff0c;否则需自行承担&#xff0c;本作者不承担相应的后果。 文章目录 前言一、 目标二、过程思路实践开始 总结完整代…

Java基于微信小程序的驾校报名小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

腾讯云游戏服务器购买入口,详细配置精准报价

2024年更新腾讯云游戏联机服务器配置价格表&#xff0c;可用于搭建幻兽帕鲁、雾锁王国等游戏服务器&#xff0c;游戏服务器配置可选4核16G12M、8核32G22M、4核32G10M、16核64G35M、4核16G14M等配置&#xff0c;可以选择轻量应用服务器和云服务器CVM内存型MA3或标准型SA2实例&am…

创建网站的具体步骤是什么?

创建网站的具体步骤是什么 一.领取一个免费域名和SSL证书&#xff0c;和CDN 1.打开网站链接&#xff1a;https://www.rainyun.com/z22_ 2.在网站主页上&#xff0c;您会看到一个"登陆/注册"的选项。 3.点击"登陆/注册"&#xff0c;然后选择"微信登…

假期刷题打卡--Day26

1、MT1212乘法表 请编写一个简单程序&#xff0c;输出九九乘法表。输入n&#xff0c;就输出乘法表到n的地方。 格式 输入格式&#xff1a; 输入整型 输出格式&#xff1a; 输出整型。形式如&#xff1a;1*11 样例 1 输入&#xff1a; 5输出&#xff1a; 1*11 2*12 …

格子表单GRID-FORM | 文档网站搭建(VitePress)与部署(Github Pages)

格子表单/GRID-FORM已在Github 开源&#xff0c;如能帮到您麻烦给个星&#x1f91d; GRID-FORM 系列文章 基于 VUE3 可视化低代码表单设计器嵌套表单与自定义脚本交互文档网站搭建&#xff08;VitePress&#xff09;与部署&#xff08;Github Pages&#xff09; 效果预览 格…

服装设计公司,如何用钉钉实现企业数字化成功转型?

钉钉作为数字化工作平台&#xff0c;为某服装设计公司实现了组织管理的数字化转型&#xff0c;构建了一站式的工作平台。通过钉钉赋能&#xff0c;有利于企业推进组织架构、员工沟通、产品运营和客户服务等方面的数字化、智能化转型。 借助钉钉平台&#xff0c;该服设公司轻松实…

【C++第二阶段】空指针访问成员函数常成员函数常成员属性

你好你好&#xff01; 以下内容仅为当前认识&#xff0c;可能有不足之处&#xff0c;欢迎讨论&#xff01; 文章目录 空指针访问成员函数常成员函数&常成员属性 空指针访问成员函数 类对象类型的空指针可以访问成员函数&#xff0c;但是不能够访问带有成员属性的成员函数。…

js-添加网页快捷方式

title: js-添加网页快捷方式 categories: Javascript tags: [p快捷方式] date: 2024-02-04 15:28:25 comments: false mathjax: true toc: true js-添加网页快捷方式 前篇 谷歌上包困难的情况, 只能通过投放落地页来缓解一下痛苦, web2app 那种形式有几个比较大的缺点就是需要…

人工智能基础部分24-人工智能的数学基础,汇集了人工智能数学知识最全面的概况

、 大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能基础部分24-人工智能的数学基础&#xff0c;汇集了人工智能数学知识最全面的概况&#xff0c;深度学习是一种利用多层神经网络对数据进行特征学习和表示学习的机器学习方法。要全面了解深度学习的数学基…

FlinkSql通用调优策略

历史文章迁移&#xff0c;稍后整理 使用DataGenerator 提前进行压测&#xff0c;了解数据的处理瓶颈、性能测试和消费能力 开启minibatch&#xff1a;"table.exec.mini-batch.enabled", "true" 开启LocalGlobal 两阶段聚合&#xff1a;"table.exec.m…

【力扣】快乐数,哈希集合+快慢指针+数学

快乐数原题地址 方法一&#xff1a;哈希集合 定义函数getNext(n)&#xff0c;返回n的所有位的平方和。一直执行ngetNext(n)&#xff0c;最终只有2种可能&#xff1a; n停留在1。无限循环且不为1。 证明&#xff1a;情况1是存在的&#xff0c;如力扣的示例一&#xff1a; 接…

怎么加密电脑磁盘?磁盘加密软件哪个好?

磁盘是电脑储存数据的基础工具&#xff0c;可以存放大量数据。为了避免数据泄露&#xff0c;可以使用专业的磁盘加密软件加密保护电脑磁盘。那么&#xff0c;磁盘加密软件哪个好呢&#xff1f;下面我们就来了解一下。 磁盘加锁专家 磁盘加锁专家是一款专业的磁盘加锁软件&…

阅读《极客时间 | Kafka核心技术与实战》(一)【Kafka入门】

阅读《极客时间 | Kafka核心技术与实战》 为什么要学习Kafka消息引擎系统ABC一篇文章带你快速搞定Kafka术语我应该选择哪种Kafka&#xff1f;聊聊Kafka的版本号 为什么要学习Kafka 如果你是一名软件开发工程师的话&#xff0c;掌握 Kafka 的第一步就是要根据你掌握的编程语言去…

使用CMSIS-DSP库进行嵌入式音频信号处理

在嵌入式环境下&#xff0c;使用CMSIS-DSP库进行音频信号处理是一种常见的应用场景。通过CMSIS-DSP库&#xff0c;开发人员可以利用嵌入式系统的处理能力来实现各种数字信号处理&#xff08;DSP&#xff09;功能&#xff0c;例如音频滤波、均衡器、噪音消除等。本文将介绍如何在…

C# 中的 out 参数传递

C# 是一种强大的编程语言&#xff0c;它提供了许多功能和特性来帮助开发人员编写高效和可维护的代码。其中&#xff0c;out 参数是 C# 中非常有用的一个特性之一。在本文中&#xff0c;我们将深入探讨 C# 中的 out 参数传递&#xff0c;并介绍它的用法、优势以及一些最佳实践。…

Dataway工具(一个接口竟然可以如此简单的配置出来无需开发任何一行代码,也不需要做任何 Mapping 实体映射绑定。)

基于 DataQL 服务聚合能力&#xff0c;为应用提供的一个接口配置工具&#xff0c;使得使用者无需开发任何代码就配置一个满足需求的接口。整个接口配置、测试、冒烟、发布&#xff0c;一站式都通过 Dataway 提供的 UI 界面完成。UI 会以 Jar 包方式提供并集成到应用中并和应用共…

Qt环境搭建+简单程序实现

Qt是什么 Qt是一个跨平台的C图形用户界面应用程序框架。 框架的本质就是一群大佬发明的让菜鸡写出来的代码也也比较规范 也就是限制程序员的自由&#xff0c;让程序员写出来的代码规范。 库和框架有相似性。 库是被程序员调用的&#xff0c;&#xff08;程序员是主体&…