国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ONNX:C++通過(guò)onnxruntime使用.onnx模型進(jìn)行前向計(jì)算【下載的onnxruntime是編譯好的庫(kù)文件,可直接使用】

這篇具有很好參考價(jià)值的文章主要介紹了ONNX:C++通過(guò)onnxruntime使用.onnx模型進(jìn)行前向計(jì)算【下載的onnxruntime是編譯好的庫(kù)文件,可直接使用】。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

一、基本介紹

微軟聯(lián)合Facebook等在2017年搞了個(gè)深度學(xué)習(xí)以及機(jī)器學(xué)習(xí)模型的格式標(biāo)準(zhǔn)–ONNX,旨在將所有模型格式統(tǒng)一為一致,更方便地實(shí)現(xiàn)模型部署?,F(xiàn)在大多數(shù)的深度學(xué)習(xí)框架都支持ONNX模型轉(zhuǎn)出并提供相應(yīng)的導(dǎo)出接口。

ONNXRuntime(Open Neural Network Exchange)是微軟推出的一款針對(duì)ONNX模型格式的推理框架,用戶可以非常便利的用其運(yùn)行一個(gè)onnx模型。ONNXRuntime支持多種運(yùn)行后端包括CPU,GPU,TensorRT,DML等??梢哉f(shuō)ONNXRuntime是對(duì)ONNX模型最原生的支持,只要掌握模型導(dǎo)出的相應(yīng)操作,便能對(duì)將不同框架的模型進(jìn)行部署,提高開(kāi)發(fā)效率。

利用onnx和onnxruntime實(shí)現(xiàn)pytorch深度框架使用C++推理進(jìn)行服務(wù)器部署,模型推理的性能是比python快很多的。

1、下載

GitHub下載地址:

https://github.com/microsoft/onnxruntime/releases

?Release ONNX Runtime v1.9.0 · microsoft/onnxruntime · GitHub

onnxruntime-linux-x64-1.9.0.tgz?

2、解壓

下載的onnxruntime是直接編譯好的庫(kù)文件,直接放在自定義的文件夾中即可。在CMakeLists.txt中引入onnxruntime的頭文件、庫(kù)文件即可。

# 引入頭文件
include_directories(......../onnxruntime/include)
# 引入庫(kù)文件
link_directories(......../onnxruntime/lib)

二、Pytorch導(dǎo)出.onnx模型

首先,利用pytorch自帶的torch.onnx模塊導(dǎo)出?.onnx?模型文件,具體查看該部分pytorch官方文檔,主要流程如下:

import torch
checkpoint = torch.load(model_path)
model = ModelNet(params)
model.load_state_dict(checkpoint['model'])
model.eval()

input_x_1 = torch.randn(10,20)
input_x_2 = torch.randn(1,20,5)
output, mask = model(input_x_1, input_x_2)

torch.onnx.export(model,
                 (input_x_1, input_x_2),
                 'model.onnx',
                 input_names = ['input','input_mask'],
                 output_names = ['output','output_mask'],
                 opset_version=11,
                 verbose = True,
                 dynamic_axes={'input':{1,'seqlen'}, 'input_mask':{1:'seqlen',2:'time'},'output_mask':{0:'time'}})

torch.onnx.export參數(shù)在文檔里面都有,opset_version對(duì)應(yīng)的版本很重要,dynamic_axes是對(duì)輸入和輸出對(duì)應(yīng)維度可以進(jìn)行動(dòng)態(tài)設(shè)置,不設(shè)置的話輸入和輸出的Tensor 的 shape是不能改變的,如果輸入固定就不需要加。

導(dǎo)出的模型可否順利使用可以先使用python進(jìn)行檢測(cè)

import onnxruntime as ort
import numpy as np
ort_session = ort.InferenceSession('model.onnx')
outputs = ort_session.run(None,{'input':np.random.randn(10,20),'input_mask':np.random.randn(1,20,5)})
# 由于設(shè)置了dynamic_axes,支持對(duì)應(yīng)維度的變化
outputs = ort_session.run(None,{'input':np.random.randn(10,5),'input_mask':np.random.randn(1,26,2)})
# outputs 為 包含'output'和'output_mask'的list

import onnx
model = onnx.load('model.onnx')
onnx.checker.check_model(model)

如果沒(méi)有異常代表導(dǎo)出的模型沒(méi)有問(wèn)題,目前torch.onnx.export只能對(duì)部分支持的Tensor操作進(jìn)行識(shí)別,詳情參考Supported operators,對(duì)于包括transformer等基本的模型都是沒(méi)有問(wèn)題的,如果出現(xiàn)ATen等問(wèn)題,你就需要對(duì)模型不支持的Tensor操作進(jìn)行改進(jìn),以免影響C++對(duì)該模型的使用。

三、模型推理流程

總體來(lái)看,整個(gè)ONNXRuntime的運(yùn)行可以分為三個(gè)階段:

  • Session構(gòu)造;
  • 模型加載與初始化;
  • 運(yùn)行;

c++ onnxruntime,# C++/ONNX,pytorch,人工智能,python

1、第1階段:Session構(gòu)造

構(gòu)造階段即創(chuàng)建一個(gè)InferenceSession對(duì)象。在python前端構(gòu)建Session對(duì)象時(shí),python端會(huì)通過(guò)http://onnxruntime_pybind_state.cc調(diào)用C++中的InferenceSession類構(gòu)造函數(shù),得到一個(gè)InferenceSession對(duì)象。

InferenceSession構(gòu)造階段會(huì)進(jìn)行各個(gè)成員的初始化,成員包括負(fù)責(zé)OpKernel管理的KernelRegistryManager對(duì)象,持有Session配置信息的SessionOptions對(duì)象,負(fù)責(zé)圖分割的GraphTransformerManager,負(fù)責(zé)log管理的LoggingManager等。當(dāng)然,這個(gè)時(shí)候InferenceSession就是一個(gè)空殼子,只完成了對(duì)成員對(duì)象的初始構(gòu)建。

2、第2階段:模型加載與初始化

在完成InferenceSession對(duì)象的構(gòu)造后,會(huì)將onnx模型加載到InferenceSession中并進(jìn)行進(jìn)一步的初始化。

2.1. 模型加載

模型加載時(shí),會(huì)在C++后端會(huì)調(diào)用對(duì)應(yīng)的Load()函數(shù),InferenceSession一共提供了8種Load函數(shù)。包讀從url,ModelProto,void* model data,model istream等讀取ModelProto。InferenceSession會(huì)對(duì)ModelProto進(jìn)行解析然后持有其對(duì)應(yīng)的Model成員。

2.2. Providers注冊(cè)

在Load函數(shù)結(jié)束后,InferenceSession會(huì)調(diào)用兩個(gè)函數(shù):RegisterExecutionProviders()和sess->Initialize();

RegisterExecutionProviders函數(shù)會(huì)完成ExecutionProvider的注冊(cè)工作。這里解釋一下ExecutionProvider,ONNXRuntime用Provider表示不同的運(yùn)行設(shè)備比如CUDAProvider等。目前ONNXRuntimev1.0支持了包括CPU,CUDA,TensorRT,MKL等七種Providers。通過(guò)調(diào)用sess->RegisterExecutionProvider()函數(shù),InferenceSession通過(guò)一個(gè)list持有當(dāng)前運(yùn)行環(huán)境中支持的ExecutionProviders。

2.3. InferenceSession初始化

即sess->Initialize(),這時(shí)InferenceSession會(huì)根據(jù)自身持有的model和execution providers進(jìn)行進(jìn)一步的初始化(在第一階段Session構(gòu)造時(shí)僅僅持有了空殼子成員變量)。該步驟是InferenceSession初始化的核心,一系列核心操作如內(nèi)存分配,model partition,kernel注冊(cè)等都會(huì)在這個(gè)階段完成。

  1. 首先,session會(huì)根據(jù)level注冊(cè) graph optimization transformers,并通過(guò)GraphTransformerManager成員進(jìn)行持有。
  2. 接下來(lái)session會(huì)進(jìn)行OpKernel注冊(cè),OpKernel即定義的各個(gè)node對(duì)應(yīng)在不同運(yùn)行設(shè)備上的計(jì)算邏輯。這個(gè)過(guò)程會(huì)將持有的各個(gè)ExecutionProvider上定義的所有node對(duì)應(yīng)的Kernel注冊(cè)到session中,session通過(guò)KernelRegistryManager成員進(jìn)行持有和管理。
  3. 然后session會(huì)對(duì)Graph進(jìn)行圖變換,包括插入copy節(jié)點(diǎn),cast節(jié)點(diǎn)等。
  4. 接下來(lái)是model partition,也就是根運(yùn)行設(shè)備對(duì)graph進(jìn)行切分,決定每個(gè)node運(yùn)行在哪個(gè)provider上。
  5. 最后,為每個(gè)node創(chuàng)建ExecutePlan,運(yùn)行計(jì)劃主要包含了各個(gè)op的執(zhí)行順序,內(nèi)存申請(qǐng)管理,內(nèi)存復(fù)用管理等操作。

3、第3階段:模型運(yùn)行

模型運(yùn)行即InferenceSession每次讀入一個(gè)batch的數(shù)據(jù)并進(jìn)行計(jì)算得到模型的最終輸出。然而其實(shí)絕大多數(shù)的工作早已經(jīng)在InferenceSession初始化階段完成。細(xì)看下源碼就會(huì)發(fā)現(xiàn)run階段主要是順序調(diào)用各個(gè)node的對(duì)應(yīng)OpKernel進(jìn)行計(jì)算。

四、代碼

和其他所有主流框架相同,ONNXRuntime最常用的語(yǔ)言是python,而實(shí)際負(fù)責(zé)執(zhí)行框架運(yùn)行的則是C++。

下面就是C++通過(guò)onnxruntime對(duì).onnx模型的使用,參考官方樣例和常見(jiàn)問(wèn)題寫的模型多輸入多輸出的情況,部分參數(shù)可以參考樣例或者查官方API文檔。

1、案例01

BasicOrtHandler.h

#include "onnxruntime_cxx_api.h"
#include "opencv2/opencv.hpp"
#include <vector>
#define CHW 0
class BasicOrtHandler {
public:
    Ort::Value BasicOrtHandler::create_tensor(const cv::Mat &mat, const std::vector<int64_t> &tensor_dims, const Ort::MemoryInfo &memory_info_handler, std::vector<float> &tensor_value_handler, unsigned int data_format);
protected:
    Ort::Env ort_env;
    Ort::Session *ort_session = nullptr;
    const char *input_name = nullptr;
    std::vector<const char *> input_node_names;
    std::vector<int64_t> input_node_dims; // 1 input only.
    std::size_t input_tensor_size = 1;
    std::vector<float> input_values_handler;
    // create input tensor
    Ort::MemoryInfo memory_info_handler = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
    std::vector<const char *> output_node_names;
    std::vector<std::vector<int64_t>> output_node_dims; // >=1 outputs
    const char*onnx_path = nullptr;
    const char *log_id = nullptr;
    int num_outputs = 1;
protected:
    const unsigned int num_threads; // initialize at runtime.
protected:
    explicit BasicOrtHandler(const std::string &_onnx_path, unsigned int _num_threads = 1);
    virtual ~BasicOrtHandler();
protected:
    BasicOrtHandler(const BasicOrtHandler &) = delete;
    BasicOrtHandler(BasicOrtHandler &&) = delete;
    BasicOrtHandler &operator=(const BasicOrtHandler &) = delete;
    BasicOrtHandler &operator=(BasicOrtHandler &&) = delete;
protected:
    virtual Ort::Value transform(const cv::Mat &mat) = 0;
private:
    void initialize_handler();
};

BasicOrtHandler.cpp

BasicOrtHandler::BasicOrtHandler(const std::string &_onnx_path, unsigned int _num_threads) : log_id(_onnx_path.data()), num_threads(_num_threads) {
// string to wstring
#ifdef LITE_WIN32
    std::wstring _w_onnx_path(lite::utils::to_wstring(_onnx_path));
  onnx_path = _w_onnx_path.data();
#else
    onnx_path = _onnx_path.data();
#endif
    initialize_handler();
}

void BasicOrtHandler::initialize_handler() {
    // set ort env
    ort_env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, log_id);
    // 0. session options
    Ort::SessionOptions session_options;
    // set op threads
    session_options.SetIntraOpNumThreads(num_threads);
    // set Optimization options:
    session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);
    // set log level
    session_options.SetLogSeverityLevel(4);

    // GPU compatiable.
    // OrtCUDAProviderOptions provider_options;
    // session_options.AppendExecutionProvider_CUDA(provider_options);
    // #ifdef USE_CUDA
    //  OrtSessionOptionsAppendExecutionProvider_CUDA(session_options, 0); // C API stable.
    // #endif

    // 1. session
    ort_session = new Ort::Session(ort_env, onnx_path, session_options);
    // memory allocation and options
    Ort::AllocatorWithDefaultOptions allocator;
    // 2. input name & input dims
    input_name = ort_session->GetInputName(0, allocator);
    input_node_names.resize(1);
    input_node_names[0] = input_name;
    // 3. input names & output dimms
    Ort::TypeInfo type_info = ort_session->GetInputTypeInfo(0);
    auto tensor_info = type_info.GetTensorTypeAndShapeInfo();
    input_tensor_size = 1;
    input_node_dims = tensor_info.GetShape();

    for (unsigned int i = 0; i < input_node_dims.size(); ++i) {
        input_tensor_size *= input_node_dims.at(i);
    }
    input_values_handler.resize(input_tensor_size);
    // 4. output names & output dimms
    num_outputs = ort_session->GetOutputCount();
    output_node_names.resize(num_outputs);
    for (unsigned int i = 0; i < num_outputs; ++i) {
        output_node_names[i] = ort_session->GetOutputName(i, allocator);
        Ort::TypeInfo output_type_info = ort_session->GetOutputTypeInfo(i);
        auto output_tensor_info = output_type_info.GetTensorTypeAndShapeInfo();
        auto output_dims = output_tensor_info.GetShape();
        output_node_dims.push_back(output_dims);
    }
}

Ort::Value BasicOrtHandler::create_tensor(const cv::Mat &mat, const std::vector<int64_t> &tensor_dims, const Ort::MemoryInfo &memory_info_handler, std::vector<float> &tensor_value_handler, unsigned int data_format) throw(std::runtime_error) {
    const unsigned int rows = mat.rows;
    const unsigned int cols = mat.cols;
    const unsigned int channels = mat.channels();

    cv::Mat mat_ref;
    if (mat.type() != CV_32FC(channels)){
        mat.convertTo(mat_ref, CV_32FC(channels));
    } else{
        mat_ref = mat;  // reference only. zero-time cost. support 1/2/3/... channels
    }
    if (tensor_dims.size() != 4) {
        throw std::runtime_error("dims mismatch.");
    }
    if (tensor_dims.at(0) != 1) {
        throw std::runtime_error("batch != 1");
    }
    // CXHXW
    if (data_format == CHW) {
        const unsigned int target_channel = tensor_dims.at(1);
        const unsigned int target_height = tensor_dims.at(2);
        const unsigned int target_width = tensor_dims.at(3);
        const unsigned int target_tensor_size = target_channel * target_height * target_width;
        if (target_channel != channels) {
            throw std::runtime_error("channel mismatch.");
        }
        tensor_value_handler.resize(target_tensor_size);
        cv::Mat resize_mat_ref;
        if (target_height != rows || target_width != cols) {
            cv::resize(mat_ref, resize_mat_ref, cv::Size(target_width, target_height));
        } else{
            resize_mat_ref = mat_ref; // reference only. zero-time cost.
        }
        std::vector<cv::Mat> mat_channels;
        cv::split(resize_mat_ref, mat_channels);
        // CXHXW
        for (unsigned int i = 0; i < channels; ++i){
            std::memcpy(tensor_value_handler.data() + i * (target_height * target_width), mat_channels.at(i).data,target_height * target_width * sizeof(float));
        }
        return Ort::Value::CreateTensor<float>(memory_info_handler, tensor_value_handler.data(), target_tensor_size, tensor_dims.data(), tensor_dims.size());
    }
    // HXWXC
    const unsigned int target_channel = tensor_dims.at(3);
    const unsigned int target_height = tensor_dims.at(1);
    const unsigned int target_width = tensor_dims.at(2);
    const unsigned int target_tensor_size = target_channel * target_height * target_width;
    if (target_channel != channels) {
        throw std::runtime_error("channel mismatch!");
    }
    tensor_value_handler.resize(target_tensor_size);
    cv::Mat resize_mat_ref;
    if (target_height != rows || target_width != cols) {
        cv::resize(mat_ref, resize_mat_ref, cv::Size(target_width, target_height));
    } else {
        resize_mat_ref = mat_ref; // reference only. zero-time cost.
    }
    std::memcpy(tensor_value_handler.data(), resize_mat_ref.data, target_tensor_size * sizeof(float));
    return Ort::Value::CreateTensor<float>(memory_info_handler, tensor_value_handler.data(), target_tensor_size, tensor_dims.data(), tensor_dims.size());
}

main.cpp

const std::string _onnx_path="";
unsigned int _num_threads = 1;

//init inference
BasicOrtHandler basicOrtHandler(_onnx_path,_num_threads);

// after transform image
const cv::Mat mat = "";
const std::vector<int64_t> &tensor_dims = basicOrtHandler.input_node_dims;
const Ort::MemoryInfo &memory_info_handler = basicOrtHandler.memory_info_handler;
std::vector<float> &tensor_value_handler = basicOrtHandler.input_values_handler;
unsigned int data_format = CHW; // 預(yù)處理后的模式

// 1. make input tensor
Ort::Value input_tensor = basicOrtHandler.create_tensor(mat_rs);

// 2. inference scores & boxes.
auto output_tensors = ort_session->Run(Ort::RunOptions{nullptr}, input_node_names.data(), &input_tensor, 1, output_node_names.data(), num_outputs);

// 3. get output tensor
Ort::Value &pred = output_tensors.at(0); // (1,n,c)

//postprocess
...

2、案例02 ?

#include <assert.h>
#include <vector>
#include <onnxruntime_cxx_api.h>

int main(int argc, char* argv[]) {
  Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "test");
  Ort::SessionOptions session_options;
  session_options.SetIntraOpNumThreads(1);
  
  session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_EXTENDED);

#ifdef _WIN32
  const wchar_t* model_path = L"model.onnx";
#else
  const char* model_path = "model.onnx";
#endif

  Ort::Session session(env, model_path, session_options);
  // print model input layer (node names, types, shape etc.)
  Ort::AllocatorWithDefaultOptions allocator;

  // print number of model input nodes
  size_t num_input_nodes = session.GetInputCount();
  std::vector<const char*> input_node_names = {"input","input_mask"};
  std::vector<const char*> output_node_names = {"output","output_mask"};
    
  std::vector<int64_t> input_node_dims = {10, 20};
  size_t input_tensor_size = 10 * 20; 
  std::vector<float> input_tensor_values(input_tensor_size);
  for (unsigned int i = 0; i < input_tensor_size; i++)
    input_tensor_values[i] = (float)i / (input_tensor_size + 1);
  // create input tensor object from data values
  auto memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
  Ort::Value input_tensor = Ort::Value::CreateTensor<float>(memory_info, input_tensor_values.data(), input_tensor_size, input_node_dims.data(), 2);
  assert(input_tensor.IsTensor());

  std::vector<int64_t> input_mask_node_dims = {1, 20, 4};
  size_t input_mask_tensor_size = 1 * 20 * 4; 
  std::vector<float> input_mask_tensor_values(input_mask_tensor_size);
  for (unsigned int i = 0; i < input_mask_tensor_size; i++)
    input_mask_tensor_values[i] = (float)i / (input_mask_tensor_size + 1);
  // create input tensor object from data values
  auto mask_memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
  Ort::Value input_mask_tensor = Ort::Value::CreateTensor<float>(mask_memory_info, input_mask_tensor_values.data(), input_mask_tensor_size, input_mask_node_dims.data(), 3);
  assert(input_mask_tensor.IsTensor());
    
  std::vector<Ort::Value> ort_inputs;
  ort_inputs.push_back(std::move(input_tensor));
  ort_inputs.push_back(std::move(input_mask_tensor));
  // score model & input tensor, get back output tensor
  auto output_tensors = session.Run(Ort::RunOptions{nullptr}, input_node_names.data(), ort_inputs.data(), ort_inputs.size(), output_node_names.data(), 2);
  
  // Get pointer to output tensor float values
  float* floatarr = output_tensors[0].GetTensorMutableData<float>();
  float* floatarr_mask = output_tensors[1].GetTensorMutableData<float>();
  
  printf("Done!\n");
  return 0;
}

編譯命令:

g++ infer.cpp -o infer onnxruntime-linux-x64-1.4.0/lib/libonnxruntime.so.1.4.0 -Ionnxruntime-linux-x64-1.4.0/include/ -std=c++11

onnxruntime中Tensor支持的數(shù)據(jù)類型包括:

typedef enum ONNXTensorElementDataType {
  ONNX_TENSOR_ELEMENT_DATA_TYPE_UNDEFINED,
  ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT,   // maps to c type float
  ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8,   // maps to c type uint8_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_INT8,    // maps to c type int8_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT16,  // maps to c type uint16_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_INT16,   // maps to c type int16_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32,   // maps to c type int32_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64,   // maps to c type int64_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_STRING,  // maps to c++ type std::string
  ONNX_TENSOR_ELEMENT_DATA_TYPE_BOOL,
  ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT16,
  ONNX_TENSOR_ELEMENT_DATA_TYPE_DOUBLE,      // maps to c type double
  ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT32,      // maps to c type uint32_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT64,      // maps to c type uint64_t
  ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX64,   // complex with float32 real and imaginary components
  ONNX_TENSOR_ELEMENT_DATA_TYPE_COMPLEX128,  // complex with float64 real and imaginary components
  ONNX_TENSOR_ELEMENT_DATA_TYPE_BFLOAT16     // Non-IEEE floating-point format based on IEEE754 single-precision
} ONNXTensorElementDataType;

其中需要注意的是使用bool型,需要從uint_8的vector轉(zhuǎn)為bool型:

std::vector<uint8_t> mask_tensor_values;
for(int i = 0; i < mask_tensor_size; i++){
	mask_tensor_values.push_back((uint8_t)(true));
}
auto mask_memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
Ort::Value mask_tensor = Ort::Value::CreateTensor<bool>(mask_memory_info, reinterpret_cast<bool *>(mask_tensor_values.data()),mask_tensor_size, mask_node_dims.data(), 3);

性能測(cè)試

實(shí)際情況粗略統(tǒng)計(jì),以transformer為例,onnxruntime-c++上的運(yùn)行效率要比pytorch-python快2-5倍

C++-onnx:用onnxruntime部署自己的模型_u013250861的博客-CSDN博客

ONNX Runtime使用簡(jiǎn)單介紹_竹葉青l(xiāng)vye的博客-CSDN博客_onnxruntime 使用

onnxruntime的c++使用_chencision的博客-CSDN博客_c++ onnxruntime

onnxruntime C++ 使用(一)_SongpingWang的技術(shù)博客_51CTO博客

OnnxRunTime的推理流程_hjxu2016的博客-CSDN博客_onnxruntime

onnxruntime安裝與使用(附實(shí)踐中發(fā)現(xiàn)的一些問(wèn)題)_本初-ben的博客-CSDN博客_onnxruntime安裝文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-611766.html

到了這里,關(guān)于ONNX:C++通過(guò)onnxruntime使用.onnx模型進(jìn)行前向計(jì)算【下載的onnxruntime是編譯好的庫(kù)文件,可直接使用】的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【ONNX】使用 C++ 調(diào)用 ONNX 格式的 PyTorch 深度學(xué)習(xí)模型進(jìn)行預(yù)測(cè)(Windows, C++, PyTorch, ONNX, Visual Studio, OpenCV)

    【ONNX】使用 C++ 調(diào)用 ONNX 格式的 PyTorch 深度學(xué)習(xí)模型進(jìn)行預(yù)測(cè)(Windows, C++, PyTorch, ONNX, Visual Studio, OpenCV)

    要使用 ONNX 模型進(jìn)行預(yù)測(cè),就需要使用 onnx runtime 首先到 ONNX 官網(wǎng)查詢所需的版本 這里使用的 Windows,同時(shí)裝了 CUDA 下面的鏈接可以進(jìn)入到安裝網(wǎng)址 https://www.nuget.org/packages/Microsoft.ML.OnnxRuntime.Gpu 安裝命令為: 首先打開(kāi) Visual Studio 2019 新建一個(gè)用于測(cè)試的項(xiàng)目 右鍵點(diǎn)擊項(xiàng)目,可

    2024年02月09日
    瀏覽(23)
  • Android+OnnxRuntime+Opencv+Onnx模型操作圖片擦除多余內(nèi)容

    今年來(lái)AI的發(fā)展非常迅速,在工業(yè)、醫(yī)療等等行業(yè)逐漸出現(xiàn)相應(yīng)的解決方案,AI也逐漸成為各行業(yè)基礎(chǔ)設(shè)施建設(shè)重要的一環(huán),未來(lái)發(fā)展的大趨勢(shì),不過(guò)這也需要一個(gè)漫長(zhǎng)的過(guò)程,需要很多技術(shù)型人才加入其中,除了工業(yè)設(shè)施的基礎(chǔ)建設(shè),在娛樂(lè)方向也有很多有趣的能力,不如圖

    2024年04月13日
    瀏覽(41)
  • 【環(huán)境搭建:onnx模型部署】onnxruntime-gpu安裝與測(cè)試(python)

    【環(huán)境搭建:onnx模型部署】onnxruntime-gpu安裝與測(cè)試(python)

    onnx 模型在 CPU 上進(jìn)行推理,在conda環(huán)境中直接使用pip安裝即可 想要 onnx 模型在 GPU 上加速推理,需要安裝 onnxruntime-gpu 。有兩種思路: 依賴于 本地主機(jī) 上已安裝的 cuda 和 cudnn 版本 不依賴于 本地主機(jī) 上已安裝的 cuda 和 cudnn 版本 要注意:onnxruntime-gpu, cuda, cudnn三者的版本要對(duì)

    2024年02月07日
    瀏覽(25)
  • ONNX格式模型 學(xué)習(xí)筆記 (onnxRuntime部署)---用java調(diào)用yolov8模型來(lái)舉例

    ONNX格式模型 學(xué)習(xí)筆記 (onnxRuntime部署)---用java調(diào)用yolov8模型來(lái)舉例

    ONNX(Open Neural Network Exchange)是一個(gè)開(kāi)源項(xiàng)目,旨在建立一個(gè)開(kāi)放的標(biāo)準(zhǔn),使深度學(xué)習(xí)模型 可以在不同的軟件平臺(tái)和工具之間輕松移動(dòng)和重用 。 ONNX模型可以用于各種應(yīng)用場(chǎng)景,例如機(jī)器翻譯、圖像識(shí)別、語(yǔ)音識(shí)別、自然語(yǔ)言處理等。 由于ONNX模型的互操作性,開(kāi)發(fā)人員 可以

    2024年01月22日
    瀏覽(26)
  • python使用onnx模型進(jìn)行推理

    我們可以看到基于YoloV7訓(xùn)練的cfg有兩種yaml文件,一個(gè)是training文件夾,一個(gè)是deploy文件夾,這兩種文件夾有啥不一樣呢??? 大家可以看下下面別人的issuse,,記住這個(gè)很關(guān)鍵,就是你選擇哪個(gè)yaml訓(xùn)練對(duì)你后面導(dǎo)出的onnx是很關(guān)鍵的,后面我們會(huì)說(shuō)到。 1、training中的yaml文件

    2024年02月12日
    瀏覽(17)
  • 【OnnxRuntime】在linux下編譯并安裝C++版本的onnx-runtime

    安裝CMake:可以通過(guò)包管理器(如apt、yum等)安裝CMake。 安裝C++編譯器:確保系統(tǒng)中已安裝C++編譯器,如GCC或Clang。 克隆ONNX Runtime的GitHub倉(cāng)庫(kù),指定版本是為了適配python3.8: 進(jìn)入ONNX Runtime的源代碼目錄: // 首先創(chuàng)建一個(gè)conda環(huán)境,因?yàn)?/build.sh實(shí)際上調(diào)用的是./tools/cl_build/bui

    2024年02月08日
    瀏覽(52)
  • Azure 機(jī)器學(xué)習(xí) - 使用 ONNX 對(duì)來(lái)自 AutoML 的計(jì)算機(jī)視覺(jué)模型進(jìn)行預(yù)測(cè)

    Azure 機(jī)器學(xué)習(xí) - 使用 ONNX 對(duì)來(lái)自 AutoML 的計(jì)算機(jī)視覺(jué)模型進(jìn)行預(yù)測(cè)

    本文介紹如何使用 Open Neural Network Exchange (ONNX) 對(duì)從 Azure 機(jī)器學(xué)習(xí)中的自動(dòng)機(jī)器學(xué)習(xí) (AutoML) 生成的計(jì)算機(jī)視覺(jué)模型進(jìn)行預(yù)測(cè)。 關(guān)注TechLead,分享AI全維度知識(shí)。作者擁有10+年互聯(lián)網(wǎng)服務(wù)架構(gòu)、AI產(chǎn)品研發(fā)經(jīng)驗(yàn)、團(tuán)隊(duì)管理經(jīng)驗(yàn),同濟(jì)本復(fù)旦碩,復(fù)旦機(jī)器人智能實(shí)驗(yàn)室成員,阿里云

    2024年02月05日
    瀏覽(15)
  • [C++]使用純opencv去部署yolov9的onnx模型

    [C++]使用純opencv去部署yolov9的onnx模型

    【介紹】 部署 YOLOv9 ONNX 模型在 OpenCV 的 C++ 環(huán)境中涉及一系列步驟。以下是一個(gè)簡(jiǎn)化的部署方案概述,以及相關(guān)的文案。 部署方案概述: 模型準(zhǔn)備 :首先,你需要確保你有 YOLOv9 的 ONNX 模型文件。這個(gè)文件包含了模型的結(jié)構(gòu)和權(quán)重。 環(huán)境配置 :安裝 OpenCV 庫(kù),并確保它支持

    2024年03月13日
    瀏覽(58)
  • [C++]使用yolov8的onnx模型僅用opencv和bytetrack實(shí)現(xiàn)目標(biāo)追蹤

    [C++]使用yolov8的onnx模型僅用opencv和bytetrack實(shí)現(xiàn)目標(biāo)追蹤

    【官方框架地址】 yolov8: https://github.com/ultralytics/ultralytics bytetrack: https://github.com/ifzhang/ByteTrack 【算法介紹】 隨著人工智能技術(shù)的不斷發(fā)展,目標(biāo)追蹤已成為計(jì)算機(jī)視覺(jué)領(lǐng)域的重要研究方向。Yolov8和ByTetrack作為當(dāng)前先進(jìn)的算法,當(dāng)它們結(jié)合使用時(shí),能夠顯著提升目標(biāo)追蹤的準(zhǔn)

    2024年01月24日
    瀏覽(26)
  • 使用Anomalib項(xiàng)目的padim無(wú)監(jiān)督算法 進(jìn)行自制工業(yè)缺陷數(shù)據(jù)集的模型訓(xùn)練和ONNX部署(一)——模型訓(xùn)練篇

    使用Anomalib項(xiàng)目的padim無(wú)監(jiān)督算法 進(jìn)行自制工業(yè)缺陷數(shù)據(jù)集的模型訓(xùn)練和ONNX部署(一)——模型訓(xùn)練篇

    目錄 前言? 一、無(wú)監(jiān)督學(xué)習(xí)缺陷檢測(cè) Anomalib介紹 二、Anomalib代碼結(jié)構(gòu) 三、任務(wù)描述和模型訓(xùn)練推理 四、總結(jié)與展望 ? ? ? ? 本文專注于padim算法在自制數(shù)據(jù)集上的訓(xùn)練過(guò)程,博主水平有限,對(duì)神經(jīng)網(wǎng)絡(luò)模型秉持能用就行的態(tài)度,所以文中不涉及網(wǎng)絡(luò)結(jié)構(gòu)和論文細(xì)節(jié)的解讀,

    2024年02月16日
    瀏覽(20)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包