官方文档地址:
https://pytorch.org/cppdocs/
说明:以下是我学习笔记,大部分内容摘录自官方文档,也添加了一些案例。
PyTorch C++ API大致可以分为五个部分:
结合起来,这些构建块形成了一个研究和生产就绪的 C++ 库,用于张量计算和动态神经网络,重点是 GPU 加速和快速 CPU 性能。
ATen 本质上是一个张量库,PyTorch 中几乎所有其他 Python 和 C++ 接口都建立在它之上。它提供了一个核心Tensor类,在该类上定义了数百个操作。
#include
at::Tensor a = at::ones({2, 2}, at::kInt);
at::Tensor b = at::randn({2, 2});
auto c = a + b.to(at::kInt);
autograd是 PyTorch 的 C++ API 的一部分,它Tensor通过自动微分功能增强了 ATen类。autograd 系统记录对张量的操作以形成autograd 图。调用backwards()执行反向模式微分,最终产生梯度。
#include
#include
torch::Tensor a = torch::ones({2, 2}, torch::requires_grad());
torch::Tensor b = torch::randn({2, 2});
auto c = a + b;
c.backward(); // a.grad() will now hold the gradient of c w.r.t. a.
注意:这里需要关注at::Tensor和torch::Tensor的区别!
ATen 中的类默认是不可微的。要添加 autograd API 提供的Tensor的可微性,就必须使用来自torch::命名空间,而不是at::命名空间的Tensor函数。例如,虽然使用at::ones创建的Tensor将不可微,但使用torch::ones创建的Tensor将是可微的。
PyTorch C++ 前端是一个用于 CPU 和 GPU 张量计算的 C++14 库,具有用于最先进机器学习应用程序的自动微分和高级构建块。它由以下组件组成:
语法上基本和Python上是一样的,基本你熟悉pytorch就可以直接使用。
案例:Mnist的模型定义
Python版本
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.conv1 = nn.Conv2d(1, 10, kernel_size=5)
self.conv2 = nn.Conv2d(10, 20, kernel_size=5)
self.conv2_drop = nn.Dropout2d()
self.fc1 = nn.Linear(320, 50)
self.fc2 = nn.Linear(50, 10)
def forward(self, x):
x = F.relu(F.max_pool2d(self.conv1(x), 2))
x = F.relu(F.max_pool2d(self.conv2_drop(self.conv2(x)), 2))
x = x.view(-1, 320)
x = F.relu(self.fc1(x))
x = F.dropout(x, training=self.training)
x = self.fc2(x)
return F.log_softmax(x, dim=1)
C++版本
struct Net : torch::nn::Module {
Net()
: conv1(torch::nn::Conv2dOptions(1, 10, /*kernel_size=*/5)),
conv2(torch::nn::Conv2dOptions(10, 20, /*kernel_size=*/5)),
fc1(320, 50),
fc2(50, 10) {
register_module("conv1", conv1);
register_module("conv2", conv2);
register_module("conv2_drop", conv2_drop);
register_module("fc1", fc1);
register_module("fc2", fc2);
}
torch::Tensor forward(torch::Tensor x) {
x = torch::relu(torch::max_pool2d(conv1->forward(x), 2));
x = torch::relu(
torch::max_pool2d(conv2_drop->forward(conv2->forward(x)), 2));
x = x.view({-1, 320});
x = torch::relu(fc1->forward(x));
x = torch::dropout(x, /*p=*/0.5, /*training=*/is_training());
x = fc2->forward(x);
return torch::log_softmax(x, /*dim=*/1);
}
torch::nn::Conv2d conv1;
torch::nn::Conv2d conv2;
torch::nn::FeatureDropout conv2_drop;
torch::nn::Linear fc1;
torch::nn::Linear fc2;
};
TorchScript 是一种 PyTorch 模型的表示,可以被 TorchScript 编译器理解、编译和序列化。从根本上说,TorchScript 本身就是一种编程语言。它是使用 PyTorch API 的 Python 子集。TorchScript 的 C++ 接口包含三个主要功能:
前面我几篇文章写的,从Python中定义模型,但随后将它们导出到 C++ 以用于生产环境推理,就属于这种情况。另外,还有个torch::jit::compile 函数可用于直接从 C++ 访问 TorchScript 编译器。
案例:TorchScript推理
Python版本
def TorchTest():
{
example = torch.rand(1, 3, 224, 224)
model = models.resnet50(pretrained=True)
model = model.eval()
output = model (example)
print(output)
return output
}
C++版本
void TorchTest(){
std::shared_ptr<torch::jit::script::Module> module = torch::jit::load("../resnet.pt");
assert(module != nullptr);
std::cout << "Load model successful!" << std::endl;
std::vector<torch::jit::IValue> inputs;
inputs.push_back(torch::zeros({1,3,224,224}));
at::Tensor output = module->forward(inputs).toTensor();
auto max_result = output.max(1, true);
auto max_index = std::get<1>(max_result).item<float>();
std::cout << max_index << std::endl;
}
C++ 扩展 API 没有向 PyTorch C++ API 添加任何新功能。相反,它提供了与 Python setuptools 的集成以及允许从 Python 访问 ATen、autograd 和其他 C++ API 的 JIT 编译机制。
这部分我也没仔细看,暂时用不到。
PyTorch C++ API 文件层次
完整的API信息查询
https://pytorch.org/cppdocs/api/library_root.html