C++ 如何在c++;

C++ 如何在c++;,c++,tensorflow,eigen,C++,Tensorflow,Eigen,我正在运行一个Tensorflow模型,返回一个3D数组作为输出,但我无法从tensor中获取该数组的数据 我确实毫无问题地打印了模型输出的形状 std::vector<tf::Tensor> outputs; auto start_inference = std::chrono::high_resolution_clock::now(); _status = _session->Run({inputs}, {"k2tfout_0", "k2tfout_1"}

我正在运行一个Tensorflow模型,返回一个3D数组作为输出,但我无法从tensor中获取该数组的数据

我确实毫无问题地打印了模型输出的形状

std::vector<tf::Tensor>        outputs;
 auto start_inference = std::chrono::high_resolution_clock::now();
 _status = _session->Run({inputs}, {"k2tfout_0", "k2tfout_1"}, {}, &outputs);
if (!_status.ok())
 {
   std::cerr << _status.ToString() << std::endl;
   return 0;
 }
unsigned int output_img_n0 = outputs[0].shape().dim_size(0);
unsigned int output_img_h0 = outputs[0].shape().dim_size(1);
unsigned int output_img_w0 = outputs[0].shape().dim_size(2);
unsigned int output_img_c0 = outputs[0].shape().dim_size(3);
std::矢量输出;
自动启动推理=标准::时钟::高分辨率时钟::现在();
_状态=_会话->运行({inputs},{“k2tfout_0”,“k2tfout_1},{},&outputs);
如果(!\u status.ok())
{
std::cerr该类允许您通过多种方法访问其内容。使用
.flat
可以获得数组的展平版本,
.tensor
为您提供一个完整的数组,然后还有一些其他方法,如
.vec
/
.matrix
(如
.tensor
,维数固定为1或2)和
flat\u-inner\u-dims
/
flat\u-outer\u-dims
/
flat\u-inner\u-outer\u-dims
(为您提供了一个某些尺寸折叠的张量)。您可以使用最适合自己的。在这种情况下,例如,如果要打印张量中的所有值,可以使用
.flat
并计算相应的偏移量,或者如果您知道尺寸数为4,则可以使用
.tensor

std::vector<tf::Tensor>        outputs;
auto start_inference = std::chrono::high_resolution_clock::now();
_status = _session->Run({inputs}, {"k2tfout_0", "k2tfout_1"}, {}, &outputs);
if (!_status.ok())
{
  std::cerr << _status.ToString() << std::endl;
  return 0;
}
unsigned int output_img_n0 = outputs[0].shape().dim_size(0);
unsigned int output_img_h0 = outputs[0].shape().dim_size(1);
unsigned int output_img_w0 = outputs[0].shape().dim_size(2);
unsigned int output_img_c0 = outputs[0].shape().dim_size(3);

for (unsigned int ni = 0; ni < output_img_n0; ni++)
{
  for (unsigned int hi = 0; hi < output_img_h0; hi++)
  {
    for (unsigned int wi = 0; wi < output_img_w0; wi++)
    {
      for (unsigned int ci = 0; ci < output_img_c0; ci++)
      {
        float_t value;
        // Get vaule through .flat()
        unsigned int offset = ni * output_img_h0 * output_img_w0 * output_img_c0 +
                              hi * output_img_w0 * output_img_c0 +
                              wi * output_img_c0 +
                              ci;
        value = outputs[0].flat<float_t>()(offset);
        // Get value through .tensor()
        value = outputs[0].tensor<float_t, 4>()(ni, hi, wi, ci);
        std::cout << "output[0](" << ni << ", " << hi << ", " << wi << ", " << ci << ") = ";
        std::cout << value << std::endl;
      }
    }
  }
}
编辑:

如果要获取指向张量数据的指针(例如,从同一缓冲区构建另一个对象,避免复制或迭代),您也可以这样做。一个选项是使用
.tensor\u data
方法,该方法返回一个
tensorflow::StringPiece
,它反过来是一个,它只是一个多边形填充。因此,此对象的
.data
方法将为您提供指向该tensor的底层字节缓冲区的指针(请注意
.tensor_data
文档中的警告:“底层的tensor缓冲区已重新计数”,因此在使用缓冲区时不要让返回的对象被销毁)。因此,您可以:

tf::StringPiece output0Str = outputs[0].tensor_data();
const char* output0Ptr = output0Str.data();
但是,这会给您一个指向
字符的指针,因此您必须将其强制转换为浮点。它应该是安全的,但看起来很难看,因此您可以让Eigen为您执行此操作。所有Eigen对象都有一个
.data
方法,该方法将其类型的指针返回到基础缓冲区。例如:

// Make tensor
tf::TTypes<float_t, 4>::Tensor outputTensor0 = outputs[0].tensor<float_t, 4>();
// Query tensor multiple times
for (...)
{
    std::cout << outputTensor0(ni, hi, wi, ci) << std::endl;
}
const float_t* output0Ptr = outputs[0].flat<float_t>().data();
const float_t*output0Ptr=outputs[0].flat().data();

谢谢你的回答。因此,没有直接的方法从张量对象获取数组数据,即图像;我需要一个for循环来遍历它并读取它。@Zaher88abd不,如果这是你的意思,你也可以获得指向数据的指针。我已经扩展了答案,解释了这一点。再次感谢你的帮助。我尝试了很多次读取数组的方法,但我失败了,因此,可能会要求您举例说明如何读取图像形式
输出[1].matrix().data();
,它应该在这个dims
浮动img[output\u img\u h0][output\u img\u w0][output\u img\u c0]
。删除第一个维度后,批大小。@Zaher88abd您没有描述
输出[1]
在你的问题中。它是一个矩阵(2维张量)吗?尺寸是多少,它如何用多个通道表示图像?我仍然不确定你到底想用张量数据做什么…我编辑了这个问题,并在输出[1]中添加了形状,即[1480600,3]=[m,h,w,c]其中c是图像的通道。谢谢你们的帮助,我很感激。
const float_t* output0Ptr = outputs[0].flat<float_t>().data();