历经千辛万苦!...
我学会了更好地使用Pytorch Discuss论坛获取Pytorch和Libtorch信息。例如,使用标签 C++。
不幸的是,有 官方的信息来源(虽然很混乱)。这就是我在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
等价物。所以这是我的黄金提示:
使用 C++ 等效函数翻译你的 python 脚本,例如,copy_
测试它(以确保它工作),而不是仅仅去 C++ 复制所有内容。narrow
slice