OpenCV DNN predicts same class for every input

asked 2019-07-09 23:56:52 -0600

updated 2019-07-10 00:04:12 -0600

berak gravatar image

Version: Opencv 3.4.1 software: Visual studio 17 , Windows 10

So I trained a model on tensorflow, and it has very good accuracy (98% on test set). Now I want to export it to opencv in C++. I froze the graph and optimized using native tensorflow files as explained here in this link.

The problem is, the model predicts only one class out of two classes (the second class from labels text file). Even if I give an input of black image, it predicts that class with 98% confidence. I'm completely confused as to why this is happening.

Am I getting the wrong output node from graph? Or is my network itself wrong? Having trouble visualizing tensorboard as well. Any inputs are appreciated!

The link to optimized .pb file I'm using is - https://drive.google.com/file/d/1mL-F...

I use this C++ code for inference

 // This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.

// Copyright (C) 2016, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.

/*
Sample of using OpenCV dnn module with Tensorflow Inception model.
*/

#include <stdafx.h>
using namespace cv;
using namespace cv::dnn;

#include <fstream>
#include <iostream>
#include <cstdlib>
using namespace std;

const String keys =
"{help h    || Sample app for loading Inception TensorFlow model. "
"The model and class names list can be downloaded here: "
"https://storage.googleapis.com/download.tensorflow.org/models/inception5h.zip }"
"{model m   |tensorflow_inception_graph.pb| path to TensorFlow .pb model file }"
"{image i   || path to image file }"
"{i_blob    | input | input blob name) }"
"{o_blob    | softmax2 | output blob name) }"
"{c_names c | imagenet_comp_graph_label_strings.txt | path to file with classnames for class id }"
"{result r  || path to save output blob (optional, binary format, NCHW order) }"
;

void getMaxClass(const Mat &probBlob, int *classId, double *classProb);
std::vector<String> readClassNames(const char *filename);

int main(int argc, char **argv)
{
    cv::CommandLineParser parser(argc, argv, keys);

    if (parser.has("help"))
    {
        parser.printMessage();
        return 0;
    }

    String modelFile = "frozentensorflowModel.pb";
    String imageFile = "000152.jpg";
    String inBlobName = "input";
    String outBlobName = "cross_";
    if (!parser.check())
    {
        parser.printErrors();
        return 0;
    }

    String classNamesFile = "imagenet_comp_graph_label_strings.txt";
    String resultFile = "output.txt";

    //! [Initialize network]
    dnn::Net net = readNetFromTensorflow(modelFile);
    //! [Initialize network]

    if (net.empty())
    {
        std::cerr << "Can't load network by using the mode file: " << std::endl;
        std::cerr << modelFile << std::endl;
        exit(-1);
    }

    //! [Prepare blob]
    Mat img = imread(imageFile);
    if (img.empty())
    {
        std::cerr << "Can't read image from the file: " << imageFile << std::endl;
        exit(-1);
    }

    Mat inputBlob = blobFromImage(img, 1.0f, Size(160, 160), Scalar(), true, false);   //Convert Mat to batch of images
    //! [Prepare blob]
    //inputBlob -= 117.0;
    //! [Set input blob]
    net.setInput(inputBlob, inBlobName);        //set the network input
    //! [Set input blob]

    cv::TickMeter tm;
    tm.start();

    //! [Make forward pass]
    Mat result = net.forward(outBlobName);                          //compute output
    //! [Make forward pass]

    tm.stop();

    if (!resultFile.empty()) {
        CV_Assert(result.isContinuous());

        ofstream ...
(more)
edit retag flag offensive close merge delete