如何转换 std::vector<float>在 C++ 中的张量流中没有复制的张量? [英] how to convert std::vector&lt;float&gt; to a tensor without copy in tensorflow in c++?

查看:37
本文介绍了如何转换 std::vector<float>在 C++ 中的张量流中没有复制的张量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 C++ 中,多维矩阵存储在 std::vector 中.我需要在使用张量的 tensorflow 中使用它.从 std::vector 到张量的转换似乎并不明显.有一个 c_api 将向量转换为 TF_Tensor 而不是 Tensor.std::copy 也有效,但我想在没有复制的情况下执行转换.

In c++, a multidimensional matrix is stored in std::vector<float>. I need to use it in tensorflow, which uses tensors. The conversion from a std::vector to a tensor seems not obvious. There is a c_api which convert a vector to a TF_Tensor instead of Tensor. std::copy also works, but I want to perform a conversion without copy.

推荐答案

Tensorflow 现在可以通过提供您自己的 tensorflow::TensorBuffer 并使用并使用以下构造函数:

Tensorflow now has a way to do this in the C++ API by providing your own tensorflow::TensorBuffer and using the following constructor:

#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/core/framework/types.pb.h>
...
tensorflow::Tensor(tensorflow::DataType type, const TensorShape & shape, TensorBuffer *buf)

由于 tensorflow::TensorBuffer 是一个抽象类,您需要对其进行子类化并自己实现一些方法(也就是说,这很容易做到).需要注意的一件事:注意我们如何让 OwnsMemory() 返回 false.如果您想使用手动内存管理(malloc/free 或 new/delete),您可以将其设置为 true,然后自己覆盖析构函数.也就是说,由于您使用的是 vector,我只需将其设置为 false 并注意不要让缓冲区超出范围.当它这样做时,vector 无论如何都会释放它自己的内部存储器.

Since tensorflow::TensorBuffer is an abstract class, you'll need to subclass it and implement a few methods yourself (that said, it's fairly easy to do). One thing to note: notice how we have OwnsMemory() returning false. If you want to use manual memory management (malloc/free or new/delete), you can set this to true and then override the destructor yourself. That said, since you're using a vector I'd just set it to false and take care to not have the buffer go out of scope. When it does, vector will free its own internal memory anyways.

例如;

class MyBuffer: public tensorflow::TensorBuffer {
    std::size_t len_;
  public:
    MyBuffer(void* data, std::size_t len): len_(len), tensorflow::TensorBuffer(data){}
    //returns how many bytes we have in our buffer
    std::size_t size() const override {return len_;};
    //needed so TF knows this isn't a child of some other buffer
    TensorBuffer* root_buffer() override { return this; }
    // Not actually sure why we need this, but it lets TF know where the memory for this tensor came from
    void FillAllocationDescription(tensorflow::AllocationDescription* proto) const override{};
    // A value of false indicates this TensorBuffer does not own the underlying data
    bool OwnsMemory() const override { return false; }
}

然后,您只需要提供正确的tensorflow::DataType(例如;tensorflow::DT_FLOAT32)和一个tensorflow::TensorShape> (您可以实例化它并使用 <TensorShape>.addDim(<the dimension>) 添加每个维度.您可以通过存储 std::vector 来修改上述内容code> 内部,然后通过使用 .data()void* 强制转换来公开内容,为 MyBuffer 创建一个构造函数,它接受一个向量.或者你可以在 MyBuffer 之外自己做.

Then, you just need to provide the correct tensorflow::DataType (eg; tensorflow::DT_FLOAT32) and a tensorflow::TensorShape (you can just instantiate it and add each dimension using <TensorShape>.addDim(<the dimension>). You could modify the above by storing the std::vector inside and then exposing the contents by using .data() and a void* cast to make a constructor for MyBuffer that takes in a vector. Or you could just do that yourself outside of MyBuffer.

这篇关于如何转换 std::vector<float>在 C++ 中的张量流中没有复制的张量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆