leovandriel / caffe2_cpp_tutorial

C++ transcripts of the Caffe2 Python tutorials and other C++ example code
BSD 2-Clause "Simplified" License
431 stars 94 forks source link

caffe2 c++ can't load shufflenet pb which is ok in caffe2 python version #84

Open cswwp opened 5 years ago

cswwp commented 5 years ago

I generate pb with caffe2 python api, which is ok when test, but i can't load model in c++ caffe2, plz help me, my load code as follows `namespace caffe2 {

void run() { std::cout << std::endl; std::cout << "## Caffe2 Loading Pre-Trained Models Tutorial ##" << std::endl; std::cout << "https://caffe2.ai/docs/zoo.html" << std::endl; std::cout << "https://caffe2.ai/docs/tutorial-loading-pre-trained-models.html" << std::endl; std::cout << "https://caffe2.ai/docs/tutorial-image-pre-processing.html" << std::endl; std::cout << std::endl;

if (!std::ifstream(FLAGS_init_net).good() || !std::ifstream(FLAGS_predict_net).good()) { std::cerr << "error: Squeezenet model file missing: " << (std::ifstream(FLAGS_init_net).good() ? FLAGS_predict_net : FLAGS_init_net) << std::endl; std::cerr << "Make sure to first run ./script/download_resource.sh" << std::endl; return; }

if (!std::ifstream(FLAGS_file).good()) { std::cerr << "error: Image file missing: " << FLAGS_file << std::endl; return; }

if (!std::ifstream(FLAGS_classes).good()) { std::cerr << "error: Classes file invalid: " << FLAGS_classes << std::endl; return; }

std::cout << "init-net: " << FLAGS_init_net << std::endl; std::cout << "predict-net: " << FLAGS_predict_net << std::endl; std::cout << "file: " << FLAGS_file << std::endl; std::cout << "size: " << FLAGS_size << std::endl;

std::cout << std::endl;

// >>> img = // skimage.img_as_float(skimage.io.imread(IMAGE_LOCATION)).astype(np.float32) auto image = cv::imread(FLAGS_file); // CV_8UC3 std::cout << "image size: " << image.size() << std::endl;

// scale image to fit cv::Size scale(std::max(FLAGS_size image.cols / image.rows, FLAGS_size), std::max(FLAGS_size, FLAGS_size image.rows / image.cols)); cv::resize(image, image, scale); std::cout << "scaled size: " << image.size() << std::endl;

// crop image to fit cv::Rect crop((image.cols - FLAGS_size) / 2, (image.rows - FLAGS_size) / 2, FLAGS_size, FLAGS_size); image = image(crop); std::cout << "cropped size: " << image.size() << std::endl;

// convert to float, normalize to mean 128 image.convertTo(image, CV_32FC3, 1.0, -128); std::cout << "value range: (" << std::min_element((float )image.datastart, (float )image.dataend) << ", " << std::max_element((float )image.datastart, (float )image.dataend) << ")" << std::endl;

// convert NHWC to NCHW vector channels(3); cv::split(image, channels); std::vector data; for (auto &c : channels) { data.insert(data.end(), (float )c.datastart, (float )c.dataend); } std::vector dims({1, image.channels(), image.rows, image.cols}); TensorCPU tensor(dims, data, NULL);

// Load Squeezenet model NetDef init_net, predict_net;

// >>> with open(path_to_INIT_NET) as f: CAFFE_ENFORCE(ReadProtoFromFile(FLAGS_init_net, &init_net)); std::cout <<">>>>>>>>>>>>>>>"<< std::endl; // >>> with open(path_to_PREDICT_NET) as f: CAFFE_ENFORCE(ReadProtoFromFile(FLAGS_predict_net, &predict_net)); std::cout <<">>>>>>>>>>>>>>>"<< std::endl; // >>> p = workspace.Predictor(init_net, predict_net) Workspace workspace("tmp"); CAFFE_ENFORCE(workspace.RunNetOnce(init_net));

auto input = workspace.CreateBlob("data")->GetMutable(); input->ResizeLike(tensor); input->ShareData(tensor); CAFFE_ENFORCE(workspace.RunNetOnce(predict_net)); std::cout <<">>>>>>>>>>>>>>>"<< std::endl;

// >>> results = p.run([img]) auto &output_name = predict_net.external_output(0); auto output = workspace.GetBlob(output_name)->Get();

// sort top results const auto &probs = output.data(); std::vector<std::pair<int, int>> pairs; for (auto i = 0; i < output.size(); i++) { if (probs[i] > 0.01) { pairs.push_back(std::make_pair(probs[i] * 100, i)); } }

std::sort(pairs.begin(), pairs.end());

std::cout << std::endl;

// read classes std::ifstream file(FLAGS_classes); std::string temp; std::vector classes; while (std::getline(file, temp)) { classes.push_back(temp); }

// show results std::cout << "output: " << std::endl; for (auto pair : pairs) { std::cout << " " << pair.first << "% '" << classes[pair.second] << "' (" << pair.second << ")" << std::endl; } }

} // namespace caffe2 `

the error is

terminate called after throwing an instance of 'caffe2::EnforceNotMet' what(): [enforce fail at operator.cc:42] blob != nullptr. op Conv: Encountered a non-existing input blob: 0

beniz commented 5 years ago

This is not exactly what you are looking for, but you'll find full C++ Caffe2 training + prediction, that works with squeezenet, here: https://github.com/jolibrain/deepdetect/blob/master/src/backends/caffe2/caffe2lib.cc#L782 and elsewhere in the directory https://github.com/jolibrain/deepdetect/tree/master/src/backends/caffe2

rilesdg3 commented 5 years ago

"Encountered a non-existing input blob: 0" this means that it is expecting Blob: 0 but it does not find that blob, either you have did not get/create it "workspace.GetBlob(), or workspace.CreateBlob()", or you did not mark it as "external_input" when you created the pb file in python.

In summary the program is expecting a blob:0 but does not find it.

hope this helps