我正在尝试使用 Tensorflow C API 来运行与 Deeplab 图的会话。在 Cityscapes 上预训练的 Deeplab 的冻结图从这里下载:http: //download.tensorflow.org/models/deeplabv3_mnv2_cityscapes_train_2018_02_05.tar.gz
通过 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_t
和segmap_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_t
andsegmap_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 实现的时间相同。不知何故,该图未能将输出张量数据转储到我分配的缓冲区中。我究竟做错了什么?