如何转换 std::vector<float>在 C++ 中的张量流中没有复制的张量? [英] how to convert std::vector<float> to a tensor without copy in tensorflow in 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屋!