0

我正在尝试使用 Tensorflow C API 来运行与 Deeplab 图的会话。在 Cityscapes 上预训练的 Deeplab 的冻结图从这里下载:http: //download.tensorflow.org/models/deeplabv3_mnv2_cityscapes_train_2018_02_05.tar.gz

当我使用 python 运行时,我得到了这个分段输出: 使用 Python 进行分割输出

通过 python line: 打印出图的所有张量tensors = [n.values() for n in tf.get_default_graph().get_operations()] ,我发现输入张量的维度是 {1,?,?,3},输出张量是 {1,?,?},而输入和输出张量的数据类型分别为 uint8 和 int64。我使用这些信息编写了一个 C++ 方法来运行图形会话:

int Deeplab::run_segmentation(image_t* img, segmap_t* seg) {
    using namespace std;

    // Allocate the input tensor
    TF_Tensor* const input = TF_NewTensor(TF_UINT8, img->dims, 4, img->data_ptr, img->bytes, &free_tensor, NULL);
    TF_Operation* oper_in = TF_GraphOperationByName(graph, "ImageTensor");
    const TF_Output oper_in_ = {oper_in, 0};

    // Allocate the output tensor
    TF_Tensor* output = TF_NewTensor(TF_INT64, seg->dims, 3, seg->data_ptr, seg->bytes, &free_tensor, NULL);
    TF_Operation* oper_out = TF_GraphOperationByName(graph, "SemanticPredictions");
    const TF_Output oper_out_ = {oper_out, 0};

    // Run the session on the input tensor
    TF_SessionRun(session, nullptr, &oper_in_, &input, 1, &oper_out_, &output, 1, nullptr, 0, nullptr, status);

    return TF_GetCode(status); // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/tf_status.h#L42 
}

其中参数类型image_tsegmap_t包含调用 TF_NewTensor 所需的参数。它们只是保存指向为输入/输出张量分配的缓冲区的指针、张量的尺寸和以字节为单位的大小:

typedef struct segmap {
    const int64_t* dims;
    size_t bytes;
    int64_t* data_ptr;
} segmap_t;

typedef struct image {
    const int64_t* dims;
    size_t bytes;
    uint8_t* data_ptr;
} image_t;

然后,我使用 OpenCV 用街景图像填充一个数组(与上面相同),并将image_tandsegmap_t结构传递给会话运行方法:

    // Allocate input image object
    const int64_t dims_in[4] = {1, new_size.width, new_size.height, 3};
    image_t* img_in = (image_t*)malloc(sizeof(image_t));
    img_in->dims = &dims_in[0];
    //img_in->data_ptr = (uint8_t*)malloc(new_size.width*new_size.height*3);
    img_in->data_ptr = resized_image.data;
    img_in->bytes = new_size.width*new_size.height*3*sizeof(uint8_t);

    // Allocate output segmentation map object
    const int64_t dims_out[3] = {1, new_size.width, new_size.height};
    segmap_t* seg_out = (segmap_t*)malloc(sizeof(segmap_t));
    seg_out->dims = &dims_out[0];
    seg_out->data_ptr = (int64_t*)calloc(new_size.width*new_size.height, sizeof(int64_t));
    seg_out->bytes = new_size.width*new_size.height*sizeof(int64_t);

但生成的张量 ( set_out->data_ptr) 由全 0 组成。该图似乎执行了大约 5 秒,与工作 python 实现的时间相同。不知何故,该图未能将输出张量数据转储到我分配的缓冲区中。我究竟做错了什么?

4

1 回答 1

0

有两个错误:

首先,Deeplab 的输入张量维度为 {1, height, width, 3},输出张量维度为 {1, height, width}。所以我不得不交换高度和宽度。

此外,出于某种原因,您必须使用该方法从张量中获取数据TF_TensorDataTF_NewTensor(..., data_ptr, ...)通过做,然后运行TF_SessionRun,最后访问来创建输出张量data_ptr不起作用。TF_AllocateTensor(...)您必须通过调用、运行TF_SessionRun和访问张量数据来创建输出张量TF_TensorData(&tensor)

于 2019-08-31T18:17:16.960 回答