c++ - 如何将代码从 Python Pytorch 翻译或转换为 C++ Libtorch

标签 c++ pytorch libtorch

我无法在 Libtorch(Pytorch C++ 前端)中为我的 Python Pytorch 代码找到等效的 C++ 调用。

根据我的搜索 ( Pytorch Discuss ) 的文档对于我的代码尚不存在。我想知道是否有人可以用以下部分(如下)指导我。

我删除了 Libtorch C++ 发生更多崩溃(错误使用)的部分。

import torch as th

th.set_grad_enabled(False)
...
X = th.zeros((nobs, 3+p), device=dev, dtype=th.float32)
y = th.tensor(indata, device=dev, dtype=th.float32)
diffilter = th.tensor([-1., 1.], device=dev, dtype=th.float32).view(1, 1, 2)
dy = th.conv1d(y.view(1, 1, -1), diffilter).view(-1)
z = dy[p:].clone()
...
# X matrix
X[:, 0] = 1 
X[:, 1] = th.arange(p+1, n) 
X[:, 2] = y[p:-1]
...
# master X 
Xm = th.zeros((nobsadf, 3+p), device=th.device('cpu'), dtype=th.float32)
...
# batch matrix, vector and observations
Xbt = th.zeros(batch_size, adfs_count, nobsadf, (3+p), device=th.device('cpu'), dtype=th.float32)
...
t = 0 # start line for master main X OLS matrix/ z vector
for i in range(nbatchs):
    for j in range(batch_size): # assembly batch_size matrixes
        Xm[:] = X[t:t+nobsadf] 
        ...
        Xbt[j, :, :, :] = Xm.repeat(adfs_count, 1).view(adfs_count, nobsadf, (3+p))            
        for k in range(adfs_count): 
            Xbt[j, k, :k, :] = 0
            nobt[j, k] = float(nobsadf-k-(p+3))

最佳答案

经历了很多痛苦之后!...

我学会了更好地使用 Pytorch Discuss PytorchLibtorch 信息论坛。例如使用标签 C++。

不幸的是,there 是官方信息来源(虽然很乱)。这就是为什么我在 SO 中分享我的答案的原因。

namespace th = torch;
...
// th.set_grad_enabled(False)
th::NoGradGuard guard; // or same as with torch.no_grad(): block 
...
auto dtype_option = th::TensorOptions().dtype(th::kFloat32);
//X = th.zeros((nobs, 3+p), device=dev, dtype=th.float32)
//y = th.tensor(indata, device=dev, dtype=th.float32)
//diffilter = th.tensor([-1., 1.], device=dev, dtype=th.float32).view(1, 1, 2)
//dy = th.conv1d(y.view(1, 1, -1), diffilter).view(-1)
//z = dy[p:].clone()
auto X = th::zeros({nobs, 3+p}, dtype_option);
auto y = th::from_blob(signal, {n}, dtype_option);
auto diffilter = th::tensor({-1, 1}, dtype_option).view({ 1, 1, 2 }); // first difference filter
auto dy = th::conv1d(y.view({ 1, 1, -1 }), diffilter).view({ -1 });
auto z = dy.slice(0, p).clone();
...
// X[:, 0] = 1 # drift
// X[:, 1] = th.arange(p+1, n) 
// X[:, 2] = y[p:-1]
// create acessors to fill in the matrix
auto ay = y.accessor<float, 1>(); // <1> dimension
auto aX = X.accessor<float, 2>(); // <2> dimension
for (auto i = 0; i < nobs; i++) {
    aX[i][0] = 1; 
    aX[i][1] = p + 1 + i; 
    aX[i][2] = ay[p+i];  
}
...
// Xm = th.zeros((nobsadf, 3+p), device=th.device('cpu'), dtype=th.float32)
auto Xm = th::zeros({ nobsadf, 3 + p }, dtype_option.device(th::Device(th::kCPU)));
// Xbt = th.zeros(batch_size, adfs_count, nobsadf, (3+p), device=th.device('cpu'), dtype=th.float32)
auto Xbt = th::zeros({ batch_size, adfs_count, nobsadf, (3 + p) }, dtype_option.device(th::Device(th::kCPU)));
...
// this acessor will be used in the inner for loop k
auto anobt = nobt.accessor<float, 2>();
auto tline = 0; // start line for master main X OLS matrix/ z vector
for (int i = 0; i < nbatchs; i++){
    for (int j = 0; j < batch_size; j++){ // assembly batch_size matrixes
        // Xm[:] = X[t:t+nobsadf]
        Xm.copy_(X.narrow(0, tline, nobsadf)); 
        ... 
        // Xbt[j, :, :, :] = Xm.repeat(adfs_count, 1).view(adfs_count, nobsadf, (3+p))   
        auto Xbts = Xbt.select(0, j);
        Xbts.copy_(Xm.repeat({ adfs_count, 1 }).view({ adfs_count, nobsadf, (3 + p) }));
        for (int k = 0; k < adfs_count; k++) { 
            // Xbt[j, k, :k, :] = 0
            // nobt[j][k] = float(nobsadf - k - (p + 3));
            Xbts.select(0, k).narrow(0, 0, k).fill_(0);
            anobt[j][k] = float(nobsadf - k - (p + 3));
        }
        tline++;
    }
}
      

可能有更好或更快的编码方式,但上面的代码完全有效。随意提出改进我的代码的建议。

上述常用函数的C++签名

Tensor Tensor::slice(int64_t dim, int64_t start, int64_t end, int64_t step)

Tensor Tensor::narrow(int64_t dim, int64_t start, int64_t length) 

Tensor Tensor::select(int64_t dim, int64_t index)

Tensor & Tensor::copy_(const Tensor & src, bool non_blocking=false)

补充说明:

几乎所有的 C++ 函数都有 Pytorch Python 等价物。所以这是我的黄金秘诀:

Translate your python script using C++ equivalent functions like copy_, narrow, slice testing it (to make sure it works) than just go to C++ replicating everything.

关于c++ - 如何将代码从 Python Pytorch 翻译或转换为 C++ Libtorch,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60059438/

相关文章:

backpropagation - 如何计算多个图像的损失,然后反向传播平均损失并更新网络权重

c++ - Pytorch C++ 运行时错误 : Expected object of device type cuda but got device type cpu for argument #1 'self' in call to _th_index_select

c++ - 如何摆脱第三方框架(gstreamer)中的内存泄漏

c++ - 我可以使 GetOpenFileName 返回路径长于 MAX_PATH 吗?

c++ - gcc 4.8 或更早版本是否存在关于正则表达式的问题?

c++ - 是否有可直接嵌入 C/C++ 程序的 C/C++ 编译器/链接器?

python - 如何在 PyTorch 中获得导数的完整雅可比行列式?

python - 如何将基于 pytorch cpu 的转换转换为基于 cuda 的转换?

python - pytorch torch.jit.trace 返回函数而不是 torch.jit.ScriptModule

c++ - 使用 Libtorch + OpenCV + QT Creator 时出错