Tensorflow:TF_SessionRun返回TF_INVALID_ARGUMENT

时间:2019-08-25 17:42:53

标签: c tensorflow deeplab

我正在使用Tensorflow C API从Deeplabv3的冻结图运行会话。当我开始使用TF_SessionRun运行会话时,返回值为3,表示TF_INVALID_ARGUMENT。我怀疑它可能必须与我离开TF_Operation*的{​​{1}}输入(第8个参数,又称“目标操作”参数)做些事情,但是我找不到关于此参数表示的任何文档。以下是我对TF_SessionRun的有问题的调用:

来自 tiny_deeplab_api.cpp

NULL

其中 // Allocate the input tensor TF_Tensor* const input = TF_NewTensor(TF_UINT8, img->dims, 3, 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_UINT8, seg->dims, 2, 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, NULL, &oper_in_, &input, 1, &oper_out_, &output, 1, NULL, 0, NULL, status); return TF_GetCode(status); // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/tf_status.h#L42 imgsegimage_t类型,其中包含指向数据和segmap_t方法可用于的维数组的指针生成输入和输出张量,然后传递给TF_NewTensor()。 (来自 tiny_deeplab_api.hpp ):

TF_SessionRun()

下面是源代码,以防问题不明显...

test.cpp:

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

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

tiny_deeplab_api.hpp:

#include <opencv2/opencv.hpp>
#include "tiny_deeplab_api.hpp"
#include <iostream>
#include <algorithm>

int main() {
    using namespace std;
    using namespace cv;

    // Initialize Deeplab object
    Deeplab dl = Deeplab();
    cout << "Successfully constructed Deeplab object" << endl;

    // Read & resize input image
    Mat image = imread("/Users/Daniel/Desktop/cat.jpg"); 
    int orig_height = image.size().height;
    int orig_width = image.size().width;
    double resize_ratio = (double) 513 / max(orig_height, orig_width);
    Size new_size((int)(resize_ratio*orig_width), (int)(resize_ratio*orig_height));
    Mat resized_image;
    resize(image, resized_image, new_size);
    cout << "Image resized (h, w): (" << orig_height << "," << orig_width << ") --> (" << new_size.height << ", " << new_size.width << ")" << endl;
    imshow("Image", resized_image);
    waitKey(0);


    // Allocate input image object
    const int64_t dims_in[3] = {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 = 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[2] = {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 = (uint8_t*)malloc(new_size.width*new_size.height);
    seg_out->bytes = new_size.width*new_size.height*sizeof(uint8_t);

    // Run Deeplab
    cout << "Running segmentation" << endl;
    int status = dl.run_segmentation(img_in, seg_out);
    if(status != 0) {
        cout << "ERROR RUNNING SEGMENTATION: " << status << endl;
        return 1;
    }

    cout << "Successfully ran segmentation" << endl;

    // Interpret results

    return 0;
}

tiny_deeplab_api.cpp:

#ifndef TINY_DEEPLAB_API_HPP_
#define TINY_DEEPLAB_API_HPP_

#include <tensorflow/c/c_api.h>

TF_Buffer* read_file(const char* file);
void free_buffer(void* data, size_t length);
void free_tensor(void* data, size_t length, void* args);

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

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


class Deeplab {
   private:
    TF_Session* session;
    TF_Graph* graph;
    TF_Output output_oper;
    TF_Output input_oper;
    TF_Status* status;

   public:
    Deeplab(); // Constructor 
    ~Deeplab();
    int run_segmentation(image_t*, segmap_t*);
};

#endif // TINY_DEEPLAB_API_HPP_

运行#include <stdio.h> #include <stdlib.h> #include <iostream> #include <tensorflow/c/c_api.h> #include "tiny_deeplab_api.hpp" Deeplab::Deeplab() { using namespace std; cout << "Hello from TensorFlow C library version" << TF_Version() << endl; // Import Deeplab graph (as a frozen graph, it has the weights hard-coded in as constants, so no need to restore the checkpoint) TF_Buffer* graph_def = read_file("../Models/Deeplab_model_unpacked/deeplabv3_mnv2_cityscapes_train/frozen_inference_graph.pb"); graph = TF_NewGraph(); status = TF_NewStatus(); TF_ImportGraphDefOptions* opts = TF_NewImportGraphDefOptions(); TF_GraphImportGraphDef(graph, graph_def, opts, status); TF_DeleteImportGraphDefOptions(opts); if (TF_GetCode(status) != TF_OK) { fprintf(stderr, "ERROR: Unable to import graph %s", TF_Message(status)); return; } cout << "Successfully loaded Deeplab graph" << endl; TF_DeleteBuffer(graph_def); // Initialize Session TF_SessionOptions* sess_opts = TF_NewSessionOptions(); session = TF_NewSession(graph, sess_opts, status); } Deeplab::~Deeplab() { using namespace std; TF_CloseSession(session, status); TF_DeleteSession(session, status); TF_DeleteStatus(status); TF_DeleteGraph(graph); cout << "Destroyed Deeplab object" << endl; } int Deeplab::run_segmentation(image_t* img, segmap_t* seg) { //TODO: Delete old TF_Tensor, TF_Operation, and TF_Output // Allocate the input tensor TF_Tensor* const input = TF_NewTensor(TF_UINT8, img->dims, 3, 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_UINT8, seg->dims, 2, 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, NULL, &oper_in_, &input, 1, &oper_out_, &output, 1, NULL, 0, NULL, status); return TF_GetCode(status); // https://github.com/tensorflow/tensorflow/blob/master/tensorflow/c/tf_status.h#L42 } TF_Buffer* read_file(const char* file) { FILE *f = fopen(file, "rb"); fseek(f, 0, SEEK_END); long fsize = ftell(f); fseek(f, 0, SEEK_SET); //same as rewind(f); void* data = malloc(fsize); fread(data, fsize, 1, f); fclose(f); TF_Buffer* buf = TF_NewBuffer(); buf->data = data; buf->length = fsize; buf->data_deallocator = free_buffer; return buf; } void free_buffer(void* data, size_t length) { free(data); } void free_tensor(void* data, size_t length, void* args) { free(data); } 的输出:

./test

1 个答案:

答案 0 :(得分:0)

答案是,由于某种原因(为什么?),Deeplab输入和输出张量的尺寸不是{width,height,3}和{width,height},而是{1,width,height,3}和{1,宽度,高度}。在制作了这种形式的维数组之后,TF_SessionRun运行无误。