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。