当前位置: 首页 > news >正文

【OpenVINO】OpenVINO C# API 常用 API 详解与演示

OpenVINO C# API 常用 API 详解与演示

  • 1 安装OpenVINO C# API
    • 2 导入程序集
  • 3 初始化OpenVINO 运行时内核
  • 4 加载并获取模型信息
    • 4.1 加载模型
    • 4.2 获取模型信息
  • 5 编译模型并创建推理请求
  • 6 张量Tensor
    • 6.1 张量的获取与设置
    • 6.2 张量的信息获取与设置
  • 7 加载推理数据
    • 7.1 获取输入张量
    • 7.2 添加推理数据
  • 8 模型推理
  • 9 获取推理结果
  • 10 释放分配的内存
  • 11 Yolov8分类模型示例
  • 12 总结

  OpenVINO™ 工具套件可以加快深度学习视觉应用开发速度,帮助用户在从边缘到云的各种英特尔平台上,更加方便快捷的将 AI 模型部署到生产系统中。OpenVINO™ 2023.1 LTS 版本现已发布,可帮助你快速轻松地开发卓越的人工智能应用,并跨边缘和云端部署深度学习推理工作负载,无论你处于人工智能编程的什么阶段。
  C# 是由 C 和 C++ 衍生出来的一种安全的、稳定的、简单的、优雅的面向对象编程语言,它综合了 VB 简单的可视化操作和 C++ 的高运行效率,成为支持成为.NET 开发的首选语言。作为人工智能开发人员,如果你希望在 C# 端使用 OpenVINO™ ,OpenVINO C# API将是你的首选,并且制作了 NuGet 程序包,实现在 C# 端了一站式安装与使用 OpenVINO™ 。
  项目的首发网址:OpenVINO™ C# API 详解与演示 | 开发者实战。
  OpenVINO C# API在制作时参考了OpenVINO™ C++ API,因此对于之前使用过OpenVINO™ 的人十分友好。下面表格向我们展示了 C# 与 C++ API的对应关系

ClassC++ APIC# API说明
Core classov::CoreCoreOpenVINO运行时核心实体类
Model classov::ModelModel用户自定义模型类
CompiledModel classov::CompiledModelCompiledModel已编译的模型类
Output classov:: Output<ov::Node>Output节点输出的句柄类
Input classov:: Input<ov::Node>Input节点输入的句柄类
InferRequest classov::InferRequestov::InferRequest以异步或同步方式运行推断请求的类
Tensor classov::TensorTensor张量
Shape classov::ShapeShape张量的形状类

  在本文中,将会根据模型部署的一般步骤,演示从模型加载到推理的方法函数使用方式,并于C++ API 做对比。

1 安装OpenVINO C# API

  OpenVINO C# API 支持 NuGet 程序包安装方式,这与在C++中安装过程相比,较为简单,并且程序包中包含了最新版的 OpenVINO™ 2023.1 发行版本的 Release,可以通 过 NuGet 安装后直接使用。

  如果使用Visual Studio 编译该项目,则可以通过 NuGet 程序包管理功能直接安装即可:

在这里插入图片描述

  如果通过dotnet命令方式安装,通过下面语句进行安装即可:

dotnet add package OpenVINO.CSharp.win

2 导入程序集

  OpenVINO C# API 程序集全部在CSharp命名空间下,因此若要使用 OpenVINO C# API,需要先引入命名空间:

using OpenVinoSharp;

3 初始化OpenVINO 运行时内核

  Core类代表一个OpenVINO运行时核心实体,后续的读取模型、加载模型等方法都需要通过 Core 类进行创建,在封装C# API 时,为了与 C++ API 对应,也对 Core 类进行了封装,并封装了与 C++ API 中对应的方法

在C#中的初始化方式:

Core core = new Core();

在C++中的初始化方式:

ov::Core core;

4 加载并获取模型信息

4.1 加载模型

  OpenVINO™ 2022.1版本更新之后,加载,下面是所使用的 API 方法:

API作用
Core.read_model ()将模型从硬盘载入内存,并返回Model对象。

在C#中加载模型的方式:

Model model = core.read_model(model_path);

在C++中的初始化方式:

std::shared_ptr<ov::Model> model = core.read_model(model_path);

4.2 获取模型信息

  通过 Core.read_model ()方法获得的 Model 对象和通过 Core.compile_model ()方法获得的 CompiledModel 对象,都支持直接访问属性获取输入与输出层信息。以Model对象获取模型信息为例,下面是所使用的 API 方法:

API作用
Model.get_friendly_name()获取模型的friendly name。
Model.input()获取模型的输入层,并返回 Input对象。
Model.output()获取模型的输出层,并返回 Output对象。

  Input/Output 主要是封装了模型网络层,可以通过下面 API 实现获取模型的详细信息:

API作用
Output.get_any_name()获取模型网络层的名字。
Output.get_element_type()获取模型网络层的数据类型,并返回 OvType对象,OvType主要封装了网络的基本数据类型。
Output.get_shape()获取模型网络层的形状,并返回 Shape对象,Shape封装了网络层的形状数组。

  在 C# 中通过下方代码,可以直接获取模型的输入、输入层以及模型的friendly name:

string model_name = model.get_friendly_name();
Input input = model.input();
Output output = model.output();

  然后将模型具体信息打印到控制台页面:

Console.WriteLine("Model name: {0}", model_name);
Console.WriteLine("/------- [In] -------/");
Console.WriteLine("Input name: {0}", input.get_any_name());
Console.WriteLine("Input type: {0}", input.get_element_type().to_string());
Console.WriteLine("Input shape: {0}", input.get_shape().to_string());
Console.WriteLine("/------- [Out] -------/");
Console.WriteLine("Output name: {0}", output.get_any_name());
Console.WriteLine("Output type: {0}", output.get_element_type().to_string());
Console.WriteLine("Output shape: {0}", output.get_shape().to_string());

  获取模型网络层信息如下:

Model name: torch_jit
/------- [In] -------/
Input name: data
Input type: float
Input shape: [1,3,224,224]
/------- [Out] -------/
Output name: prob
Output type: float
Output shape: [1,1000]

  同样的输出信息,我们使用 C++ API 实现如下:

std::cout << "Model name: " << model->get_friendly_name() << std::endl;
ov::Output<ov::Node> input = model->input();
std::cout << "/------- [In] -------/" << std::endl;
std::cout << "Input name: " << input.get_any_name() << std::endl;
std::cout << "Input type: " << input.get_element_type().c_type_string() << std::endl;
std::cout << "Input shape: " << input.get_shape().to_string() << std::endl;
ov::Output<ov::Node> output = model->output();
std::cout << "/------- [Out] -------/" << std::endl;
std::cout << "Output name: " << output.get_any_name() << std::endl;
std::cout << "Output type: " << output.get_element_type().c_type_string() << std::endl;
std::cout << "Output shape: " << output.get_shape().to_string() << std::endl;

5 编译模型并创建推理请求

  在读取本地模型后,调用模型编译方法将模型编译为可以在目标设备上执行的 compile_model 对象,并通过该对象创建用于推断已编译模型的推断请求对象。下面是所使用的 API 方法:

API作用
Core.compile_model()将模型编译为可以在目标设备上执行的 compile_model 对象。
CompiledModel.create_infer_request()创建用于推断已编译模型的推断请求对象,创建的请求已经分配了输入和输出张量。

  在 C# 中编译模型并创建推理请求的方式:

CompiledModel compiled_model = core.compile_model(model, "AUTO");
InferRequest infer_request = compiled_model.create_infer_request();

  使用C++ API中编译模型并创建推理请求的方式:

CompiledModel compiled_model = core.compile_model(model, "AUTO");
InferRequest infer_request = compiled_model.create_infer_request();

6 张量Tensor

6.1 张量的获取与设置

  在创建推理请求后,系统会自动创建和分配输入和输出的张量,张量可以通过InferRequest 对象获得,并且可以自定义张量并加载到模型指定节点;可以根据张量的输入输出序号、名称以及模型节点Node对象获取和设置,主要C# API 如下:

API作用
InferRequest.set_tensor()设置要推断的输入/输出张量。
InferRequest.set_input_tensor()设置要推断的输入张量。
InferRequest.set_output_tensor()设置要推断的输出张量
InferRequest.get_tensor()获取用于推理的输入/输出张量。
InferRequest.get_input_tensor()获取用于推理的输入张量。
InferRequest.get_output_tensor()获取用于推理的输出张量。

6.2 张量的信息获取与设置

  张量中主要包含的信息有张量的形状(Shape)、张量的数据格式(OvType-> element.Type)以及张量中的内存数据。可以通过以下API方法操作张量的参数:

API作用
Tensor.set_shape ()给张量设置一个新的形状。
Tensor.get_shape()获取张量的形状。
Tensor.get_element_type()获取张量的数据类型。
Tensor.get_size()获取张量的数据长度。
Tensor.get_byte_size()获取张量的字节大小。
Tensor.data()获取张量的内存地址。
Tensor.set_data()将指定类型的数据加载到张量内存下。
Tensor.get_data()从张量中读取指定类型的数据。

  以上方法是对张量的一些基础操作,除了set_data、get_data是OpenVINO C# API独有的,其他接口都与C++API一致。

7 加载推理数据

7.1 获取输入张量

  对于单输入的模型可以直接通过get_input_tensor()方法获得,并调用Tensor的相关方法获取Tensor的相关信息,C# 代码如下所示:

Tensor input_tensor = infer_request.get_input_tensor();
Console.WriteLine("/------- [Input tensor] -------/");
Console.WriteLine("Input tensor type: {0}", input_tensor.get_element_type().to_string());
Console.WriteLine("Input tensor shape: {0}", input_tensor.get_shape().to_string());
Console.WriteLine("Input tensor size: {0}", input_tensor.get_size());

获取输出结果为:

/------- [Input tensor] -------/
Input tensor type: f32
Input tensor shape: Shape : {1, 3, 224, 224}
Input tensor size: 150528

对于上述的同样输出内容,我们也可以通过C++ API 实现,C++ 代码如下:

ov::Tensor input_tensor = infer_request.get_input_tensor();
std::cout << "/------- [Input tensor] -------/" << std::endl;
std::cout << "Input tensor type: " << input_tensor.get_element_type().c_type_string() << std::endl;
std::cout << "Input tensor shape: " << input_tensor.get_shape().to_string() << std::endl;
std::cout << "Input tensor size: " << input_tensor.get_size() << std::endl;

7.2 添加推理数据

  这一步主要是将处理好的图片数据加载到Tensor数据内存中,OpenVINO的API中提供了访问内存地址的接口,可以获取数据内存首地址,不过为了更好的加载推理数据,我们此处封装了set_data()方法,可以实现将处理后的图片数据加载到数据内存上。在C#中的代码为:

Mat input_mat = new Mat();
Shape input_shape = input_tensor.get_shape();
long channels = input_shape[1];
long height = input_shape[2];
long width = input_shape[3];
float[] input_data = new float[channels * height * width];
Marshal.Copy(input_mat.Ptr(0), input_data, 0, input_data.Length);
input_tensor.set_data(input_data);

下面是在C++中实现上述功能的代码:

cv::Mat input_mat;
float* input_data = input_tensor.data<float>();
ov::Shape input_shape = input_tensor.get_shape();
size_t channels = input_shape[1];
size_t height = input_shape[2];
size_t width = input_shape[3];
for (size_t c = 0; c < channels; ++c) {for (size_t h = 0; h < height; ++h) {for (size_t w = 0; w < width; ++w) {input_data[c * height * width + h * width + w] = input_mat.at<cv::Vec<float, 3>>(h, w)[c];}}
}

8 模型推理

  在加载完推理数据后,就可以调用模型推理的API方法推理当前数据,主要使用到的API方法为:

API作用
InferRequest.infer()在同步模式下推断指定的输入。

  调用该方法也较为简单,只需要调用该API接口即可,在C#中的代码为:

infer_request.infer();

C++中的代码与C++中一致。

9 获取推理结果

  对于单输出的模型可以直接通过get_output_tensor()方法获得,并调用Tensor的相关方法获取Tensor的相关信息,C# 代码如下所示:

Tensor output_tensor = infer_request.get_output_tensor();
Console.WriteLine("/------- [Output tensor] -------/");
Console.WriteLine("Output tensor type: {0}", output_tensor.get_element_type().to_string());
Console.WriteLine("Output tensor shape: {0}", output_tensor.get_shape().to_string());
Console.WriteLine("Output tensor size: {0}", output_tensor.get_size());

  获取输出output_tensor信息为:

/------- [Output tensor] -------/
Output tensor type: f32
Output tensor shape: Shape : {1, 1000}
Output tensor size: 1000

  对于输出Tensor,我们只需要读取输出内存上的数据即可,此处我们封装了get_data()方法,可以直接获取输出内存上的数据,在C#中的代码为:

float[] result = output_tensor.get_data<float>(1000);

同样获取推理结果,在C++中的代码为:

const float* output_data = output_tensor.data<const float>();
float result[1000];
for (int i = 0; i < 1000; ++i) {result[i] = *output_data;output_data++;
}

  在获取结果后,后续的处理需要根据模型的输出类型做相应的处理。

10 释放分配的内存

  由于C#在封装时采用的C API 接口实现的,因此在C#中会产生较多的 非托管内存,若该对象出现循环重复创建,会导致过多的内存未释放导致内存泄漏,因此对于临时创建的对象在使用后要即使销毁,销毁方式也较为简单,只需要调用对象的dispose()方法即可。

output_tensor.dispose();
input_shape.dispose();
infer_request.dispose();
compiled_model.dispose();
input.dispose();
output.dispose();
model.dispose();
core.dispose();

11 Yolov8分类模型示例

  下面代码展示了Yolov8分类模型使用OpenVINO C# API API方法部署模型的完整代码:

using OpenCvSharp;
using OpenCvSharp.Dnn;
using OpenVinoSharp;
using System.Data;
using System.Runtime.InteropServices;
namespace test_openvino_csharp_api
{internal class Program{static void Main(string[] args){string model_path = "E:\\GitSpace\\ OpenVINO-CSharp-API \\model\\yolov8\\yolov8s-cls.xml";Core core = new Core(); // 初始化推理核心Model model = core.read_model(model_path); // 读取本地模型CompiledModel compiled_model = core.compile_model(model, "AUTO"); // 便哟模型到指定设备// 获取模型的输入输出信息Console.WriteLine("Model name: {0}", model.get_friendly_name());Input input = compiled_model.input();Console.WriteLine("/------- [In] -------/");Console.WriteLine("Input name: {0}", input.get_any_name());Console.WriteLine("Input type: {0}", input.get_element_type().to_string());Console.WriteLine("Input shape: {0}", input.get_shape().to_string());Output output = compiled_model.output();Console.WriteLine("/------- [Out] -------/");Console.WriteLine("Output name: {0}", output.get_any_name());Console.WriteLine("Output type: {0}", output.get_element_type().to_string());Console.WriteLine("Output shape: {0}", output.get_shape().to_string());// 创建推理请求InferRequest infer_request = compiled_model.create_infer_request();// 获取输入张量Tensor input_tensor = infer_request.get_input_tensor();Console.WriteLine("/------- [Input tensor] -------/");Console.WriteLine("Input tensor type: {0}", input_tensor.get_element_type().to_string());Console.WriteLine("Input tensor shape: {0}", input_tensor.get_shape().to_string());Console.WriteLine("Input tensor size: {0}", input_tensor.get_size());// 读取并处理输入数据Mat image = Cv2.ImRead(@"E:\GitSpace\ OpenVINO-CSharp-API \dataset\image\demo_7.jpg");Mat input_mat = new Mat();input_mat = CvDnn.BlobFromImage(image, 1.0 / 255.0, new Size(224, 224), 0, true, false);// 加载推理数据Shape input_shape = input_tensor.get_shape();long channels = input_shape[1];long height = input_shape[2];long width = input_shape[3];float[] input_data = new float[channels * height * width];Marshal.Copy(input_mat.Ptr(0), input_data, 0, input_data.Length);input_tensor.set_data(input_data);// 模型推理infer_request.infer(); // 获取输出张量Tensor output_tensor = infer_request.get_output_tensor();Console.WriteLine("/------- [Output tensor] -------/");Console.WriteLine("Output tensor type: {0}", output_tensor.get_element_type().to_string());Console.WriteLine("Output tensor shape: {0}", output_tensor.get_shape().to_string());Console.WriteLine("Output tensor size: {0}", output_tensor.get_size());// 获取输出数据float[] result = output_tensor.get_data<float>(1000);List<float[]> new_list = new List<float[]> { };for (int i = 0; i < result.Length; i++){new_list.Add(new float[] { (float)result[i], i });}new_list.Sort((a, b) => b[0].CompareTo(a[0]));KeyValuePair<int, float>[] cls = new KeyValuePair<int, float>[10];for (int i = 0; i < 10; ++i){cls[i] = new KeyValuePair<int, float>((int)new_list[i][1], new_list[i][0]);}Console.WriteLine("\n Classification Top 10 result : \n");Console.WriteLine("classid probability");Console.WriteLine("------- -----------");for (int i = 0; i < 10; ++i){Console.WriteLine("{0}   {1}", cls[i].Key.ToString("0"), cls[i].Value.ToString("0.000000"));}// 销毁非托管内存output_tensor.dispose();input_shape.dispose();infer_request.dispose();compiled_model.dispose();input.dispose();output.dispose();model.dispose();core.dispose();}}
}

12 总结

  在本文中我们基于模型推理流程,演示了OpenVINO C# API使用方法,并和OpenVINO C++API进行了对比,展示了OpenVINO C# API与C++API在使用的区别,这也对使用过C++ API的开发者十分友好,上手会十分容易。

  在本文中我们只展示了基础的模型推理流程代码,也对各个API进行了测试,针对其他比较高级的API方法,我们后续会继续进行测试其他API方法,向各位开发者展示其用法。

  总的来说,目前OpenVINO C# API已经完全支持在Windows环境下的安装使用,欢迎各位开发者安装使用,如有相关问题或优化方法,也欢迎大家提出意见与指导。

相关文章:

【OpenVINO】OpenVINO C# API 常用 API 详解与演示

OpenVINO C# API 常用 API 详解与演示 1 安装OpenVINO C# API2 导入程序集 3 初始化OpenVINO 运行时内核4 加载并获取模型信息4.1 加载模型4.2 获取模型信息 5 编译模型并创建推理请求6 张量Tensor6.1 张量的获取与设置6.2 张量的信息获取与设置 7 加载推理数据7.1 获取输入张量…...

django无法导入第三方库

引子 有的人可能会很困惑&#xff0c;为什么自己在pip中安装了某个包&#xff0c;但是在django中死活无法导入。 在cmd中能够导入。 启动django&#xff0c;总是无法导入。 本文将会用一分钟解决你的困惑。 正文 那么本文以上述的第三方库dj_db_conn_pool为例&#xff0c;…...

7-k8s-helm管理

文章目录 一、为什么需要Helm二、Helm相关概念介绍三、Helm安装四、Helm指令介绍五、Helm创建tomcat六、Helm创建tomcat其他方式七、Helm创建redis 一、为什么需要Helm k8s部署&#xff1a;k8s平台部署的服务都是由资源文件描述组成&#xff0c;传统的k8s部署应用需要手工编排…...

零基础怎么样才能学好 Python?Python 入门必看

Python 目前可以用一个字来描述那就是 “火”&#xff0c;问题来了&#xff0c;这么火的语言零基础小白到底该怎样学习 Python&#xff1f; 首先&#xff0c;从基础开始学习&#xff0c;切勿毛躁。 刚开始学习 Python 的时候&#xff0c;我们可能会有些毛躁总觉得这些知识太简…...

1.X3-Warming up

/* 此程序使用 Boost Spirit 库来解析用户提供的逗号分隔的数字列表。它演示了如何使用 Spirit 来定义解析 器和执行解析操作&#xff0c;并且在用户输入时反复执行解析操作。用户可以提供一系列逗号分隔的数字&#xff0c;程序会检查它们 是否符合指定的解析规则。如果解析成功…...

【23真题】两电一邮之一,难度骤降!24可能回升!

今天分享的是23年电子科技大学858的信号与系统试题及解析。23成电858真题和22年相比&#xff0c;难度骤降&#xff01;今年我预测可能会有反弹。22年成电858真题&#xff0c;是我做过的22真题中数一数二的难度&#xff01;23年一般&#xff0c;但是题目也很好&#xff0c;真的很…...

持续集成部署-k8s-资源调度:DaemonSet

持续集成部署-k8s-资源调度:DaemonSet 1. DaemonSet 简介2. 部署 Fluent 日志收集程序1. DaemonSet 简介 在 Kubernetes 中,DaemonSet 是一种用于在集群中运行一个 Pod 副本的控制器对象。它可以保证在每个节点上都运行一个 Pod 副本,并且在节点加入或退出集群时自动地更新…...

RabbitMQ内容

RabbitMQ是一款开源的消息中间件&#xff0c;支持多个消息协议&#xff0c;包括AMQP、STOMP、MQTT等&#xff0c;它的主要功能是将分散的应用程序连接在一起&#xff0c;以便它们可以相互通信&#xff0c;从而构建可靠的、高效的分布式系统。 RabbitMQ的基础概念包括&#xff…...

搭建一个vscode+uni+vue的小程序项目

我们使用 vue2 创建工程作为示例&#xff0c;uni-app中Vue2版的组件库和插件也比较多&#xff0c;稳定、问题少&#xff0c;可以先参考下官方文档:uni-app官网 既然是使用vue脚手架&#xff0c;那肯定要全局安装vue/cli&#xff0c;已安装的可以跳过。 注意&#xff1a;Vue2创…...

处理ElementUI组件默认样式多次重复问题

问题截图&#xff1a; 解决办法&#xff1a; 在postcss.config.js文件里添加配置项&#xff1a; module.exports {plugins: {autoprefixer: {},cssnano: {} //添加这行代码}, } 处理结果&#xff1a; github issues&#xff1a; https://github.com/ElemeFE/element/is…...

配置hpa后,target显示<unknown>/50%

背景&#xff1a; 有两个服务&#xff0c;server 负责主要后端请求&#xff0c;bill 负责计量计费请求。服务都是使用 helm 部署。测试提了一个缺陷&#xff0c;说全部服务没有配置hpa。 解决一 按照之前的代码结构添加了hpa后&#xff0c;发现&#xff1a; ➜ kubectl get…...

用java实现抖音授权登录

要使用Java实现抖音授权登录&#xff0c;您需要使用抖音开放平台提供的API。以下是一个简单的Java代码示例&#xff0c;演示如何使用OAuth 2.0授权登录流程&#xff1a; 要使用Java实现抖音授权登录&#xff0c;您需要按照以下步骤进行操作&#xff1a; 创建抖音开放平台账号…...

Atlassian午餐会直播回顾:如何在Jira中进行项目时间与成本管理?

工时管理是项目过程管理的一个重要手段&#xff0c;通过科学记录项目组成员在项目执行过程中的任务完成和时间消耗情况&#xff0c;可以帮助管理者精准评估成员工作效率&#xff0c;实时掌握项目进展&#xff0c;并有效管控项目成本。 想要成为时间管理大师吗&#xff1f;在近…...

屏幕时代的数字化信息管理:从传统到纯软件的转变

随着数字化时代的推进&#xff0c;屏幕已经成为了企业和机构向外界传递信息的主要媒介。除了传统的手机和电脑屏幕&#xff0c;线下空间如办公楼、商场、店铺、医院、展厅等也需要利用屏幕来展示和发布各类信息。 管理这些屏幕和发布信息并不是一件容易的事情&#xff0c;特别是…...

Stm32_标准库_14_串口蓝牙模块_解决手机与蓝牙模块数据传输的不完整性

由手机向蓝牙模块传输时间信息&#xff0c;Stm32获取信息并将已存在信息修改为传入信息 测试代码&#xff1a; #include "stm32f10x.h" // Device header #include "Delay.h" #include "OLED.h" #include "Serial.h"uint16_t num…...

基于深度学习的“语义通信编解码技术”框架分类

目录 基于神经网络的语义提取基于神经网络的语义信源编码基于神经网络的语义信源信道联合编码基于神经网络的语义编码与数字调制联合设计参考文献 基于神经网络的语义提取 在现有的信源编码前端加上一个语义提取神经网络[53] &#xff0c;如图所示。语义提取神经网络的输入是原…...

信钰证券:股票抵押是好还是坏?

股票典当是指将持有的股票作为质押品向银行或其他金融机构融资的行为。股票典当有其优势和下风&#xff0c;下面咱们将从多个角度来剖析股票典当是否好仍是坏。 一、优势 1.占用资金少 相比较于其他融资办法&#xff0c;股票典当所需求占用的资金较少&#xff0c;只需将股票作…...

媒体基础:打开多模态大模型的新思路

编者按&#xff1a;2023年是微软亚洲研究院建院25周年。25年来&#xff0c;微软亚洲研究院探索并实践了一种独特且有效的企业研究院的新模式&#xff0c;并以此为基础产出了诸多对微软公司和全球社会都有积极影响的创新成果。一直以来&#xff0c;微软亚洲研究院致力于创造具有…...

dubbo-admin安装

一、dubbo-admin安装 1、环境准备 dubbo-admin 是一个前后端分离的项目。前端使用vue&#xff0c;后端使用springboot&#xff0c;安装 dubbo-admin 其实就是部署该项目。我们将dubbo-admin安装到开发环境上。要保证开发环境有jdk&#xff0c;maven&#xff0c;nodejs 安装no…...

Kaggle - LLM Science Exam(三):Wikipedia RAG

文章目录 一、赛事概述1.1 OpenBookQA Dataset1.2 比赛背景1.3 评估方法和代码要求1.4 比赛数据集1.5 优秀notebook 二、 [EDA, Data gathering] LLM-SE ~ Wiki STEM | 1k DS2.1 Data overview2.2 Data gathering 三、如何高效收集数据3.1 概述3.2 与训练数据关联的维基百科类别…...

【机器学习】PyTorch-MNIST-手写字识别

文章目录 前言完成效果一、下载数据集手动下载代码下载MNIST数据集&#xff1a; 二、 展示图片三、DataLoader数据加载器四、搭建神经网络五、 训练和测试第一次运行&#xff1a; 六、优化模型第二次优化后运行&#xff1a; 七、完整代码八、手写板实现输入识别功能 前言 注意…...

玩转代码| Vue 中 JSX 的特性,这一篇讲的明明白白

目录 什么时候使用JSX JSX在Vue2中的基本使用 配置 文本插值 条件与循环渲染 属性绑定 事件绑定 v-show与v-model 插槽 使用自定义组件 在method里返回JSX JSX是一种Javascript的语法扩展&#xff0c;即具备了Javascript的全部功能&#xff0c;同时又兼具html的语义…...

(vue)el-descriptions 描述列表无效

(vue)el-descriptions 描述列表无效 原因&#xff1a;element 的版本不够 解决&#xff1a;运行下面两个命令 npm uninstall element-ui //卸载之前安装的版本 npm i element-ui -S //重新安装解决参考&#xff1a;https://blog.csdn.net/weixin_59769148/article/details/1…...

ios 苹果手机日期格式问题

目录 问题解决其他 问题 ios 无法识别的时间戳格式&#xff1a;2023-10-17 11:10:49 可识别的&#xff1a; 2023/10/17 11:10:49 解决 const startTime 2023/10/17 11:10:49 startTime.replace(/-/g, /)// 获取时间差值 export const useDateDiff (startTime , endTime …...

学习嵌入式系统的推荐步骤:

学习嵌入式系统的推荐步骤&#xff1a; 00001. 选择一款Linux发行版作为主要操作系统&#xff0c;如RedHat、Ubuntu、Fedora等。进入Linux后&#xff0c;使用终端进行任务操作。建议不要使用虚拟机&#xff0c;如有需要可考虑双系统安装。 00002. 00003. 学习C语言、数…...

勒索病毒LockBit2.0 数据库(mysql与sqlsever)解锁恢复思路分享

0.前言 今天公司服务器中招LockBit2.0勒索病毒&#xff0c;损失惨重&#xff0c;全体加班了一天基本解决了部分问题&#xff0c;首先是丢失的文件数据就没法恢复了&#xff0c;这一块没有理睬&#xff0c;主要恢复的是两个数据库&#xff0c;一个是16GB大小的SQLserver数据库&…...

超简单小白攻略:如何利用黑群晖虚拟机和内网穿透实现公网访问

文章目录 前言本教程解决的问题是&#xff1a;按照本教程方法操作后&#xff0c;达到的效果是前排提醒&#xff1a; 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机&#xff1a;1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…...

Ubuntu 16.04 LTS third maintenance update release

Ubuntu 16.04 LTS (Xenial Xerus)今天迎来的第三个维护版本更新中&#xff0c;已经基于Linux Kernel 4.10内核&#xff0c;而且Mesa图形栈已经升级至17.0版本。Adam Conrad表示&#xff1a;“像此前LTS系列相似&#xff0c;16.04.3对那些使用更新硬件的用户带来了硬件优化。该版…...

Java学习_day01_hello java

构成 JDK JDK是java开发者工具&#xff0c;由JRE和一些开发工具组成。JRE JRE是java运行环境&#xff0c;由JVM和java核心类库组成。JVM JVM是java虚拟机&#xff0c;主要用来运行字节码。 执行过程 由IDE或文本编辑器&#xff0c;编写源代码&#xff0c;并将文件保存为*.ja…...

UnitTesting 单元测试

1. 测试分为两种及详细介绍测试书籍: 1.1 Unit Test : 单元测试 - test the business logic in your app : 测试应用中的业务逻辑 1.2 UI Test : 界面测试 - test the UI of your app : 测试应用中的界面 1.3 测试书籍网址:《Testing Swift》 https://www.hackingwithswift.c…...

邢台网站建设服务周到/凡科建站

【2018.02】劳特利奇国防研究手册&#xff08;第一版&#xff09;Routledge Handbook of Defence Studies&#xff0c;共412页。 如果需要电子版&#xff0c;请联系QQ&#xff1a;3042075372。 Routledge是英国的一家跨国出版社&#xff0c;总部设在伦敦&#xff0c;主要在伦敦…...

怎么做多个域名指向一个网站/外贸谷歌推广怎么样

可以使用以下 SQL 查询来实现&#xff1a; SELECT teacher_id, teacher_name, title, course_name, evaluation, evaluation_level FROM teachers JOIN courses ON teachers.teacher_id courses.teacher_id其中&#xff0c;teachers 表存储教师的信息&#xff0c;包括教师号、…...

wordpress注册防骚挠/网站定制设计

什么是容器 容器是指容纳其他物品的工具&#xff0c;物体可以被放置在容器内&#xff0c;容器可以保护其中内容物&#xff1b; Linux容器发展之路 容器技术的概念最初出现在 2000 年&#xff0c;当时称为 FreeBSD jail&#xff0c;这种技术可将 FreeBSD 系统分区为多个子系统&a…...

做网站需要前置审批/百度快速排名软件下载

chatGPT基于所谓的大模型&#xff0c;这里有两个关键词一个是“大”&#xff0c;一个是“模型”&#xff0c;我们先看什么叫“模型”。所谓模型其实就是深度学习中的神经网络&#xff0c;后者由很多个称之为“神经元”基本单元组成。神经元是一种基础计算单元&#xff0c;它执行…...

wordpress 五分钟/品牌运营推广方案

译者注 Dagger2是在Dagger1的基础上升级开发的&#xff0c;所以要学习Dagger2&#xff0c;先了解Dagger1。下文是由Dagger1的官方文档翻译而来。 参考&#xff1a; 原文链接 Dagger1项目链接 介绍 在任何应用中最好的类是那些“干活卖力”的&#xff1a;如BarcodeDecoder…...

网站方案模板/百度信息流怎么做效果好

收集到某国家145家电力企业的总成本tc、产量q、工资率pl、燃料价格pf及资本租赁价格pk的数据&#xff0c;试以总成本为因变量&#xff0c;以产量、工资率、燃料价格、租赁价格为自变量&#xff0c;建立多元线性回归研究其关系。数据文件名称为 cost.sav。第1题请以【逐步回归】…...