将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是啥?

Posted

技术标签:

【中文标题】将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是啥?【英文标题】:What is the most efficient way of converting a std::vector<std::tuple<>> to a torch::Tensor?将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是什么? 【发布时间】:2021-05-29 11:22:08 【问题描述】:

我有一个元组向量,需要将其转换为torch::Tensor。到目前为止,我想出的是香草方法,如下所示:

std::vector<torch::Tensor> anchors;
std::vector<std::tuple<float, float, float, float>> anchors_raw;

//...
for (auto& rows: anchors_raw)
    
        auto& [cx, cy, s_kx, s_ky] = rows;
        anchors.emplace_back(std::move(torch::stack( std::move(torch::tensor(cx)),
                                                     std::move(torch::tensor(cy)),
                                                     std::move(torch::tensor(s_kx)),
                                                     std::move(torch::tensor(s_ky))
                                                    , 0)));
    
    outo output = std::move(torch::stack(std::move(anchor)).view( -1,4 ));
    //...

我使用的是 Torch 1.7。还有其他可能更有效的方法吗?

【问题讨论】:

【参考方案1】:

我不知道有任何 libtorch 功能可以轻松做到这一点。我会建议使用torch::from_blob,希望数据可以连续存储,但我发现this thread 另有说明。

所以如果可能,我的建议是将你的tuple&lt;float, float...&gt;替换为std::array&lt;float, 4&gt;(内存布局是连续的),并执行类似的操作

std::vector<std::array<float,4>> anchors_raw;
// ...
auto options = torch::TensorOptions().dtype(at::kFloat);
auto anchors = torch::from_blob(&anchors_raw[0][0], anchors_raw.size(), 4, options).clone()

我目前无法尝试,所以我希望它可以编译并运行良好,但我相信它应该可以工作,所有浮点值都应该连续存储在向量和数组中,所以from_blob会工作。

与往常一样,如果在您完成 anchors 之前,anchors_raw 有超出范围的风险,则需要调用 clone。如果您确定anchors_raw 的寿命会比anchors 的寿命长,您可以取消调用。

【讨论】:

非常感谢,一如既往的感谢。这工作得很好,虽然我必须做一些小的改动,比如将anchors_raw.size() 转换为int,而且我选择了struct 而不是std::array。出色的工作让我的生活更甜蜜 600 倍:-D

以上是关于将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

这段代码安全吗?将 std::vector<Derived*> 强制转换为 std::vector<Base*>

将 std::stack 复制到 std::vector

如何将std :: vector的大小作为int?

使用 std::optional 通过引用将 std::vector<int> 传递给函数

将 std::vector<std::tuple<>> 转换为 torch::Tensor 的最有效方法是啥?

将两个 std::vector<cv::Point> 向量和安全公共点与第三个 std::vector<cv::Point> 进行比较