OpenCV 3 Java - How to train neural network with TrainData

asked 2017-01-31 09:32:51 -0500

Sipho gravatar image

updated 2017-01-31 10:09:21 -0500

I was recently updating my Java OpenCV 2.4 code to OpenCV 3.2. I had some code to train an ANN_MLP. I found out that OpenCV 3.2 has a new class called TrainData and decided to use it. I think I may have a discovered a bug but figured I would ask here first.

I have a Mat of samples and a Mat of responses in the ROW_SAMPLE layout, that is each row is a sample. Here is the code I use to train the neural network:

// ann is my ANN_MLP
ann.train(samples, Ml.ROW_SAMPLE, responses);

This code runs with no errors and on testing the prediction is correct.

The following code however does not run but instead crashes java:

TrainData td = TrainData.create(samples, Ml.ROW_SAMPLE, responses);
ann.train(td);

The "samples" and "responses" Mats are the exact same ones used in the above code snippet. This code snippet throws the following error:

Exception in thread "main" java.lang.Exception: unknown exception
at org.opencv.ml.StatModel.train_2(Native Method)
at org.opencv.ml.StatModel.train(StatModel.java:97)

and then it shows the stack trace to ann.train(td)

Is there any way to find out what the "unknown exception" is? Is this a bug only present in the Java port? Maybe I am just doing something wrong but according to the documentation this is correct usage of TrainData. Maybe somebody else has run into this issue.

I don't feel there is any need to provide more code due to it working with the same Mats when not using TrainData but if I need to provide more code just let me know.

EDIT: I am pretty sure this is a bug now because I tried running the following code

    TrainData td = TrainData.create(samples, Ml.ROW_SAMPLE, responses);
    ann.train(td.getSamples(), Ml.ROW_SAMPLE, td.getResponses());

and it works just fine.

edit retag flag offensive close merge delete

Comments

1

there's a few cases, where you want to use TrainData, e.g. for reading data from csv files, or conveniently get randomly split train/testdata.

but in your case, i'd simply stick with the old method.

(no java here, so i cannot test, so not really an answer !)

berak gravatar imageberak ( 2017-01-31 10:05:36 -0500 )edit
1

@berak Yes I was planning on just sticking to the old method for now. However, using TrainData allows you to use calcError and, as you said, to randomly split the train/testdata which are really quite handy. Plus I found myself implementing all those functions anyways.

This isn't the first machine learning bug I have encountered in the Java port of OpenCV 3.2. It seems pretty unstable actually.

Sipho gravatar imageSipho ( 2017-01-31 10:12:40 -0500 )edit

but i have to admit, it pretty much looks like a bug.

any chance, you still have the temp files from building around ? the generated c++ / java code might be of interest in this case !

berak gravatar imageberak ( 2017-01-31 10:15:49 -0500 )edit
1

@berak Unfortunately no. I didn't build it myself. I just downloaded the pre-built .jar file. If that's what you mean.

Sipho gravatar imageSipho ( 2017-01-31 10:25:35 -0500 )edit
1

ah, ok, i see. (didn't even know, that the prebuild packages come with java wrappers)

no idea, how bold you feel, atm, but nothing will change, unless someone makes an issue here ;)

(maybe wait a bit, and see, if anybody else has an idea, but in the end .. someeone has to do it !)

berak gravatar imageberak ( 2017-01-31 10:35:46 -0500 )edit
2

@berak I'll give it a while. Don't want to embarrass myself :)

Sipho gravatar imageSipho ( 2017-01-31 10:57:26 -0500 )edit

Dear Sipho, I am completely new to OpenCv with Android + java. It would be of great help if you or anyone here can help me understand how do I interpret images as MAT so as to train my classifier.

My code is: strong text Mat originalMat = new Mat(); Bitmap bmp = BitmapFactory.decodeResource(getResources(), R.drawable.a); Utils.bitmapToMat(bmp,originalMat);

              NormalBayesClassifier classifier = NormalBayesClassifier.create();
                TrainData td = TrainData.create(originalMat, Ml.ROW_SAMPLE, originalMat);
                classifier.train(originalMat,Ml.ROW_SAMPLE,originalMat);

:

Ankit Verma gravatar imageAnkit Verma ( 2017-05-02 04:50:25 -0500 )edit

this is the error:

E/org.opencv.ml: ml::create_11() caught cv::Exception: /build/master_pack-android/opencv/modules/ml/src/data.cpp:259: error: (-215) samples.type() == CV_32F || samples.type() == CV_32S in function void cv::ml::TrainDataImpl::setData(cv::InputArray, int, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray, cv::InputArray)

Ankit Verma gravatar imageAnkit Verma ( 2017-05-02 04:50:45 -0500 )edit