C# ONNX使用入门教程

news2025/2/22 9:26:25

背景

有新入坑的老哥不太了解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的小伙伴知悉。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux 文件查看 head 、 cat 、 less 、tail 、grep

查看文件详细信息 stat 文件 cat 》》适合显示小文件【行数比较少】&#xff0c;如果行数较多&#xff0c;屏幕显示不完整&#xff08;如果虚拟操作&#xff0c;是无法上下键的&#xff0c;或者滚动鼠标的&#xff0c;第三方 xsheel&#xff0c;crt 可以方向键查看&#xf…

MySQL 多表查询

重点&#xff1a; MySQL 的 三种安装方式&#xff1a;包安装&#xff0c;二进制安装&#xff0c;源码编译安装。 MySQL 的 基本使用 MySQL 多实例 DDLcreate alter drop DML insert update delete DQL select 3.5&#xff09;DDL 语句 表&#xff1a;二维关系 设计表&…

【微服务】skywalking自定义链路追踪与日志采集

目录 一、前言 二、自定义链路追踪简介 2.1 自定义链路追踪应用场景 2.2 链路追踪几个关键概念 三、skywalking 自定义链路追踪实现 3.1 环境准备 3.2 集成过程 3.2.1 导入核心依赖 3.2.2 几个常用注解 3.2.3 方法集成 3.2.4 上报追踪信息 四、skywalking 自定义日志…

Spring速成(二)

Spring速成&#xff08;二&#xff09; 掌握IOC/DI配置管理第三方bean掌握IOC/DI的注解开发掌握IOC/DI注解管理第三方bean完成Spring与Mybatis及Junit的整合开发 1&#xff0c;IOC/DI配置管理第三方bean 1.1 案例:数据源对象管理 1.1.1 环境准备 学习之前&#xff0c;先来准…

STM32标准库——(9)TIM编码器接口

1.编码器接口简介 Encoder Interface 编码器接口编码器接口可接收增量&#xff08;正交&#xff09;编码器的信号&#xff0c;根据编码器旋转产生的正交信号脉冲&#xff0c;自动控制CNT自增或自减&#xff0c;从而指示编码器的位置、旋转方向和旋转速度每个高级定时器和通用定…

异步编程Completablefuture使用详解----进阶篇

JDK版本&#xff1a;jdk17 IDEA版本&#xff1a;IntelliJ IDEA 2022.1.3 文章目录 前言一、异步任务的交互1.1 applyToEither1.2 acceptEither1.3 runAfterEither 二、get() 和 join() 区别三、ParallelStream VS CompletableFuture3.1 使用串行流执行并统计总耗时3.2 使用并行…

单元/集成测试服务

服务概述 单元/集成测试旨在证明被测软件实现其单元/架构设计规范、证明被测软件不包含非预期功能。经纬恒润测试团队拥有丰富的研发经验、严格的流程管控&#xff0c;依据ISO26262/ASPICE等开展符合要求的单元测试/集成测试工作。 在ISO 26262 - part6 部分产品开发&#xff…

荣耀手机如何录屏?在线分享3个录屏方法

荣耀手机如何录屏&#xff1f;荣耀手机录屏是一项非常实用的功能&#xff0c;它可以帮助我们轻松记录手机屏幕上的内容&#xff0c;无论是游戏攻略、教育学习还是工作演示&#xff0c;都能够方便地进行录制。通过录屏&#xff0c;我们可以随时随地记录和分享自己的操作和见解。…

C++ 动态规划 线性DP 最长上升子序列

给定一个长度为 N 的数列&#xff0c;求数值严格单调递增的子序列的长度最长是多少。 输入格式 第一行包含整数 N 。 第二行包含 N 个整数&#xff0c;表示完整序列。 输出格式 输出一个整数&#xff0c;表示最大长度。 数据范围 1≤N≤1000 &#xff0c; −109≤数列中的数…

学成在线: 新增/修改课程计划

新增/修改课程计划(同接口) 界面原型 第一步: 在课程计划界面,点击添加章新增第一级课程计划,点击添加小节可以向某个第一级课程计划下添加小节 新增章/节成功后会自动发起请求刷新课程计划列表并且把新增的课程计划信息添加到数据库当中,新增的课程计划自动排序到最后 第二…

2024年第三届能源与环境工程国际会议(CFEEE 2024) | Ei&Scopus双检索

会议简介 Brief Introduction 2024年第三届能源与环境工程国际会议(CFEEE 2024) 会议时间&#xff1a;2024年12月12日-14日 召开地点&#xff1a;澳大利亚凯恩斯 大会官网&#xff1a;CFEEE 2024-2024 International Conference on Frontiers of Energy and Environment Engine…

【python】python爱心代码

一、实现效果&#xff1a; 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 二、准备工作 &#xff08;1)、导入必要的模块&#xff1a; 代码首先导入了需要使用的模块&#xff1a;requests、lxml和csv。 import requests from lxml import etree import csv 如果出现…

不同状态角 θz 下的 K2eff 和 Kav 计算结果

不同状态角 θ z 下的 K 2 eff 和 K av 计算结果 clear clc close all syms theta for theta_z[pi/5,pi/3,pi/2,2*pi/3,4*pi/5,pi] % theta_zdtheta_z*180/pi theta_1-theta_z/2; theta_2theta_z/2; fthetacos(theta); ftheta2cos(theta)^2; Keff2int(ftheta2,theta_1,…

png,jpg,bmp等格式图像转.npy文件(附代码)

目录 一、npy文件二、代码三、转后效果 一、npy文件 .npy 文件是 NumPy 库用于存储数组的二进制文件格式。这种文件可以存储一个或多个 NumPy 数组对象。.npy 文件在保存和加载 NumPy 数组时非常有用&#xff0c;因为它们可以用于在磁盘上高效地存储数据&#xff0c;并且在加载…

MySQL 安装配置 windows

一、下载 去官网MySQL :: MySQL Downloads 下载社区版 然后根据自己的系统选择 直接下载。 二、安装 点击安装程序 这边看样子缺少东西。 去这边下载 Latest supported Visual C Redistributable downloads | Microsoft Learn 然后再一次安装mysql 三、配置 安装完成后&a…

PPT母版页码设置

PPT母版页码设置 一、需求介绍二、达到效果三、具体操作1. 插入页码2. 设置起始页码为03. 进入母版编辑页面4. 内容格式调整5. 删去最后一个板式的三个模块信息6. 尾页处理7. 最终效果 一、需求介绍 PPT的母版可以设定PPT的基调&#xff0c;且在非母版页面不会误改PPT中的固定…

参考数据集INRIA Holidays dataset

Download datasets 很贴心,MATLAB访问代码: % This function reads a siftgeo binary file % % Usage: [v, meta] = siftgeo_read (filename, maxdes) % filename the input filename % maxdes maximum number of descriptors to be loaded % (default=unlimit…

力扣刷题之旅:启程篇(二)

力扣&#xff08;LeetCode&#xff09;是一个在线编程平台&#xff0c;主要用于帮助程序员提升算法和数据结构方面的能力。以下是一些力扣上的入门题目&#xff0c;以及它们的解题代码。 --点击进入刷题地址 1.最后得到的余数 题目描述&#xff1a; 给定两个非空字符串 nu…

2024/2/3

一&#xff0e;选择题 1、适宜采用inline定义函数情况是&#xff08;C&#xff09; A. 函数体含有循环语句 B. 函数体含有递归语句‘、考科一 ’ C. 函数代码少、频繁调用 D. 函数代码多、不常调用 2、假定一个函数为A(int i4, int j0) {;}, 则执行“A (1);”语句后&#xff0c…

C++之std::tuple(一) : 使用

相关系列文章 C之std::tuple(一) : 使用 C三剑客之std::variant(一) : 使用 C三剑客之std::variant(二)&#xff1a;深入剖析 目录 1.简介 2.创建元组 2.1.直接初始化方式 2.2.使用花括号初始化列表方式&#xff08;C11及以上版本&#xff09; 2.3.make_tuple方式 2.4.使…