Ask Your Question
0

OpenCV Error When Train ANN_MLP

asked 2016-04-24 07:25:28 -0600

aligoglos gravatar image

i want train neural network to classify two type of images but when train network this error occurred :

OpenCV Error: Bad argument (output training data should be a floating-point matrix with the number of rows equal to the number of training samples and the number of columns equal to the size of last (output) layer) in cv::ml::ANN_MLPImpl::prepare_to_train, file C:\buildslave64\win64_amdocl\master_PackSlave-win64-vc14-shared\opencv\modules\ml\src\ann_mlp.cpp, line 675

my code :

#include "opencv2\core.hpp"#include "opencv2\imgproc.hpp"#include "opencv2\imgcodecs.hpp"#include "opencv2\highgui.hpp"#include "opencv2\ml.hpp"#include <string>#include "lbp.h"
using namespace cv;
using namespace cv::ml;
void LoadTrainingData();

Mat Data; Mat Lables; //const int numberOfClass1 = 2384; //const int numberOfClass2 = 2462; const int numberOfClass1 = 23; const int numberOfClass2 = 24; int Class1 = 1; int Class2 = -1; const int imageDimention = 22;

std::string NumberToString(size_t Number) { std::stringstream ss; ss << Number; return ss.str(); }

void main() { LoadTrainingData(); Ptr<ann_mlp> annClassifier; annClassifier = ANN_MLP::create(); annClassifier->setActivationFunction(ANN_MLP::ActivationFunctions::SIGMOID_SYM); Mat layers(1, 3, CV_32F); layers.at<float>(0) = Data.cols; layers.at<float>(1) = 100; layers.at<float>(2) = 2; annClassifier->setLayerSizes(layers); annClassifier->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-6)); annClassifier->setTrainMethod(ANN_MLP::TrainingMethods::BACKPROP); bool trained = annClassifier->train(Data,ROW_SAMPLE,Lables); if (trained) annClassifier->save("Ann_sigmoid_eye"); }

void LoadTrainingData() { Data = Mat(numberOfClass1 + numberOfClass2, imageDimention*imageDimention, CV_32FC1); Lables = Mat(numberOfClass1 + numberOfClass2,1 , CV_32SC1); // load openEye Mat img; Mat lbpImg; Mat row; std::string path; for (size_t i = 1; i <= numberOfClass2; i++) { path = "class1 (" + NumberToString(i) + ").jpg"; img = imread(path); if (img.channels() > 1) cvtColor(img, img, CV_BGR2GRAY); lbp::ELBP(img,lbpImg, 1, 16);
row = lbpImg.reshape(0, 1); row.convertTo(row, CV_32FC1); Data.push_back(row); Lables.push_back(Class1); } for (size_t i = 1; i <= numberOfClass1; i++) { path ="class2 (" + NumberToString(i) + ").jpg"; img = imread(path); if (img.channels() > 1) cvtColor(img, img, CV_BGR2GRAY); lbp::ELBP(img,lbpImg, 1, 16); row = lbpImg.reshape(0, 1); row.convertTo(row, CV_32FC1); Data.push_back(row); Lables.push_back(Class2); } }

i don't why this happen ! please help me,thanks.

edit retag flag offensive close merge delete

Comments

looking back at this - simply converting LBP features to float will make a horribly bad feature.

(you're expected to either use patched histograms(see face recognition), or some embedding , that works better with L2 distance / SGD)

berak gravatar imageberak ( 2017-04-08 02:36:51 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2016-04-24 08:18:27 -0600

berak gravatar image

updated 2016-04-24 10:32:08 -0600

the train responses for an ann differ a bit from the usual opencv ml approach.

if you have 2 output neurons in your ann, you need 2 output neurons for each training feature too, not a single "class label" (like with e.g. an SVM).

it should look like this:

[train_data]                [train_responses]

lbpfeature1                 -1   1     // class A
lbpfeature2                 -1   1     // class A
lbpfeature3                 1   -1     // class B
lbpfeature4                 1   -1     // class B

so, the responses must have num_features rows X 2 cols.

one way (there are endless..) would be:

    // leave Labels empty (btw, your original code seems to leave the 1st element empty)
    // Lables = Mat(numberOfClass1 + numberOfClass2,1 , CV_32SC1);

    // instead of 
    //Lables.push_back(Class1);
    Lables.push_back(1.0f);
    Lables.push_back(-1.0f);

    // and instead of 
    //Lables.push_back(Class2);
    Lables.push_back(-1.0f);
    Lables.push_back(1.0f);

    // then, before training, reshape to N x 2:
    Labels = Labels.reshape(1, Labels.rows / 2);
edit flag offensive delete link more

Comments

i apply this changes but this time this exception occurred : OpenCV Error: Assertion failed ((layout == ROW_SAMPLE && responses.rows == nsamples) || (layout == COL_SAMPLE && responses.cols == nsamples)) in cv::ml::TrainDataImpl::setData, file C:\buildslave64\win64_amdocl\master_PackSlave-win64-vc14-shared\opencv\modules\ml\src\data.cpp, line 290

aligoglos gravatar imagealigoglos ( 2016-04-24 10:03:35 -0600 )edit

i comment this line : //Data = Mat(numberOfCloseEye + numberOfOpenEye, imageDimention*imageDimention, CV_32FC1);

but previous exception again occurred.

aligoglos gravatar imagealigoglos ( 2016-04-24 10:15:50 -0600 )edit

ah, sorry, it needs float labels, see edit

berak gravatar imageberak ( 2016-04-24 10:48:09 -0600 )edit

this fixed by :

Data.convertTo(Data, CV_32FC1); Lables.convertTo(Lables, CV_32FC1);

aligoglos gravatar imagealigoglos ( 2016-04-24 10:50:27 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-04-24 07:25:28 -0600

Seen: 1,976 times

Last updated: Apr 24 '16