mdietrichstein / tensorflow-open_nsfw

Tensorflow Implementation of Yahoo's Open NSFW Model
Other
430 stars 136 forks source link

a segment fault happend when I translate this code to C++ #9

Closed kylezhang1983 closed 6 years ago

kylezhang1983 commented 6 years ago

Hi @mdietrichstein ,

I try to translate your code to C++ ,and a segment fault happend when call tf_session->Run(input_tname,output_tname,output_node,&output_tensor). I used caffe2tensoflow to convert caffe model to tensorflow pbfile would you mind having a look what's wrong in my code as i'm newer in tensorlow, thank you so much:

`#include

include

include

include

include

include

include

include

include

include

include "tensorflow/cc/ops/const_op.h"

include "tensorflow/cc/ops/image_ops.h"

include "tensorflow/cc/ops/standard_ops.h"

include "tensorflow/core/framework/graph.pb.h"

include "tensorflow/core/framework/tensor.h"

include "tensorflow/core/graph/default_device.h"

include "tensorflow/core/graph/graph_def_builder.h"

include "tensorflow/core/lib/core/errors.h"

include "tensorflow/core/lib/core/stringpiece.h"

include "tensorflow/core/lib/core/threadpool.h"

include "tensorflow/core/lib/io/path.h"

include "tensorflow/core/lib/strings/stringprintf.h"

include "tensorflow/core/platform/init_main.h"

include "tensorflow/core/platform/logging.h"

include "tensorflow/core/platform/types.h"

include "tensorflow/core/public/session.h"

include "tensorflow/core/util/command_line_flags.h"

include "opencv2/highgui/highgui.hpp"

include "opencv2/imgproc/imgproc.hpp"

include "opencv2/core/core.hpp"

using tensorflow::Flag; using tensorflow::Tensor; using tensorflow::Status; using tensorflow::string; using tensorflow::int32;

// Given an image file name, read in the data,resize it to the yahoo requested size, and then scale the values as desired. tensorflow::Status YahooImageLoader(string file_name, cv::Mat &img) { auto root = tensorflow::Scope::NewRootScope(); using namespace ::tensorflow::ops; // NOLINT(build/namespaces)

cv::Mat src= cv::imread(file_name );
if(!src.data)
{
    std::cerr << "Could not open or find the image at " << file_name << std::endl;
    return tensorflow::errors::NotFound("Failed to load compute graph at '", file_name, "'");
}
std::cout<<"file_name:"<<file_name<<std::endl;
int widthOrigin = src.cols;
int heightOrigin = src.rows;
//here hard code as Yahoo open_nsfw trained model using this size
cv::resize(src, src, cv::Size(224,224),0,0);
src.convertTo(src, CV_32FC3);
cv::Mat cv_data_mean(224, 224, CV_32FC3, cv::Scalar(104.00698793, 116.66876762, 122.67891434));
src -= cv_data_mean;
// std::vector<cv::Mat> mat_vec;
//split(src, mat_vec);
img = src;
std::cout<<"finished resize image:"<<file_name<<std::endl;
return Status::OK();

} // Reads a model graph definition from disk, and creates a session object you can use to run it. tensorflow::Status TF_LoadGraph(const std::string& graph_file_name, tensorflow::Session* session) { tensorflow::GraphDef graph_def; tensorflow::Status load_graph_status = tensorflow::ReadBinaryProto(tensorflow::Env::Default(), graph_file_name, &graph_def); if (!load_graph_status.ok()) { return tensorflow::errors::NotFound("Failed to load compute graph at '", graph_file_name, "'"); } tensorflow::Status status = NewSession(tensorflow::SessionOptions(), &session); if (!status.ok()) { std::cerr << status.ToString() << std::endl; //return 1; } else { std::cout << "Session created successfully" << std::endl; }
//debug for (int i = 0; i < graph_def.node_size(); ++i) { auto node = graph_def.node(i); //std::cout<< " ***name:" << node.name() << ";op:" << node.op() << std::endl; }

return session->Create(graph_def);

} bool TF_init(const std::string& graph_file_name, tensorflow::Session* tf_session) { int argc = 0; tensorflow::port::InitMain(NULL, &argc, NULL);

tensorflow::Status status = TF_LoadGraph(graph_file_name, tf_session);
if (!status.ok()) {
    std::cerr << "TF_LoadGraph ERROR: " << status.error_message() << std::endl;
    return false;
}
return true;

}

int main(int argc, char* argv[]) {

//string graph_file_name = "./nsfw_model/resnet_50_1by2_nsfw.pb";
tensorflow::Session *tf_session;

std::string graph_file_name(argv[1]) ;
bool  status = TF_init(graph_file_name, tf_session);
if (!status)
{
    std::cerr << "TF_init ERROR" << std::endl;
    return -1;
}

cv::Mat cvIm ;
std::string image_path(argv[2]);
if ( !YahooImageLoader(image_path, cvIm).ok() )
{
    LOG(ERROR) << "Load image";
    return -1;
}
tensorflow::TensorShape image_shape = tensorflow::TensorShape{1, cvIm.rows, cvIm.cols, cvIm.channels()};
std::cout << "Input TensorShape ["
          << image_shape.dim_size(0) << ", "
          << image_shape.dim_size(1) << ", "
          << image_shape.dim_size(2) << ", "
          << image_shape.dim_size(3) << "]" << std::endl;

tensorflow::Tensor input = tensorflow::Tensor(tensorflow::DT_FLOAT, image_shape) ;
// copy data from OpenCv to TensorFlow Tensor
//std::copy_n((char*) image_float_data, image_shape.num_elements() * sizeof(float),
//               const_cast<char*>(input.tensor_data().data()));
std::vector<cv::Mat> mat_vec;
split(cvIm, mat_vec);
char* dst_data =const_cast<char*> (input.tensor_data().data());
float* src_data;
for (int k = 0; k < mat_vec.size(); ++k)
{
     for (int y = 0; y<mat_vec[k].rows; y++)
     {
         src_data = mat_vec[k].ptr<float>(y);
         memcpy(dst_data, src_data, sizeof(float)*mat_vec[k].cols);
         dst_data += mat_vec[k].cols*sizeof(float);
     }
}

string input_layer = "data:0";
string output_layer = "prob:0";

std::vector<std::pair<string, Tensor> > input_tname;
std::pair<string,Tensor> input0(input_layer, input);
input_tname.push_back(input0);

std::vector<string> output_tname;
std::vector<Tensor> output_tensor;

output_tname.push_back(output_layer);

std::vector<string> output_node;

std::cout<<"start classify image:"<<image_path<<std::endl;

tensorflow::Status run_status = tf_session->Run(input_tname,output_tname,output_node,&output_tensor);  

if (!run_status.ok())
{
    LOG(ERROR) << "Running model failed";
    return -1;
}
  // here deal the output which included the scores of sfw and nsfw
  tf_session->Close();
  return 0;

} `

mdietrichstein commented 6 years ago

Sorry I don't have a lot of experience with the C++ tensorflow api.