Pytorch的C ++ API的生鏽綁定。 tch板條箱的目的是在C ++ Pytorch API(又名Libtorch)周圍提供一些薄包裝器。它旨在保持與原始C ++ API盡可能近的距離。然後可以在此基礎上開發更多的慣用生鏽綁定。該文檔可以在文檔中找到。
ChangElog
libtorch上C API的代碼生成部分來自Ocaml-Torch。
該板條箱需要v2.5.1中的C ++ Pytorch庫(LIBTORCH),才能在您的系統上使用。您可以:
LIBTORCH環境變量知道。LIBTORCH_USE_PYTORCH=1 。LIBTORCH ,則構建腳本可以使用download-libtorch功能下載libtorch的二進製版本。默認情況下,使用CPU版本。 TORCH_CUDA_VERSION環境變量可以設置為cu117 ,以便使用CUDA 11.7獲得預構建的二進制。在Linux平台上,構建腳本將在/usr/lib/libtorch.so中尋找一個系統範圍的libtorch庫。
如果設置了LIBTORCH_USE_PYTORCH環境變量,則調用Active Python解釋器來檢索有關Torch Python軟件包的信息。然後將此版本鏈接到。
libtorch並提取ZIP文件的內容。.bashrc或等效的位置,其中/path/to/libtorch是在解壓縮文件時創建的目錄的路徑。 export LIBTORCH=/path/to/libtorch標題文件位置也可以通過以下方式與共享庫分開指定:
# LIBTORCH_INCLUDE must contain `include` directory.
export LIBTORCH_INCLUDE=/path/to/libtorch/
# LIBTORCH_LIB must contain `lib` directory.
export LIBTORCH_LIB=/path/to/libtorch/對於Windows用戶,假設X:pathtolibtorch是未拉鍊的libtorch目錄。
LIBTORCH變量,然後將其設置為X:pathtolibtorch 。X:pathtolibtorchlib到Path變量。如果您希望暫時設置環境變量,則可以在PowerShell中運行
$ Env: LIBTORCH = " X:pathtolibtorch "
$ Env: Path += " ;X:pathtolibtorchlib "cargo run --example basics 。根據Pytorch文檔,Windows調試和發布版本不兼容。如果使用了不正確的libtorch版本,這可能會導致某些segfault。
建議使用MSVC Rust工具鏈(例如,通過Rustup安裝stable-x86_64-pc-windows-msvc ,而不是基於Mingw的穩定,因為Pytorch與Mingw具有兼容性問題。
設置環境變量LIBTORCH_STATIC=1 , libtorch靜態鏈接而不是使用動態庫。默認情況下,預編譯的文物似乎不包括libtorch.a ,因此必須手動編譯,例如,通過以下內容進行編譯:
git clone -b v2.5.1 --recurse-submodule https://github.com/pytorch/pytorch.git pytorch-static --depth 1
cd pytorch-static
USE_CUDA=OFF BUILD_SHARED_LIBS=OFF python setup.py build
# export LIBTORCH to point at the build directory in pytorch-static. 該板條箱提供了一種張量型,可包裝pytorch張量。這是如何執行一些張量操作的最小示例。
use tch :: Tensor ;
fn main ( ) {
let t = Tensor :: from_slice ( & [ 3 , 1 , 4 , 1 , 5 ] ) ;
let t = t * 2 ;
t . print ( ) ;
}Pytorch為其支持的大多數張量操作提供了自動差異化。這通常用於使用梯度下降訓練模型。優化是通過定義其形狀和初始化來通過nn::VarStore創建的變量進行的。
在下面的示例中, my_module使用兩個變量x1和x2 ,初始值為0。向前pass應用於張量xs返回xs * x1 + exp(xs) * x2 。
生成模型後,創建了nn::Sgd優化器。然後在訓練循環的每個步驟中:
VarStore的變量。 use tch :: nn :: { Module , OptimizerConfig } ;
use tch :: { kind , nn , Device , Tensor } ;
fn my_module ( p : nn :: Path , dim : i64 ) -> impl nn :: Module {
let x1 = p . zeros ( "x1" , & [ dim ] ) ;
let x2 = p . zeros ( "x2" , & [ dim ] ) ;
nn :: func ( move |xs| xs * & x1 + xs . exp ( ) * & x2 )
}
fn gradient_descent ( ) {
let vs = nn :: VarStore :: new ( Device :: Cpu ) ;
let my_module = my_module ( vs . root ( ) , 7 ) ;
let mut opt = nn :: Sgd :: default ( ) . build ( & vs , 1e-2 ) . unwrap ( ) ;
for _idx in 1 .. 50 {
// Dummy mini-batches made of zeros.
let xs = Tensor :: zeros ( & [ 7 ] , kind :: FLOAT_CPU ) ;
let ys = Tensor :: zeros ( & [ 7 ] , kind :: FLOAT_CPU ) ;
let loss = ( my_module . forward ( & xs ) - ys ) . pow_tensor_scalar ( 2 ) . sum ( kind :: Kind :: Float ) ;
opt . backward_step ( & loss ) ;
}
}nn API可用於創建神經網絡體系結構,例如,以下代碼定義了一個帶有一個隱藏層的簡單模型,並使用ADAM Optimizer在MNIST數據集上訓練它。
use anyhow :: Result ;
use tch :: { nn , nn :: Module , nn :: OptimizerConfig , Device } ;
const IMAGE_DIM : i64 = 784 ;
const HIDDEN_NODES : i64 = 128 ;
const LABELS : i64 = 10 ;
fn net ( vs : & nn :: Path ) -> impl Module {
nn :: seq ( )
. add ( nn :: linear (
vs / "layer1" ,
IMAGE_DIM ,
HIDDEN_NODES ,
Default :: default ( ) ,
) )
. add_fn ( |xs| xs . relu ( ) )
. add ( nn :: linear ( vs , HIDDEN_NODES , LABELS , Default :: default ( ) ) )
}
pub fn run ( ) -> Result < ( ) > {
let m = tch :: vision :: mnist :: load_dir ( "data" ) ? ;
let vs = nn :: VarStore :: new ( Device :: Cpu ) ;
let net = net ( & vs . root ( ) ) ;
let mut opt = nn :: Adam :: default ( ) . build ( & vs , 1e-3 ) ? ;
for epoch in 1 .. 200 {
let loss = net
. forward ( & m . train_images )
. cross_entropy_for_logits ( & m . train_labels ) ;
opt . backward_step ( & loss ) ;
let test_accuracy = net
. forward ( & m . test_images )
. accuracy_for_logits ( & m . test_labels ) ;
println ! (
"epoch: {:4} train loss: {:8.5} test acc: {:5.2}%" ,
epoch ,
f64 :: from ( & loss ) ,
100. * f64 :: from ( & test_accuracy ) ,
) ;
}
Ok ( ( ) )
}有關培訓循環的更多詳細信息可以在詳細的教程中找到。
預驗證的模型示例說明瞭如何在圖像上使用一些預訓練的計算機視覺模型。可以從pytorch實施中提取的權重 - 可以在此處下載Resnet18.ot和resnet34.ot。
然後可以通過以下命令運行示例:
cargo run --example pretrained-models -- resnet18.ot tiger.jpg這應該打印圖像的前5個Imagenet類別。此示例的代碼非常簡單。
// First the image is loaded and resized to 224x224.
let image = imagenet :: load_image_and_resize ( image_file ) ? ;
// A variable store is created to hold the model parameters.
let vs = tch :: nn :: VarStore :: new ( tch :: Device :: Cpu ) ;
// Then the model is built on this variable store, and the weights are loaded.
let resnet18 = tch :: vision :: resnet :: resnet18 ( vs . root ( ) , imagenet :: CLASS_COUNT ) ;
vs . load ( weight_file ) ? ;
// Apply the forward pass of the model to get the logits and convert them
// to probabilities via a softmax.
let output = resnet18
. forward_t ( & image . unsqueeze ( 0 ) , /*train=*/ false )
. softmax ( - 1 ) ;
// Finally print the top 5 categories and their associated probabilities.
for ( probability , class ) in imagenet :: top ( & output , 5 ) . iter ( ) {
println ! ( "{:50} {:5.2}%" , class , 100.0 * probability )
}safetensors是一種用於存儲張量的Faceface的一種新的簡單格式。它不依賴Python的pickle模塊,因此張量不綁定到特定類別和保存模型時使用的確切目錄結構。它也是零拷貝,這意味著讀取文件將不需要比原始文件更多的內存。
有關safetensors的更多信息,請訪問https://github.com/huggingface/safetensors
safetensors您可以通過PIP Manager安裝safetensors :
pip install safetensors
import torchvision
from safetensors import torch as stt
model = torchvision . models . resnet18 ( pretrained = True )
stt . save_file ( model . state_dict (), 'resnet18.safetensors' )注意:導出的文件名必須以.safetensors後綴命名,以使其通過tch正確解碼。
tch中進口重量 use anyhow :: Result ;
use tch :: {
Device ,
Kind ,
nn :: VarStore ,
vision :: {
imagenet ,
resnet :: resnet18 ,
}
} ;
fn main ( ) -> Result < ( ) > {
// Create the model and load the pre-trained weights
let mut vs = VarStore :: new ( Device :: cuda_if_available ( ) ) ;
let model = resnet18 ( & vs . root ( ) , 1000 ) ;
vs . load ( "resnet18.safetensors" ) ? ;
// Load the image file and resize it to the usual imagenet dimension of 224x224.
let image = imagenet :: load_image_and_resize224 ( "dog.jpg" ) ?
. to_device ( vs . device ( ) ) ;
// Apply the forward pass of the model to get the logits
let output = image
. unsqueeze ( 0 )
. apply_t ( & model , false )
. softmax ( - 1 , Kind :: Float ) ;
// Print the top 5 categories for this image.
for ( probability , class ) in imagenet :: top ( & output , 5 ) . iter ( ) {
println ! ( "{:50} {:5.2}%" , class , 100.0 * probability )
}
Ok ( ( ) )
}進一步的例子包括:
外部材料:
tch-rs和opencv在網絡攝像頭供稿上運行基於Mobilenet V3的python訓練模型。 查看此線程中的一些細節。
檢查此問題。
請參閱此問題,這可能是由於Rust-Analyzer不知道LIBTORCH和LD_LIBRARY_PATH等適當的環境變量而引起的。
可以通過PYO3從Python調用RUST/TCH代碼,TCH-EXT提供了這樣的Python擴展名的示例。
如果您在運行生成的二進製文件時沒有找到某些共享庫的錯誤(例如, error while loading shared libraries: libtorch_cpu.so: cannot open shared object file: No such file or directory )。您可以嘗試將以下內容添加到您的.bashrc中,where /path/to/libtorch是您安裝libtorch的路徑。
# For Linux
export LD_LIBRARY_PATH=/path/to/libtorch/lib:$LD_LIBRARY_PATH
# For macOS
export DYLD_LIBRARY_PATH=/path/to/libtorch/lib:$DYLD_LIBRARY_PATH
tch-rs根據MIT許可證和Apache許可證(版本2.0)的條款分發。
有關更多詳細信息,請參見許可證,許可-MIT。