1、pytorch和libtorch安裝(標貝科技)
PyTorch 是Torch7 團隊開發的,從它的名字就可以看出,其與Torch 的不同之處在於PyTorch 使用了Python 作為開發語言。所謂“Python first”,同樣說明它是一個以Python 優先的深度學習框架,不僅能夠實現強大的GPU 加速,同時還支持動態神經網絡,這是現在很多主流框架比如Tensorflow 等都不支持的。
PyTorch 既可以看做加入了GPU 支持的numpy,同時也可以看成一個擁有自動求導功能的強大的深度神經網絡,除了Facebook 之外,它還已經被Twitter、CMU 和Salesforce 等機構采用。
pytorch是一個強大的機器學習庫,其中集成了很多方法,但從python本身角度講,它的速度還不夠快,雖然對於許多需要動態性和易迭代性的場景來說,Python是一種合適且首選的語言,但在同樣的情況下,Python的這些特性恰恰是不利的。它常常應用於生產環境,這是一個低延遲和有嚴格部署要求的領域,一般選擇C++。
1)安裝pytorch
兩種方式安裝pytorch:根據實際cuda版本和需求安裝對應版本pytorch,這里安裝的是1.5.0版本。
a.查看cuda版本
cat /usr/local/cuda/version.txt
得到cuda版本,安裝合適版本的pytorch。
b.使用pip安裝
pip install torch==1.5.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
c.使用conda安裝
下載anaconda
wget https://mirrors.tuna.tsinghua.edu.cn/anaconda/archive/Anaconda3-5.2.0-Linux-x86_64.sh
安裝anconda
bash Anaconda3-5.2.0-Linux-x86_64.sh
創建test_torch虛擬環境,python版本=3.6
conda create -n test_torch python=3.6
激活test_torch虛擬環境
conda activate test_torch
安裝pytorch
conda install torch=1.5.0
d.torch測試
import torch
torch.version
2)安裝libtorch
a.確定libtorch版本
使用libtorch調用c++接口,要保證下載的libtorch的版本和pytorch的版本對應,使用低版本的pytorch和高版本的libtorch是沒法成功的。根據pytorch和cuda版本確認libtorch版本
查看libtorch版本
https://blog.csdn.net/lxx4610/article/details/105806017/
https://pytorch.org/get-started/locally/
b.從官網下載編譯好的文件
獲取libtorch有兩種方式:
• 從官網下載編譯好的文件
https://pytorch.org/ 下載對應版本
c.自己進行源碼編譯
碼雲下載
git clone https://gitee.com/mirrors/pytorch.git
查看libtorch版本
git tag
查看當前分支
git branch
根據cuda和pytorch版本切換到適配的版本
git checkout v1.2.0
更新第三方庫
git submodule update --init --recursive
編譯
mkdir build
cd build
python ../tools/build_libtorch.py
2、使用pytorch訓練模型
這里就不展開介紹
3、將Pytorch模型轉化為Torch Script
Torch Script可以完好的表達pytorch模型,而且也能被C++頭文件所理解。有兩種方法可以將pytorch模型轉換成TorchScript,Tracing和Annotation。
1)Tracing
這種方法需要你給模型傳入一個sample input,它會跟蹤在模型的forward方法中的過程。
例如,加載一個torchvision.models.resnet18()模型
model = torchvision.models.resnet18()
使用 torch.rand(),生成一個隨機樣例輸入
example = torch.rand(1, 3, 224, 224)
torch.jit.trace()方法對根據樣例輸入跟蹤模型的forward方法中的過程
traced_script_module = torch.jit.trace(model, example)
最后導出TorchScript模型。
traced_script_module.save("traced_resnet_model.pt")
完整過程:
import torch
import torchvision
# An instance of your model.
model = torchvision.models.resnet18()
# An example input you would normally provide to your model's forward() method.
example = torch.rand(1, 3, 224, 224)
# Use torch.jit.trace to generate a torch.jit.ScriptModule via tracing.
traced_script_module = torch.jit.trace(model, example) traced_script_module.save("traced_resnet_model.pt")
2)Annotation
如果forward方法中具有判斷語句,Tracing方法就行不通了,Annotation方法則可以處理模型里有判斷語句的情形,使用torch.jit.script。
模型定義:
class MyModule(torch.nn.Module):
def __init__(self, N, M):
super(MyModule, self).__init__()
self.weight = torch.nn.Parameter(torch.rand(N, M))
def forward(self, input):
if input.sum() > 0:
output = self.weight.mv(input)
else:
output = self.weight + input return output
定義了一個模型結構,在forward方法中使用了判斷語句,這種模型在轉化為Torch Script時,不能Tracing方法,這時可以使用 torch.jit.script()方法:
my_module = MyModule(10,20)
traced_script_module = torch.jit.script(my_module)
traced_script_module.save("traced_resnet_model.pt")
4、在C++中加載Model
將pytorch訓練好的模型導出成torch script形式並保存,C++能夠理解,編譯並序列化torch script格式的模型。
使用libtorch中torch::jit::load()加載導出的模型。
#include <torch/script.h> // One-stop header.
#include <iostream>
#include <memory>
int main(int argc, const char* argv[]) {
if (argc != 2) {
std::cerr << "usage: example-app <path-to-exported-script-module>\n";
return -1;
}
torch::jit::script::Module module;
try {
// Deserialize the ScriptModule from a file using torch::jit::load().
module = torch::jit::load(argv[1]);
}
catch (const c10::Error& e) {
std::cerr << "error loading the model\n"; return -1;
}
std::cout << "ok\n";
}
torch::jit::load()函數用來加載模形,參數為模型文件名,返回torch::jit::script::Module類,<torch/script.h>頭文件包含了需要的類和方法,這個文件通過安裝libtorch得到。
5、運行模型
模型已經導入成功,使用libtorch中的一些方法,你就可以像在python中一樣去跑你的模型了,並根據c++模型的輸出與python模型的輸出,對比結果。
// Create a vector of inputs.
std::vector<torch::jit::IValue> inputs;
inputs.push_back(torch::ones({1, 3, 224, 224}));
// Execute the model and turn its output into a tensor.
at::Tensor output = module.forward(inputs).toTensor();
std::cout << output.slice(/*dim=*/1, /*start=*/0, /*end=*/5) << '\n';
歡迎體驗標貝語音開放平台
地址:https://ai.data-baker.com/#/?source=qaz123
(注:填寫邀請碼hi25d7,每日免費調用量還可以翻倍)