PyTorch-C++前端

C++调用PyTorch模型教程 在人工智能的世界中,PyTorch已经成为了研究人员和工程师们广泛使用的深度学习框架之一。它以其灵活性和动态计算图而闻名,非常适合快速原型设计和实验。然而,当我们想要将训练好的模型部署到生产环境中时,我们可能会倾向于使用C++这样的更高性能语言,因为它提供了更好的速度和资源管理。幸运的是,PyTorch提供了LibTorch库,使得我们可以在C++环境中加载和使用PyTorch模型。本教程将详细介绍如何在C++中调用PyTorch模型,包括环境配置、模型的导出、C++中的加载和使用等步骤。 阅读详情

PyTorch-C++前端

1、LibTorch与VS2017社区版配置

安装libtorch需要与自身pytorch版本以及CUDA版本对应,输入win+r打开终端输入以下命令依次检查对应版本。

pip list #查看pytorch版本
nvcc -V #查看CUDA版本

在这里插入图片描述

本机torch和CUDA版本分别为1.9.0和10.2,因此需要去官网下载对应版本的各个版本CUDA和各个版本CUDNN。

1.1、下载libtorch

libtorch主要用来部署pytorch的模型,是最近流行的C++部署框架。在Linux、Mac、Windows上都有对应的版本下载。同时也有release版本和debug版本,目前官网只提供最新的1.9.0版本。

Windows下各个版本下载

LibTorch-Versionrelease-cpurelease-gpudebug-cpudebug-gpu
1.0.01.0.0-CPU1.0.0-CUDA-80
1.0.0-CUDA-90
1.0.0-CUDA-100
失效失效
1.0.11.0.1-CPU1.0.1-CUDA-80
1.0.1-CUDA-90
1.0.1-CUDA-100
失效失效
1.1.01.1.0-CPU1.1.0-CUDA-90
1.1.0-CUDA-100
1.1.0-CPU1.1.0-CUDA-90
1.1.0-CUDA-100
1.2.01.2.0-CPU1.2.0-CUDA-92
1.2.0-CUDA-100
1.2.0-CPU1.2.0-CUDA-92
1.2.0-CUDA-100
1.3.01.3.0-CPU1.3.0-CUDA-92
1.3.0-CUDA-101
1.3.0-CPU1.3.0-CUDA-92
1.3.0-CUDA101
1.3.11.3.1-CPU1.3.1-CUDA-92
1.3.1-CUDA-101
1.3.1-CPU1.3.1-CUDA-92
1.3.1-CUDA-101
1.4.01.4.0-CPU1.4.0-CUDA-92
1.4.0-CUDA-101
1.3.1-CPU1.3.1-CUDA-92
1.3.1-CUDA-101
1.5.01.5.0-CPU1.5.0-CUDA-92
1.5.0-CUDA-101
1.5.0-CUDA-102
1.5.0-CPU1.5.0-CUDA-92
1.5.0-CUDA-101
1.5.0-CUDA-102
1.6.01.6.0-CPU1.6.0-CUDA-101
1.6.0-CUDA-102
1.6.0-CPU1.6.0-CUDA-101
1.6.0-CUDA-102
1.7.01.7.0-CPU1.7.0-CUDA-101
1.7.0-CUDA-102
1.7.0-CUDA-110
1.7.0-CPU1.7.0-CUDA-101
1.7.0-CUDA-102
1.7.0-CUDA-110
1.7.11.7.1-CPU1.7.1-CUDA-101
1.7.1-CUDA-102
1.7.1-CUDA-110
1.7.1-CPU1.7.1-CUDA-101
1.7.1-CUDA-102
1.7.1-CUDA-110
1.8.01.8.0-CPU1.8.0-CUDA-102
1.8.0-CUDA-111
1.8.0-CPU1.8.0-CUDA-102
1.8.0-CUDA-111
1.8.1(LTS)1.8.1(LTS)-CPU1.8.1(LTS)-CUDA-102
1.8.1(LTS)-CUDA-111
1.8.1(LTS)-CPU1.8.1(LTS)-CUDA-102
1.8.1(LTS)-CUDA-111
1.9.01.9.0-CPU1.9.0-CUDA-102
1.9.0-CUDA-111
1.9.0-CPU1.9.0-CUDA-102
1.9.0-CUDA-111

同时还有Ubuntu各个版本,后期补充。

下载与torch对应版本的libtorch后解压缩。将其放在任意位置,我的是放C盘下。

在这里插入图片描述

配置libtorch的环境变量。

在这里插入图片描述

1.2、配置libtorch和VS2017社区版

新建C++工程文件,根据自己的情况修改第三个步骤

在这里插入图片描述

新建完成后默认是x86的,需要改为X64的,因为libtorch是x64的,不支持32位的。我下载是release版本的,所以还要改为release模式。

在这里插入图片描述

然后右键test_test项目,选择属性,配置libtorch环境

在这里插入图片描述

选择配置属性->调试->环境输入:

PATH=C:\libtorch\lib;%PATH%

在这里插入图片描述

选择配置属性->C/C++ ->常规:将SDL检查设为否,将以下内容输入附加包含目录:

C:\libtorch\include
C:\libtorch\include\torch\csrc\api\include

在这里插入图片描述

选择配置属性->C/C++ ->语言:将符合模式设为否,将C++语言标准设为C++14。

在这里插入图片描述

选择配置属性->链接器 ->常规:将以下内容添加到附加库目录:

C:\libtorch\lib

在这里插入图片描述

选择配置属性->链接器 ->输入:将以下内容添加到附加库目录:

asmjit.lib
c10.lib
c10_cuda.lib
c10d.lib
caffe2_detectron_ops_gpu.lib
caffe2_module_test_dynamic.lib
caffe2_nvrtc.lib
Caffe2_perfkernels_avx.lib
Caffe2_perfkernels_avx2.lib
Caffe2_perfkernels_avx512.lib
clog.lib
cpuinfo.lib
dnnl.lib
fbgemm.lib
fbjni.lib
kineto.lib
libprotobuf.lib
libprotobuf-lite.lib
libprotoc.lib
mkldnn.lib
pthreadpool.lib
pytorch_jni.lib
torch.lib
torch_cpu.lib
torch_cuda.lib
XNNPACK.lib

在这里插入图片描述

此处的内容根据各个libtorch版本的不同而有所改变,这里的是libtorch-1.9.0的。

输入以下内容测试是否调用到CUDA:

#include<torch/torch.h>
#include<iostream>

using namespace std;

int main() {
	torch::Tensor tensor = torch::rand({ 5,3 });
	std::cout << tensor << std::endl;
	std::cout << torch::cuda::is_available() << std::endl; // 测试CUDA是否可用
	std::cout << torch::cuda::cudnn_is_available() << std::endl; // 测试CUDNN是否可用
}

显示如下:

在这里插入图片描述

如果没有正确调用CUDA将会显示为0。此时选择配置属性->链接器 ->输入,加入以下内容:

/INCLUDE:?searchsorted_cuda@native@at@@YA?AVTensor@2@AEBV32@0_N1@Z

/INCLUDE:?warp_size@cuda@at@@YAHXZ 

在这里插入图片描述

点击调试->开始执行或者F5,显示为1则表示调用CUDA成功:

在这里插入图片描述

至此,libtorch配置VS2017完毕,另一个debug或者cmake形式的尚未研究(待补充)

2、PyTorch-C++前端新手入门

PyTorch-C++前端建立深度学习模型是完全基于C++语言重构网络结构并进行训练保存模型。这是一套全新的可用的C++的API。先宏观的感受下C++版的模型构建。

利用原生的python代码实现这样一个模型,如下:

import torch

class Net(torch.nn.Module):
  def __init__(self, N, M):
    super(Net, self).__init__()
    self.W = torch.nn.Parameter(torch.randn(N, M))
    self.b = torch.nn.Parameter(torch.randn(M))

  def forward(self, input):
    return torch.addmm(self.b, input, self.W)

现在C++实现的形式如下:

#include <torch/torch.h>

struct Net : torch::nn::Module {
  Net(int64_t N, int64_t M) {
    W = register_parameter("W", torch::randn({N, M}));
    b = register_parameter("b", torch::randn(M));
  }
  torch::Tensor forward(torch::Tensor input) {
    return torch::addmm(b, input, W);
  }
  torch::Tensor W, b;
};

2.1、基于libtorch的LeNet5网络代码实现

按照上述步骤创建工程并配置好libtorch后

(1)输入相关的头文件,并定义相关参数

配置好libtorch后,导入torch相关的头文件,C++定义的网络结构函数都在头文件中有定义。

#include <torch\torch.h>
#include <cstddef>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>

// Where to find the MNIST dataset.
const char* kDataroot = "D:/C_Plus/LeNet_Mnist/data";

// The batch size for training.
const int64_t kTrainBatchSize = 32;

// The number of epochs to train.
const int64_t kNumberOfEpochs = 10;

// After how many batches to log a new update with the loss value.
const int64_t kLogInterval = 10;

// After how many batches to create a new checkpoint periodically.
const int64_t kCheckpointEvery = 200;
(2)定义LeNet5网络结构

在这里插入图片描述

第一层卷积输入通道为 3,输出通道为 6,size = 5,stride = 1,padding = 0,最大池化size = 2,stride = 2。

第二层卷积输入通道为 6,输出通道为 16,size = 5,stride = 1,padding = 0 ,最大池化size = 2,stride = 2。

Flatten(16 * 4 * 4);(这里4和图中5,是因为取整的方式不同导致)

第三层全连接输入通道为256(16 * 4 * 4),输出通道为120。

第四层全连接输入通道为120,输出通道为84。

由于MNIST数据集是单通道图像,因此LeNet5网络的输入通道为1,这里将flatten层进行改动。

此处代码的书写风格暂时只可意会不可言传,因此不做代码编程思路介绍

// 创建网络
struct LeNet5 : torch::nn::Module {
	LeNet5()
		: conv1(torch::nn::Conv2dOptions(1, 6, 5)
			.stride(1)
			.padding(2)),// 1 * 28 * 28 -> 6 * 28 * 28 -> 6 * 14 * 14
		conv2(torch::nn::Conv2dOptions(6, 16, 5)
			.stride(1)
			.padding(0)),// 6 * 14 * 14 -> 16 * 10 * 10 -> 16 * 5 * 5
		conv3(torch::nn::Conv2dOptions(16, 120, 5)
			.stride(1)
			.padding(0)),// 16 * 5 * 5 -> 120 * 1 * 1 (不需要池化)
		fc1(120,84),
		fc2(84,10)
	//注册需要学习的模块
	{
		register_module("conv1", conv1);
		register_module("conv2", conv2);
		register_module("conv3", conv3);
		register_module("fc1", fc1);
		register_module("fc2", fc2);

	}

	torch::Tensor forward(torch::Tensor x) {
		//conv1
		x = torch::relu(torch::max_pool2d(conv1->forward(x),2));
		//conv2
		x = torch::relu(torch::max_pool2d(conv2->forward(x), 2));
		//conv3
		x = torch::relu(conv3->forward(x));
		//数据格式转换
		x = x.view({ -1,120 });

		//全连接层
		//fc1
		x = torch::relu(fc1->forward(x));
		//fc2
		x = fc2->forward(x);

		return torch::log_softmax(x, 1);
	};

	torch::nn::Conv2d conv1, conv2,conv3;
	torch::nn::Linear fc1, fc2;
};

(3)数据集定义及加载

此处读取数据集的形式只是其中的一种,还有其他的形式,也支持自定义操作,待后续深入研究后完善

//加载数据集并进行批处理
	//训练集
	auto train_datasets = torch::data::datasets::MNIST(kDataroot, torch::data::datasets::MNIST::Mode::kTrain)
		.map(torch::data::transforms::Normalize<>(0.1307, 0.3081))
		.map(torch::data::transforms::Stack<>());

	const size_t train_dataset_size = train_datasets.size().value();
	auto train_dataloader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
		std::move(train_datasets), kTrainBatchSize);

	//测试集
	auto test_datasets = torch::data::datasets::MNIST(kDataroot, torch::data::datasets::MNIST::Mode::kTest)
		.map(torch::data::transforms::Normalize<>(0.1207, 0.3081))
		.map(torch::data::transforms::Stack<>());

	const size_t test_dataset_size = test_datasets.size().value();
	auto test_dataloader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
		std::move(test_datasets), kTrainBatchSize);
(4)定义训练函数

训练函数的结构类似于PyTorch结构,将模型调为训练模式,循环读取dataloader,对数据进行训练。

//定义训练函数
template<typename DataLoader>
void train(
	size_t epoch,
	LeNet5& model,
	torch::Device device,
	DataLoader& data_loader,
	torch::optim::Optimizer& optimizer,
	size_t dataset_size
	) {
	model.train();
	size_t batch_idx = 0;
	for (auto& batch : data_loader) {
		auto data = batch.data.to(device);
		auto label = batch.target.to(device);
		
		optimizer.zero_grad();
		
		auto output = model.forward(data);
		auto loss = torch::nll_loss(output, label);
		AT_ASSERT(!std::isnan(loss.template item<float>()));

		loss.backward();
		optimizer.step();

		batch_idx++;
		if (batch_idx % kLogInterval == 0) {
			std::printf(
				"\rTrain Epoch: %ld [%5ld/%5ld] Loss: %.4f",
				epoch,
				batch_idx * batch.data.size(0),
				dataset_size,
				loss.template item<float>());
		}
	}
}
(5)定义测试函数

测试函数不再多阐述,跟PyTorch结构类似。

template <typename DataLoader>
void test(
	LeNet5& model,
	torch::Device device,
	DataLoader& data_loader,
	size_t dataset_size) {
	torch::NoGradGuard no_grad;
	model.eval();
	double test_loss = 0;
	int32_t correct = 0;
	for (const auto& batch : data_loader) {
		auto data = batch.data.to(device), targets = batch.target.to(device);
		auto output = model.forward(data);
		test_loss += torch::nll_loss(
			output,
			targets,
			/*weight=*/{},
			torch::Reduction::Sum)
			.template item<float>();
		auto pred = output.argmax(1);
		correct += pred.eq(targets).sum().template item<int64_t>();
	}

	test_loss /= dataset_size;
	std::printf(
		"\nTest set: Average loss: %.4f | Accuracy: %.3f\n",
		test_loss,
		static_cast<double>(correct) / dataset_size);
}
(6)定义主函数

训练步骤也跟PyTorch的结构类似,调用GPU/CPU---->定义数据集函数---->定义优化器---->定义训练函数---->定义测试函数---->保存模型。

auto main(int argc, const char** argv) ->int{
	torch::manual_seed(1);

	//查询CUDA是否有用。否则在CPU上运行
	torch::DeviceType device_type;
	if (torch::cuda::is_available) {
		std::cout << "CUDA is available,Training on GPU" << std::endl;
		device_type = torch::kCUDA;
	}
	else {
		std::cout << "Training on CPU" << std::endl;
		device_type = torch::kCPU;
	}
	torch::Device device(device_type);

	LeNet5 model;
	//auto model = std::make_shared<LeNet5>();
	model.to(device);

	//加载数据集并进行批处理
	//训练集
	auto train_datasets = torch::data::datasets::MNIST(kDataroot, torch::data::datasets::MNIST::Mode::kTrain)
		.map(torch::data::transforms::Normalize<>(0.1307, 0.3081))
		.map(torch::data::transforms::Stack<>());

	const size_t train_dataset_size = train_datasets.size().value();
	auto train_dataloader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
		std::move(train_datasets), kTrainBatchSize);//此处有疑点,须后期认真研究

	//测试集
	auto test_datasets = torch::data::datasets::MNIST(kDataroot, torch::data::datasets::MNIST::Mode::kTest)
		.map(torch::data::transforms::Normalize<>(0.1207, 0.3081))
		.map(torch::data::transforms::Stack<>());

	const size_t test_dataset_size = test_datasets.size().value();
	auto test_dataloader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
		std::move(test_datasets), kTrainBatchSize);

	//优化器
	torch::optim::SGD optimizer(model.parameters(), torch::optim::SGDOptions(0.01).momentum(0.5));

	//开始训练
	for (size_t epoch = 1; epoch <= kNumberOfEpochs; ++epoch) {
		train(epoch, model, device, *train_dataloader, optimizer, train_dataset_size);
		test(model, device, *test_dataloader, test_dataset_size);

		
	}
	printf("Finish training!\n");
	torch::serialize::OutputArchive archive;
	model.save(archive);
	archive.save_to("mnist.pt");  //保存训练好的模型到文件,方便下次使用
	printf("Save the training result to mnist.pt.\n");
}

完整训练代码:

#include<torch\torch.h>
#include <cstddef>
#include <cstdio>
#include <iostream>
#include <string>
#include <vector>

// Where to find the MNIST dataset.
const char* kDataroot = "D:/C_Plus/LeNet_Mnist/data";

// The batch size for training.
const int64_t kTrainBatchSize = 32;

// The number of epochs to train.
const int64_t kNumberOfEpochs = 10;

// After how many batches to log a new update with the loss value.
const int64_t kLogInterval = 10;

// After how many batches to create a new checkpoint periodically.
const int64_t kCheckpointEvery = 200;



// 创建网络
struct LeNet5 : torch::nn::Module {
	LeNet5()
		: conv1(torch::nn::Conv2dOptions(1, 6, 5)
			.stride(1)
			.padding(2)),// 1 * 28 * 28 -> 6 * 28 * 28 -> 6 * 14 * 14
		conv2(torch::nn::Conv2dOptions(6, 16, 5)
			.stride(1)
			.padding(0)),// 6 * 14 * 14 -> 16 * 10 * 10 -> 16 * 5 * 5
		conv3(torch::nn::Conv2dOptions(16, 120, 5)
			.stride(1)
			.padding(0)),// 16 * 5 * 5 -> 120 * 1 * 1 (不需要池化)
		fc1(120,84),
		fc2(84,10)
	//注册需要学习的模块
	{
		register_module("conv1", conv1);
		register_module("conv2", conv2);
		register_module("conv3", conv3);
		register_module("fc1", fc1);
		register_module("fc2", fc2);

	}

	torch::Tensor forward(torch::Tensor x) {
		//conv1
		x = torch::relu(torch::max_pool2d(conv1->forward(x),2));
		//conv2
		x = torch::relu(torch::max_pool2d(conv2->forward(x), 2));
		//conv3
		x = torch::relu(conv3->forward(x));
		//数据格式转换
		x = x.view({ -1,120 });

		//全连接层
		//fc1
		x = torch::relu(fc1->forward(x));
		//fc2
		x = fc2->forward(x);

		return torch::log_softmax(x, 1);
	};

	torch::nn::Conv2d conv1, conv2,conv3;
	torch::nn::Linear fc1, fc2;
};



//定义训练函数
template<typename DataLoader>
void train(
	size_t epoch,
	LeNet5& model,
	torch::Device device,
	DataLoader& data_loader,
	torch::optim::Optimizer& optimizer,
	size_t dataset_size
	) {
	model.train();
	size_t batch_idx = 0;
	for (auto& batch : data_loader) {
		auto data = batch.data.to(device);
		auto label = batch.target.to(device);
		
		optimizer.zero_grad();
		
		auto output = model.forward(data);
		auto loss = torch::nll_loss(output, label);
		AT_ASSERT(!std::isnan(loss.template item<float>()));

		loss.backward();
		optimizer.step();

		batch_idx++;
		if (batch_idx % kLogInterval == 0) {
			std::printf(
				"\rTrain Epoch: %ld [%5ld/%5ld] Loss: %.4f",
				epoch,
				batch_idx * batch.data.size(0),
				dataset_size,
				loss.template item<float>());
		}
	}
}

template <typename DataLoader>
void test(
	LeNet5& model,
	torch::Device device,
	DataLoader& data_loader,
	size_t dataset_size) {
	torch::NoGradGuard no_grad;
	model.eval();
	double test_loss = 0;
	int32_t correct = 0;
	for (const auto& batch : data_loader) {
		auto data = batch.data.to(device), targets = batch.target.to(device);
		auto output = model.forward(data);
		test_loss += torch::nll_loss(
			output,
			targets,
			/*weight=*/{},
			torch::Reduction::Sum)
			.template item<float>();
		auto pred = output.argmax(1);
		correct += pred.eq(targets).sum().template item<int64_t>();
	}

	test_loss /= dataset_size;
	std::printf(
		"\nTest set: Average loss: %.4f | Accuracy: %.3f\n",
		test_loss,
		static_cast<double>(correct) / dataset_size);
}


auto main(int argc, const char** argv) ->int{
	torch::manual_seed(1);

	//查询CUDA是否有用。否则在CPU上运行
	torch::DeviceType device_type;
	if (torch::cuda::is_available) {
		std::cout << "CUDA is available,Training on GPU" << std::endl;
		device_type = torch::kCUDA;
	}
	else {
		std::cout << "Training on CPU" << std::endl;
		device_type = torch::kCPU;
	}
	torch::Device device(device_type);

	LeNet5 model;
	//auto model = std::make_shared<LeNet5>();
	model.to(device);

	//加载数据集并进行批处理
	//训练集
	auto train_datasets = torch::data::datasets::MNIST(kDataroot, torch::data::datasets::MNIST::Mode::kTrain)
		.map(torch::data::transforms::Normalize<>(0.1307, 0.3081))
		.map(torch::data::transforms::Stack<>());

	const size_t train_dataset_size = train_datasets.size().value();
	auto train_dataloader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
		std::move(train_datasets), kTrainBatchSize);//此处有疑点,须后期认真研究

	//测试集
	auto test_datasets = torch::data::datasets::MNIST(kDataroot, torch::data::datasets::MNIST::Mode::kTest)
		.map(torch::data::transforms::Normalize<>(0.1207, 0.3081))
		.map(torch::data::transforms::Stack<>());

	const size_t test_dataset_size = test_datasets.size().value();
	auto test_dataloader = torch::data::make_data_loader<torch::data::samplers::SequentialSampler>(
		std::move(test_datasets), kTrainBatchSize);

	//优化器
	torch::optim::SGD optimizer(model.parameters(), torch::optim::SGDOptions(0.01).momentum(0.5));

	//开始训练
	for (size_t epoch = 1; epoch <= kNumberOfEpochs; ++epoch) {
		train(epoch, model, device, *train_dataloader, optimizer, train_dataset_size);
		test(model, device, *test_dataloader, test_dataset_size);

		
	}
	printf("Finish training!\n");
	torch::serialize::OutputArchive archive;
	model.save(archive);
	archive.save_to("mnist.pt");  //保存训练好的模型到文件,方便下次使用
	printf("Save the training result to mnist.pt.\n");
}
(7)模型推理

择良日完善!!!!

c++调用pytorch libtorch(基础篇) c++调用pytorch libtorch1.将pytorch模型转换成Torch Script参考文献 以GitHub [见参考文献1]为例,学习了c++调用pytorch API libtorch的实现过程。 1.将pytorch模型转换成Torch Script 官方tutorial https://pytorch.org/tutorials/advanced/cpp_export.html中给出了当前将pytorch模型转成Torch Script的两种方式(官方源码如下): 1.Converti 阅读详情

相关推荐

PyTorch C++ 前端:张量

本文详细介绍如何使用PyTorch C++ 前端:张量

DT程序员的博客 559

C++部署pytorch模型

转自https://www.jianshu.com/p/02f16439892d,侵删 (一)————将pytorch模型转化为torchscript模型 Pytorch官方提供的C++API名为libtorch,在Pytorch1.0版本之后开始支持windows,以后就可以直接用libtorch来部署Pytorch模型了。 在Windows平台上用C++部署深度学习应用一直很麻烦,caffe使用自定义层还需要自己写backward(),而TensorFlow对Windows平台的支持也不是很好,在W

weixin_39450742的博客 2165

Pytorch使用手册—使用 PyTorch C++ 前端(专题四十七)

现在我们的基本环境已经配置好,我们可以深入本教程中更有趣的部分。首先,我们将讨论如何在C++前端中定义和与模块交互。我们将从基本的小规模示例模块开始,然后使用C++前端提供的丰富内置模块库实现一个完整的GAN。就像在Python中一样,我们定义了一个名为Net的类(为了简化,这里使用了struct而不是class),并从模块基类派生。在构造函数中,我们使用创建张量,就像在Python中使用一样。一个有趣的区别是我们如何注册参数。在Python中,我们使用类来包装张量,而在C++中,我们必须通过。

183

在 C++ 中使用 PyTorch

PyTorch 提供了 C++ 前端 API 接口,可以直接在 C++ 中使用 PyTorch 的相关功能。您可以使用 C++ API 在 C++ 代码中构建、训练和部署深度学习模型。6.使用 C++ API 加载和运行 Torch Script 模型或使用 ONNX Runtime 加载和运行 ONNX 模型。上述代码实现了一个使用 C++ API 训练 MNIST 数字识别模型并在每 100 批次后输出损失值的示例。4.在训练周期中使用 C++ API 优化模型。

程序猿视角 3123

kineto:一个CPU + GPU分析库,提供对时间线跟踪和硬件性能计数器的访问

坚人 Kineto是一个PyTorch性能分析库和框架,致力于为生产工作负载提供低开销的全系统检测。 目前,它由libkineto组成,libkineto是与PyTorch集成的进程内分析库。 但是,未来将添加其他相关组件,例如基于达米安的部署和跟踪处理管道的基础架构。 什么是libkineto? Libkineto是整个Kineto项目的组成部分,是一个进程内分析库,该库还提供了C ++ API。 请参考libkineto文件夹中的文件。 计划首次发布: libkineto,一个进程内库,提供CPU + GPU时间线跟踪功能。 允许PyTorch探查器控制时间线跟踪收集的API。 在Chrome浏览器中使用chrome:// tracing扩展程序进行可视化。 未来发展: Tensorboard集成 协作功能 基于守护程序的部署,用于更大的设置 分布式跟踪支持 跟踪处理和分析管

银河麒麟V10离线安装VLC播放器:依赖处理与3.0.9.2版本实操指南

在国产化操作系统日益普及的背景下,软件安装方式成为政企内网用户关注的重点。离线安装作为一种不依赖公网源的部署手段,常用于解决内网环境下的软件获取问题。其核心在于理解Linux包管理机制,如dpkg与apt对依赖关系的处理逻辑。掌握这一原理,不仅能应对多媒体软件的部署,也能提升系统维护效率。VLC作为跨平台多媒体播放器,凭借强大的解码能力与协议支持,广泛应用于本地视频播放、RTSP拉流及监控大屏等场景。本文从离线安装的通用概念出发,结合银河麒麟V10桌面版的实际环境,详细梳理了VLC 3.0.9.2离线包的获

weixin_32247165的博客 364

[PyTorch]PyTorch的C++前端和模型部署

一.前言 差不多一年前的这个时候,在狗厂实习的时候,主要用PyTorch做一些事情。那个时候针对PyTorch的模型部署问题,主要讨论ONNX。想像一下今天的DL框架格局,PyTorch,Tensorflow,Keras,Caffe,Caffe2等,持久化模型之间不兼容。常见的一种情况是,一篇论文基于不同框架写不同版本的代码。那么,很显然的一个需求是: 一个框架下的模型如何可以转化为另一个框架下的模型? 相关工作有一些,ONNX是其中一个,微软也做过类似工作。但是问题是总会遇到一些无法直接转换的组件。

sunlin972913894的博客 985

5G R18标准:AI/ML如何重塑空口优化与网络架构

人工智能与机器学习正逐步成为通信网络优化的核心技术。其核心原理在于通过数据驱动模型,从海量网络数据中学习信道变化、用户行为等统计规律,替代传统的基于固定规则的优化方法。这一技术范式能显著提升网络性能与效率,尤其在空口资源管理、干扰协调和能耗控制等场景中价值突出。在5G Advanced(R18)标准化框架下,AI/ML被系统性地引入空口设计,聚焦于信道状态信息反馈增强、波束管理与预测等关键用例。通过定义网络侧AI、终端侧AI及联合学习的标准化接口与流程,R18旨在实现跨厂商设备的智能协同,推动无线网络向自适

weixin_35671843的博客 241

使用 PyTorch C++ 前端

使用 PyTorch C++ 前端 PyTorch C++ 前端是 PyTorch 机器学习框架的纯 C++ 接口。 虽然 PyTorch 的主要接口是 Python,但 Python API 位于大量 C++ 代码库之上,提供基础数据结构和功能,例如张量和自动微分。 C++ 前端公开了一个纯 C++11 API,它使用机器学习训练和推理所需的工具扩展了这个底层 C++ 代码库。 这包括用于神经网络建模的内置通用组件集合; 使用自定义模块扩展此集合的 API; 流行的优化算法库,例如随机梯度下降; 一个带有

wolaiyeptx的博客 3230

机器学习: 共轭梯度算法(PCG)

今天介绍数值计算和优化方法中非常有效的一种数值解法,共轭梯度法。我们知道,在解大型线性方程组的时候,很少会有一步到位的精确解析解,一般都需要通过迭代来进行逼近,而 PCG 就是这样一种迭代逼近算法。 我们先从一种特殊的线性方程组的定义开始,比如我们需要解如下的线性方程组: Ax=bAx=b 这里的 A(n×n)A(n×n) 是对称,正定矩阵, b(n×...

weixin_30807677的博客 3179

深入解析LVDS电平标准在LCD屏接口设计中的关键作用

本文深入解析了LVDS电平标准在LCD屏接口设计中的核心作用。文章不仅阐释了LVDS低电压差分信号的工作原理、关键电气参数及抗噪优势,还详细对比了VESA与JEIDA两种主流数据格式,并提供了从PCB布局布线到信号调试的实战避坑指南,是确保高速、稳定显示的关键技术参考。

weixin_28419039的博客 331

一键构建 pytorch cpp lib 前端和 wheel

系统环境:ubuntu 22.04V100 GPU。

eloudy的专栏 190

GameFramework 框架详解之 Network网络模块 工具链

GameFramework(下面简称GF)Demo中,已经给我们提供了Network模块使用的protobuf使用的动态链接库protobuf-net.dll,但是GF并没有给我们提供protobuf相关的工具链,比如:1.proto文件自动导出对应c#的Packet类和PacketHandler类2.导出Packet类继承IReference以便使用引用池。3.自动生成Packet类和PacketHandler的Id,且保持和服务器Id一一对应。

TxNet 2899

PyTorch 1.0 中文官方教程:使用 PyTorch C++ 前端

译者:solerji PyTorch C++ 前端 是PyTorch机器学习框架的一个纯C++接口。PyTorch的主接口是Python,Python API位于一个基础的C++代码库之上,提供了基本的数据结构和功能,例如张量和自动求导。C++前端暴露了一个纯的C++11的API,在C++底层代码库之上扩展了机器学习训练和推理所需的工具扩展。这包括用于神经网络建模的内置组件集合;扩展此集合的自...

weixin_30845171的博客 226

uniapp ios原生插件开发 (framework,cocoapods)

已知UniApp的插件开发方式有两种, 第一种 Xcode Framework的方式,这种方式是官方指定的方式。 这种方式的优点就是简单直接, 但也有不足,比如当插件需要引入一些三方库时,操作起来就不是那么方便。 而使用Cocoapods则可以很方便的引入三方库。 接下来,本文探索使用Cocoapods的方式来进行UniApp插件开发。

Rey的技术博客 9820

ROS机器人未知环境自主探索功能包explore_lite最全源码详细解析(一)

本系列文章主要针对ROS机器人常使用的未知环境自主探索功能包explore_lite展开全源码的详细解析,并进行概括总结。 本系列文章共包含六篇文章,前五篇文章主要介绍explore_lite功能包中 explore.cpp、costmap_tools.h、frontier_search.cpp、costmap_client.cpp等源码实现文件中全部函数的详细介绍,第六篇文章进行概括总结,包含自主探索功能包explore_lite的简介,实现未知环境自主探索功能的原理及流程总结,效果演示,使用功能包

慕羽★的博客 3934

pytorch安装到一半中断_使用 PyTorch C++ 前端(上)

译者:solerji 来源:官方文档转载请告知PyTorch C++ 前端 是PyTorch机器学习框架的一个纯C++接口。PyTorch的主接口是Python,Python API位于一个基础的C++代码库之上,提供了基本的数据结构和功能,例如张量和自动求导。C++前端暴露了一个纯的C++11的API,在C++底层代码库之上扩展了机器学习训练和推理所需的工具扩展。这包括用于神经网络建模的内置组...

weixin_39710251的博客 513

innovus:像ICC2一样设置placement label

ICC2有placement label/placement rule功能,能控制各种类型cell 之间的spacing规则,包括top和bottom edge的spacing。innovus也有相同的功能,以下示例方便大家了解用法。我们需要给所有OAI* cell之间设置一个spacing rule,让他们不要上下或者挨着。效果如下图,这个spacing指的是同一边的间距,不是cell间距。我正在「拾陆楼」和朋友们讨论有趣的话题,你⼀起来吧?

m0_61544122的博客 832

PyTorch C++ 前端是 PyTorch 机器学习框架的纯 C++ 接口

现在我们已经配置了基本环境,我们可以深入研究本教程中更有趣的部分。首先,我们将讨论如何在 C++ 前端中定义模块并与之交互。我们将从基本的小规模示例模块开始,然后使用 C++ 前端提供的广泛的内置模块库来实现全面的 GAN。N , M }));就像在 Python 中一样,我们定义了一个名为Net的类(为简单起见,这里是struct而不是class),然后从模块基类派生它。在构造器内部,我们使用创建张量,就像在 Python 中使用一样。一个有趣的区别是我们如何注册参数。

yanglamei1962的博客 2915

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

libtorch (pytorch c++前端 / pytorch的C++版本)

libtorch是pytorch c++ 前端 就是可以用c++来写pytorch libtorch(pytorch c++)的大多数api和pytorch保持一致

hxxjxw的博客 2295

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

PyTorch C++前端:高性能推理部署实战指南

你还在为PyTorch模型部署到生产环境发愁?推理延迟高、Python依赖重、动态图执行效率低?本文将带你掌握C++前端(LibTorch)的高性能推理实战,无需复杂配置,轻松实现模型落地。读完你将获得: - 3分钟上手的C++推理全流程 - 比Python快40%的性能优化技巧 - 动态批处理与多设备部署方案 ## 为什么选择C++前端? PyTorch C++前端(LibTorch)是基于...

gitblog_00721的博客 1268

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

pytorch 提取权重_利用Pytorch的C++前端(libtorch)读取预训练权重并进行预测

前言距离发布Pytorch-1.0-Preview版的发布已经有两个多月,Pytorch-1.0最瞩目的功能就是生产的大力支持,推出了C++版本的生态端(FB之前已经在Detectron进行了实验),包括C++前端和C++模型编译工具。对于我们来说,之后如果想要部署深度学习应用的时候,只需要在Python端利用Pytorch进行训练,然后使用torch.jit导出我们训练好的模型,再利用C++端的...

weixin_28785069的博客 619

使用Pytorch C++前端加载MNIST数据集失败

pytorch/torch/csrc/api/src/data/datasets/mnist.cpp 在使用Pytorch C++前端加载MNIST数据集时 需要把下载的MNIST的压缩文件先解压 再将解压后文件夹中的文件改成上面对应的名字 ...

DuanLiuchang的博客 559

解锁PyTorch新姿势:自定义CUDA算子与C++前端实战揭秘

PyTorch作为深度学习领域的主流框架,以其动态计算图和简洁API广受欢迎。然而,随着应用场景的复杂化,原生功能已难以满足所有需求,自定义CUDA算子和C++前端开发成为扩展PyTorch生态的关键技术。自定义CUDA算子通过优化GPU并行计算,显著提升模型性能,尤其在图像卷积等计算密集型任务中表现突出。C++前端开发则提供了高性能的C++接口,适用于低延迟、高并发场景,并能与现有C++项目无缝集成。本文通过图像卷积加速和实时目标检测系统等案例,展示了这些技术的实际应用价值,帮助开发者提升深度学习模型的开

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1276
上一篇: VSCODE-Tutorials-将 GCC 与 MinGW 结合使用
下一篇: ILSVRC2012数据集-图像分类
humeme
博客等级 码龄9年 25粉丝 25原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值