Attention! This forum will be made read-only by Dec-20. Please migrate to https://forum.opencv.org. Most of existing active users should've received invitation by e-mail.
Ask Your Question
0

Logistic Regression on MNIST dataset

asked 2016-05-17 11:32:04 -0500

lino gravatar image

In this post you can find a very good tutorial on how to apply SVM classifier to MNIST dataset. I was wondering if I could use logistic regression instead of SVM classifier. So I searhed for Logistic regression in openCV, And I found that the syntax for both classifiers are almost identical. So I guessed that I could just comment out these parts:

    cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();
    svm->setType(cv::ml::SVM::C_SVC);
    svm->setKernel(cv::ml::SVM::POLY);//LINEAR, RBF, SIGMOID, POLY 
    svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));
    svm->setGamma(3); 
    svm->setDegree(3);
    svm->train( trainingMat , cv::ml::ROW_SAMPLE , labelsMat );

and replace it with:

    cv::Ptr<cv::ml::LogisticRegression> lr1 = cv::ml::LogisticRegression::create();
    lr1->setLearningRate(0.001);
    lr1->setIterations(10);
    lr1->setRegularization(cv::ml::LogisticRegression::REG_L2);
    lr1->setTrainMethod(cv::ml::LogisticRegression::BATCH);
    lr1->setMiniBatchSize(1);
    lr1->train( trainingMat, cv::ml::ROW_SAMPLE, labelsMat);

But first I got this error: OpenCV Error: Bad argument(data and labels must be a floating point matrix)

Then I changed

cv::Mat labelsMat(labels.size(), 1, CV_32S, labelsArray);

to:

cv::Mat labelsMat(labels.size(), 1, CV_32F, labelsArray);

And now I get this error: OpenCV Error: bad argument(data should have atleast two classes)

I have 10 classes (0,1,...,9) but I don't know why I get this error. My codes are almost identical with the ones in the mentioned tutorial.

edit retag flag offensive close merge delete

2 answers

Sort by ยป oldest newest most voted
2

answered 2016-05-17 12:08:38 -0500

berak gravatar image

updated 2016-05-17 12:36:49 -0500

what is your labelsArray ? (if it is an int[] or similar, you cannot simpy change the type flag)

i think, you need 2 steps:

cv::Mat labelsMat(labels.size(), 1, CV_32S, labelsArray); // assuming, labelsArray is int[]
labelsMat.convertTo(labelsMat, CV_32F); // proper float Mat now.
edit flag offensive delete link more
1

answered 2016-05-17 12:14:40 -0500

I think that the data should be categorical (also refered as one-hot-encoding) , ie for 2 classes: [1,0] instead of [0], then for mnist, it should be: [1,0,0,0,0,0,0,0,0,0] for class 0, [0,1,0,0,0,0,0,0,0,0] for class 1, etc.

You could find a small description here.

There is plenty of Python methods to do that, but none in OpenCV as far as I know it... But if you implement it, feel free to add a pull request for it (has well as a doc update in another pull request if that solve your issue!)

edit flag offensive delete link more

Comments

let me add, that this is true for ANN_MLP (but not for other opencv ml classes)

berak gravatar imageberak ( 2016-05-18 11:52:01 -0500 )edit
Login/Signup to Answer

Question Tools

1 follower

Stats

Asked: 2016-05-17 11:32:04 -0500

Seen: 322 times

Last updated: May 17 '16