深度學習模型在C++平臺的部署

一、概述

??深度學習模型能夠在各種生產場景中發揮重要的作用,而深度學習模型往往在Python環境下完成訓練,因而訓練好的模型如何在生產環境下實現穩定可靠的部署,便是一個重要內容。C++開發平臺廣泛存在于各種復雜的生產環境,隨著業務效能需求的不斷提高,充分運用深度學習技術的優勢顯得尤為重要。本文介紹如何實現將深度學習模型部署在C++平臺上。

二、步驟

??s1. Python環境中安裝深度學習框架(如PyTorch、TensorFlow等);

??s2. P ython環境中設計并訓練深度學習模型;

??s3. 將訓練好的模型保存為.onnx格式的模型文件;

??s4. C++環境中安裝Microsoft.ML.OnnxRuntime程序包;
(Visual Studio 2022中可通過項目->管理NuGet程序包完成快捷安裝)

??s5. C++環境中加載模型文件,完成功能開發。

三、示例

??在Python環境下設計并訓練一個關于手寫數字識別的卷積神經網絡(CNN)模型,將模型導出為ONNX格式的文件,然后在C++環境下完成對模型的部署和推理。

1. Python訓練和導出

import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.functional import F# 定義簡單的CNN模型
class SimpleCNN(nn.Module):def __init__(self):super(SimpleCNN, self).__init__()self.conv1 = nn.Conv2d(1, 16, kernel_size=3, stride=1, padding=1)self.pool = nn.MaxPool2d(2, 2)self.conv2 = nn.Conv2d(16, 32, kernel_size=3, stride=1, padding=1)self.fc1 = nn.Linear(32 * 7 * 7, 128)self.fc2 = nn.Linear(128, 10)def forward(self, x):x = self.pool(F.relu(self.conv1(x)))x = self.pool(F.relu(self.conv2(x)))x = x.view(-1, 32 * 7 * 7)x = F.relu(self.fc1(x))x = self.fc2(x)return x# 數據預處理
transform = transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.1307,), (0.3081,))
])# 加載訓練數據
train_dataset = datasets.MNIST('data', train=True, download=True, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)# 初始化模型、損失函數和優化器
model = SimpleCNN()
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)# 訓練模型
def train(model, train_loader, criterion, optimizer, epochs=5):model.train()for epoch in range(epochs):running_loss = 0.0for batch_idx, (data, target) in enumerate(train_loader):optimizer.zero_grad()output = model(data)loss = criterion(output, target)loss.backward()optimizer.step()running_loss += loss.item()print(f'Epoch {epoch+1}, Loss: {running_loss/len(train_loader)}')# 訓練模型
train(model, train_loader, criterion, optimizer)# 導出為ONNX格式
dummy_input = torch.randn(1, 1, 28, 28)
torch.onnx.export(model,dummy_input,"mnist_model.onnx",export_params=True,opset_version=11,do_constant_folding=True,input_names=['input'],output_names=['output'],dynamic_axes={'input': {0: 'batch_size'}, 'output': {0: 'batch_size'}}
)print("模型已成功導出為mnist_model.onnx")

在這里插入圖片描述

2. C++ 部署和推理

#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>
#include <onnxruntime_cxx_api.h>int main() {// 初始化環境Ort::Env env(ORT_LOGGING_LEVEL_WARNING, "MNIST");Ort::SessionOptions session_options;session_options.SetIntraOpNumThreads(1);session_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);// 加載模型std::wstring model_path = L"mnist_model.onnx";Ort::Session session(env, model_path.c_str(), session_options);// 準備輸入std::vector<int64_t> input_shape = { 1, 1, 28, 28 };size_t input_tensor_size = 28 * 28;std::vector<float> input_tensor_values(input_tensor_size);// 讀取測試圖片cv::Mat test_image = cv::imread("test.jpg", cv::IMREAD_GRAYSCALE);         // 將Mat數據復制到vector中for (int i = 0; i < test_image.rows; ++i) {for (int j = 0; j < test_image.cols; ++j) {input_tensor_values[i * test_image.cols + j] = static_cast<float>(test_image.at<uchar>(i, j)); // 注意:uchar是unsigned char的縮寫,表示無符號字符,通常用于存儲灰度值}}// 創建輸入張量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_shape.data(), 4);// 設置輸入輸出名稱std::vector<const char*> input_names;std::vector<const char*> output_names;input_names.push_back(session.GetInputNameAllocated(0, Ort::AllocatorWithDefaultOptions()).get());output_names.push_back(session.GetOutputNameAllocated(0, Ort::AllocatorWithDefaultOptions()).get());// 運行推理auto output_tensors = session.Run(Ort::RunOptions{ nullptr },input_names.data(),&input_tensor,1,output_names.data(),1);// 獲取輸出結果float* output = output_tensors[0].GetTensorMutableData<float>();std::vector<float> results(output, output + 10);// 找到預測的數字int predicted_digit = 0;float max_probability = results[0];for (int i = 1; i < 10; i++) {if (results[i] > max_probability) {max_probability = results[i];predicted_digit = i;}}std::cout << "預測結果: " << predicted_digit << std::endl;std::cout << "置信度分布:" << std::endl;for (int i = 0; i < 10; i++) {std::cout << "數字 " << i << ": " << results[i] << std::endl;}return 0;
}

測試圖片:
在這里插入圖片描述

程序運行:
在這里插入圖片描述



End.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/88249.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/88249.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/88249.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

若以部署在linux,nginx反向代理,登錄404,刷新404問題

history模式在router下面的index.js文件的最下面history: createWebHistory(import.meta.env.VITE_APP_CONTEXT_PATH),這兩個配置文件都加上然后nginx里面的配置是這個位置按照實際情況&#xff0c;我的是用docker掛載的&#xff0c;所以在/usr/share/nginx/html/lw-clothing為…

SQL Server通過存儲過程實現HTML頁面生成

引言在現代企業應用中&#xff0c;數據可視化是提升決策效率的關鍵。SQL Server作為核心數據庫管理系統&#xff0c;不僅處理數據存儲和查詢&#xff0c;還具備強大的擴展能力。通過存儲過程直接生成HTML頁面&#xff0c;企業能減少對中間層&#xff08;如Web服務器或應用程序&…

qt繪制餅狀圖并實現點擊即放大點擊部分

做得比較low #ifndef TEST_POWER_H #define TEST_POWER_H#include <QWidget> #include <QtMath> #include <QPainter> #include <QPushButton> #include <QVector> #include <cmath>namespace Ui { class test_power; } struct PieData {Q…

HashMap的put、get方法詳解(附源碼)

put方法 HashMap 只提供了 put 用于添加元素&#xff0c;putVal 方法只是給 put 方法調用的一個方法&#xff0c;并沒有提供給用戶使用。 對 putVal 方法添加元素的分析如下&#xff1a;如果定位到的數組位置沒有元素 就直接插入。如果定位到的數組位置有元素就和要插入的 key …

雙立柱式帶鋸床cad【1張總圖】+設計說明書+絳重

雙立柱式帶鋸床 摘 要 隨著機械制造技術的進步&#xff0c;制造業對于切割設備的精度、效率和穩定性要求越來越高。雙立柱式帶鋸床作為一種重要的切割設備&#xff0c;必須能夠滿足工業生產對于高精度、高效率的需求。 雙立柱式帶鋸床是一種重要的工業切割設備&#xff0c;其結…

在線JS解密加密配合ECC保護

在線JS解密加密配合ECC保護 1. ECC加密簡介 定義 ECC&#xff08;Elliptic Curve Cryptography&#xff09;是一種基于橢圓曲線數學的公鑰加密技術&#xff0c;利用橢圓曲線離散對數問題&#xff08;ECDLP&#xff09;實現高安全性。 背景 1985年&#xff1a;Koblitz&#xff0…

使用 Docker Compose 簡化 INFINI Console 與 Easysearch 環境搭建

前言回顧 在上一篇文章《搭建持久化的 INFINI Console 與 Easysearch 容器環境》中&#xff0c;我們詳細介紹了如何使用基礎的 docker run 命令&#xff0c;手動啟動和配置 INFINI Console (1.29.6) 和 INFINI Easysearch (1.13.0) 容器&#xff0c;并實現了關鍵數據的持久化&…

Word 怎么讓段落對齊,行與行之間寬一點?

我們來分兩步解決&#xff1a;段落對齊 和 調整行距。 這兩個功能都集中在Word頂部的【開始】選項卡里的【段落】區域。 第一步&#xff1a;讓段落對齊 “對齊”指的是段落的左右邊緣如何排列。通常有四種方式。 操作方法&#xff1a;將鼠標光標點在你想修改的那個段落里的任意…

Attention機制完全解析:從原理到ChatGPT實戰

一、Attention的本質與計算步驟 1.1 核心思想 動態聚焦&#xff1a;Attention是一種信息分配機制&#xff0c;讓模型在處理輸入時動態關注最重要的部分。類比&#xff1a;像人類閱讀時用熒光筆標記關鍵句子。 1.2 計算三步曲&#xff08;以"吃蘋果"為例&#xff09; …

2025年3月青少年電子學會等級考試 中小學生python編程等級考試三級真題答案解析(判斷題)

博主推薦 所有考級比賽學習相關資料合集【推薦收藏】1、Python比賽 信息素養大賽Python編程挑戰賽 藍橋杯python選拔賽真題詳解

HTML5 新特性詳解:從語義化到多媒體的全面升級

很多小伙伴本都好奇&#xff1a;HTML5有什么功能是以前的HTML沒有的&#xff1f; 今天就給大家說道說道 HTML5 作為 HTML 語言的新一代標準&#xff0c;帶來了諸多革命性的新特性。這些特性不僅簡化了前端開發流程&#xff0c;還大幅提升了網頁的用戶體驗和功能性。本文將深入…

mac安裝docker

1、下載docker-desktop https://www.docker.com/products/docker-desktop/2、安裝&#xff0c;雙擊安裝 3、優化docker配置 默認配置 cat ~/Library/Group\ Containers/group.com.docker/settings-store.json {"AutoStart": false,"DockerAppLaunchPath": …

mapbox進階,繪制不隨地圖旋轉的矩形,保證矩形長寬沿屏幕xy坐標方位

????? 主頁: gis分享者 ????? 感謝各位大佬 點贊?? 收藏? 留言?? 加關注?! ????? 收錄于專欄:mapbox 從入門到精通 文章目錄 一、??前言1.1 ??mapboxgl.Map 地圖對象1.2 ??mapboxgl.Map style屬性1.3 ??line線圖層樣式1.4 ??circle點圖層樣…

${project.basedir}延申出來的Maven內置的一些常用屬性

如&#xff1a;${project.basedir} 是 Maven 的內置屬性&#xff0c;可以被 pom.xml 直接識別。它表示當前項目的根目錄&#xff08;即包含 pom.xml 文件的目錄&#xff09;。 Maven 內置的一些常用屬性&#xff1a; 項目相關&#xff1a; ${project.basedir} <!-- 項…

[特殊字符] Python 批量生成詞云:讀取詞頻 Excel + 自定義背景 + Excel to.png 流程解析

本文展示如何用 Python 從之前生成的詞頻 Excel 文件中讀取詞頻數據&#xff0c;結合 wordcloud 和背景圖&#xff0c;批量生成直觀美觀的詞云圖。適用于文本分析、內容展示、報告可視化等場景。 &#x1f4c2; 第一步&#xff1a;讀取所有 Excel 詞頻文件 import os from ope…

模擬網絡請求的C++類設計與實現

在C開發中&#xff0c;理解和模擬網絡請求是學習客戶端-服務器通信的重要一步。本文將詳細介紹一個模擬HTTP網絡請求的C類庫設計&#xff0c;幫助開發者在不涉及實際網絡編程的情況下&#xff0c;理解網絡請求的核心概念和工作流程。 整體架構設計 這個模擬網絡請求的類庫主要由…

移動機器人的認知進化:Deepoc大模型重構尋跡本質

統光電尋跡技術已逼近物理極限。當TCRT5000傳感器在強烈環境光下失效率超過37%&#xff0c;當PID控制器在路徑交叉口產生63%的決策崩潰&#xff0c;工業界逐漸意識到&#xff1a;導引線束縛的不僅是車輪&#xff0c;更是機器智能的演化可能性。 ?技術破局點出現在具身認知架構…

記錄一次pip安裝錯誤OSError: [WinError 32]的解決過程

因為要使用 PaddleOCR&#xff0c;需要安裝依賴。先通過 conda新建了虛擬環境&#xff0c;然后安裝 PaddlePaddle&#xff0c;繼續安裝 PaddleOCR&#xff0c;上述過程我是在 VSCode的終端中處理&#xff0c;結果報錯如下&#xff1a;Downloading multidict-6.6.3-cp312-cp312-…

后端id設置long類型時,傳到前端,超過19位最后兩位為00

文章目錄一、前言二、問題描述2.1、問題背景2.2、問題示例三、解決方法3.1、將ID轉換為字符串3.2、使用JsonSerialize注解3.3、使用JsonFormat注解一、前言 在后端開發中&#xff0c;我們經常會遇到需要將ID作為標識符傳遞給前端的情況。當ID為long類型時&#xff0c;如果該ID…

SpringAI學習筆記-MCP客戶端簡單示例

MCP客戶端是AI與外部世界交互的橋梁。在AI系統中&#xff0c;大模型雖然具備強大的認知能力&#xff0c;卻常常受限于數據孤島問題&#xff0c;無法直接訪問外部工具和數據源。MCP協議應運而生&#xff0c;作為標準化接口解決這一核心挑戰。該協議采用客戶端-服務端架構&#x…