【问题标题】:Subtensor of a Tensorflow tensor (C++)Tensorflow 张量的子张量 (C++)
【发布时间】:2018-04-17 15:46:14
【问题描述】:

我在 C++ 中有一个 tensorflow::Tensor batch,形状为 [2, 720, 1280, 3](#images x height x width x #channels)。

我想得到另一个只有第一张图像的张量,因此我会有一个形状为 [1, 720, 1280, 3] 的张量。换句话说,我想要:

tensorflow::Tensor first = batch[0]

实现它的最有效方法是什么?

我知道如何在 python 中做到这一点,但是 C++ api 和文档不如 python。

【问题讨论】:

  • 也许你可以显示一些 sn-p 的上下文?你有一个tensorflow::Tensor,对吧?您想用该图像生成另一个tensorflow::Tensor,或者将该数据提取到其他东西中?
  • 没错。我有一个 tensorflow::Tensor,我想要一个只有第一张图像的“子张量”。换句话说,我想要的基本上是 originalTensor[0, :, :, :]。我将根据您的建议编辑我的问题。
  • 谢谢。那么您期望结果中的形状是[1, 720, 1280, 3] 还是[720, 1280, 3]?我知道元素的数量是相同的,但张量的构造略有不同。在 Python 中,你会得到第一个 batch[:1] 和第二个 batch[0]
  • 我更喜欢形状为 [1, 720, 1280, 3] 的结果,但毕竟 [720, 1280, 3] 可能不是问题。

标签: c++ tensorflow


【解决方案1】:

花了一些时间尝试通过复制实现后,我意识到API中支持此操作Slice

tensorflow::Tensor first = batch.Slice(0, 1);

请注意,如文档所述,返回的张量与切片的张量共享内部缓冲区,如果这与您相关,两个张量的对齐方式可能不同。


编辑:

既然我已经这样做了,这里是我尝试复制相同的功能,基于副本。我认为它应该可以工作(它与我在其他情况下使用的非常相似)。

#include <cstdlib>
#include <cassert>
#include <tensorflow/core/framework/tensor.h>
#include <tensorflow/core/framework/tensor_shape.h>

tensorflow::Tensor get_element(const tensorflow::Tensor data, unsigned int index, bool keepDim)
{
    using namespace std;
    using namespace tensorflow;

    typedef typename tensorflow::DataTypeToEnum<T> DataType;
    auto dtype = DataType::v();
    assert(dtype == data.dtype());

    auto dtype = data.dtype();
    auto dataShape = data.shape();

    TensorShape elementShape;
    if (keepDim)
    {
        elementShape.addDim(1);
    }
    for (int iDim = 1; iDim < dataShape.dims(); iDim++) {
      elementShape.AddDim(dataShape.dim_size(iDim));
    }
    Tensor element(dtype, elementShape);
    auto elementBytes = elementShape.num_elements() * DataTypeSize(dtype);

    memcpy(element.flat<void>().data(),
           batch.flat<void>().data() + elementBytes * index,
           elementBytes);
    return element;
}

int main()
{
    Tensor batch =  ...;
    Tensor first = get_element(batch, 0);
    return 0;
}

如果您只想将数据提取到例如向量或其他东西中,也可以更改代码。

【讨论】:

  • 感谢您的回答。它有效,但我现在在代码后面使用函数 flat() 进行对齐时遇到了问题,正如文档所报告的那样。同样,文档对此并不十分清楚。你知道“对齐”是什么意思吗?
  • @ArnaldoGualberto 说实话,关于这究竟意味着什么以及该警告的含义是什么的文档很少。我的理解(我可能错了)是如果 IsAligned() 返回 false 然后调用 flat() 和类似的将无法按预期工作。在这种情况下,也许您可​​以copy-construct 另一个张量并对其进行操作?
  • 实际上,创建一个要求更好地澄清这一点和/或一些示例的问题可能是有意义的。
  • @ArnaldoGualberto 我已经添加了我的基于副本的尝试,以防你觉得有用...
  • 假设我将图像分组在轨道中,因此暗淡为[4, 2, 720, 1280, 3]。我想要第一首曲目的第一张图片。有没有办法通过 C++ API 做到这一点?看起来 slice 只适用于第一个维度。
【解决方案2】:

这很好用

#include "tensorflow/core/framework/tensor_slice.h"

Tensor t2 = t1.Slice(0,1);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多