Ask Your Question
2

ANN_MLP bad argument error

asked 2017-05-30 15:42:43 -0600

Tomna gravatar image

updated 2017-08-01 19:20:57 -0600

i am going straigt to the point i am doing a neural network and after setting the ANN i get this error saying that

OpenCV Error: Bad argument (input 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 0-th (input) layer) in prepare_to_train, file /home/tomna/Desktop/opencv-3.1.0/modules/ml/src/ann_mlp.cpp, line 668 Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: /home/tomna/Desktop/opencv-3.1.0/modules/ml/src/ann_mlp.cpp:668: error: (-5) input 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 0-th (input) layer in function prepare_to_train ]

but i dont get why cuz the numbers seems to be okay or what i think they are soo here is the code

void run() throws IOException {
        String PATH_numbers = "/home/tomna/NetBeansProjects/Parking-tracking-system/src/mainclass/chdataset/Numb";
        Mat img = Imgcodecs.imread("/home/tomna/NetBeansProjects/Parking-tracking-system/src/mainclass/characters/4.jpg");
        Mat trainingData = new Mat();
        Mat trainingLabels = new Mat();

        //// here i prepare the neural network//////////
        ANN_MLP knn = ANN_MLP.create();
        TermCriteria s = new TermCriteria(TermCriteria.MAX_ITER + TermCriteria.EPS, 100, 0.00001);

        knn.setTrainMethod(ANN_MLP.BACKPROP);
        knn.setBackpropWeightScale(0.05f);
        knn.setBackpropMomentumScale(0.05f);
        knn.setTermCriteria(s);

     " ///////////here i identify that 3 layer 1 input 5 hidden 1 output   ////not sure here how to put the input since i have only 45 images for training so need help here and i think 5 is also a not good example for hidden so yaa as well here "
        Mat layers = new Mat(3,1,CvType.CV_32SC1);
        layers.row(0).setTo(new Scalar(1));
        layers.row(1).setTo(new Scalar(5));
        layers.row(2).setTo(new Scalar(1));

        knn.setLayerSizes(layers);


        int i = 0;
        for (File file : new File(PATH_numbers).listFiles()) {
            Mat image = getMat(file.getAbsolutePath());

            Imgproc.GaussianBlur(image, image, new Size(5, 5), 0);
            Core.addWeighted(image, 1.5, image, 0, 0, image);
            image.convertTo(image, CvType.CV_32F); // Convert to float
            Imgproc.resize(image, image, new Size(60, 74));

            Mat imgresized = image.reshape(1, 1); // make continous
            trainingData.push_back(imgresized);

            int nImagesPerClass = 5;
            int id = 1 + (i / nImagesPerClass);
            trainingLabels.push_back(new Mat(1, 1, CvType.CV_32SC1, new Scalar(id)));
            i++;
            System.out.println(trainingData);
        }

        Mat response = new Mat();
        Mat tmp;
        tmp = trainingLabels.reshape(1, 1); // make continuous
        tmp.convertTo(response, CvType.CV_32F); // Convert to float
        System.out.println(trainingData.cols());
        knn.train(trainingData, Ml.ROW_SAMPLE, response);  <<-- "error point here  when i output trainiData.rows=45 and   trainiData.rows.cols = 4440   so i guess the bad argument is for the cols ? " 

        Mat test = new Mat();
        Imgproc.cvtColor(img, test, Imgproc.COLOR_RGB2GRAY);
        Imgproc.GaussianBlur(test, test, new Size(5, 5), 0);
        Core.addWeighted(test, 0.5, test, 0, 0, test);
        Imgproc.resize(test, test, new Size(60, 74));
        test.convertTo(test, CvType.CV_32F);
        Mat results = new Mat();
        int label ...
(more)
edit retag flag offensive close merge delete

Comments

1

@berak man sorry for tagging you in every question i post but man you seem like the only one who understand image processing here once again sorry and hope you help here :)

Tomna gravatar imageTomna ( 2017-05-30 15:44:56 -0600 )edit
1

take a break, and read a bit

no , seriously, at least the 1st module.

berak gravatar imageberak ( 2017-05-30 23:26:05 -0600 )edit
1

@berak, nice complement, but @Tomna, it seems there are others around that know computer vision also xD

StevenPuttemans gravatar imageStevenPuttemans ( 2017-05-31 04:00:12 -0600 )edit

@berak i just updated the the question check the UPDATE and i really wanna know how close am i from fininshing this and thank you

Tomna gravatar imageTomna ( 2017-05-31 12:50:04 -0600 )edit

2 answers

Sort by ยป oldest newest most voted
1

answered 2017-05-31 05:12:26 -0600

berak gravatar image

updated 2017-05-31 05:14:56 -0600

your network will need one input per feature (so, 60 x 74 = 4440)

you also need 1 output per class, so 5.

the hidden weights is the place, where the information about your training data is stored, so smaller will yield less accuracy, larger will take more time (and memory).

so, [4440, 2000, 5] , the network, so far ...

then an ann uses "one-hot-encoded" responses (the last network layer), instead of a single label number, like with knn, you need a row of n classes, and set a 1 where your class id is, and the others to 0, like:

[0,0,0,1,0] // 3
[1,0,0,0,0] // 0

from java, maybe:

int numImages = 10;//example
int numImgPerClass = 5;
int numClasses = 5;
Mat labels = new Mat(numImages, numClasses, CV_32F, Scalar.all(0));

int id=2;//example
labels.submat(0,5,id,id+1).setTo(Scalar(1));

id=0;//example
labels.submat(5,5+numImgPerClass,id,id+1).setTo(Scalar(1));

labels.dump()


[0, 0, 1, 0, 0; // image1
 0, 0, 1, 0, 0; // image2
 0, 0, 1, 0, 0; // ...
 0, 0, 1, 0, 0;
 0, 0, 1, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0]
edit flag offensive delete link more

Comments

@berak ok soo i understood the second part the one-hot encoded but the first part setting the network layers is what i dont understand

according to your explanation this is how the network will look like ?

 Mat layers = new Mat(3,1,CvType.CV_32SC1);
    layers.row(0).setTo(new Scalar(4440));
    layers.row(1).setTo(new Scalar(2000));
    layers.row(2).setTo(new Scalar(5));
Tomna gravatar imageTomna ( 2017-05-31 06:42:44 -0600 )edit

^^ yes, exactly.

berak gravatar imageberak ( 2017-05-31 07:38:29 -0600 )edit

@berak mm ok good and now there is a problem with part two i cant seem to update the parameters of submat

    for (File file : new File(PATH_numbers).listFiles()) {
                 int numImgPerClass = 5;
    int rowstart = 0;

        trainingLabels.submat(rowstart, numImgPerClass, index, index + 1).setTo(new Scalar(1));
        index++;
        rowstart += 5;
        numImgPerClass += 5;
}
System.out.println(trainingLabels.dump());

[1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;]  it out puts the 45 all "0"
Tomna gravatar imageTomna ( 2017-05-31 08:02:29 -0600 )edit
1

you have to put int rowstart=0;outside the loop (else you overwrite it in any iteration)

berak gravatar imageberak ( 2017-06-01 00:51:33 -0600 )edit

@berak this outputs an error

OpenCV Error: Assertion failed (0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows) in Mat, file /home/tomna/Desktop/opencv-3.1.0/modules/core/src/matrix.cpp, line 469
Exception in thread "main" CvException [org.opencv.core.CvException: cv::Exception: /home/tomna/Desktop/opencv-3.1.0/modules/core/src/matrix.cpp:469: error: (-215) 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows in function Mat
]
Tomna gravatar imageTomna ( 2017-06-01 04:50:08 -0600 )edit

what i did in a loop outside and this output just fine

int index = 0;
int numImgPerClass = 5;
int rowstart = 0;
for (int i = 0; i < 9; i++) {
    trainingLabels.submat(rowstart, numImgPerClass, i, i + 1).setTo(new Scalar(1));
    rowstart += 5;
    numImgPerClass += 5;
}
Tomna gravatar imageTomna ( 2017-06-01 04:51:25 -0600 )edit

yea, you must not increase index per file (its a class id, you have less classes than files, so you're out of bounds)

berak gravatar imageberak ( 2017-06-01 04:57:56 -0600 )edit

@berak mm ok this means the code above is correct.. could you check the UPDATE cuz it outputs an error if i added a reshaper and convert to the output to the training labels but if i dont the output is 0

Tomna gravatar imageTomna ( 2017-06-01 05:10:01 -0600 )edit

@berak Sir, My question where would i found good documentation about ANN_MLP opencv 2 or 3. And book? I tired to search about this. I cannot found any proper documentation. Thank you very much for good explanation about labels. what is the range of predict. if fparam1 and fparam2 is 1, 1. And do you have any email?

alexcerry gravatar imagealexcerry ( 2017-06-01 23:51:20 -0600 )edit
0

answered 2017-05-31 08:49:18 -0600

Tomna gravatar image

updated 2017-05-31 08:50:51 -0600

@berak so there is something i just noticed if according to your code

Mat labels = new Mat(numImages, numClasses, CV_32F, Scalar.all(0)); Mat labels = new Mat( 45, 5 , CV_32F, Scalar.all(0)); <-- this means that

the output of the labels will be something like that

[1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 1, 0, 0, 0, 0;
 0, 1, 0, 0, 0;
 0, 1, 0, 0, 0;
 0, 1, 0, 0, 0;
 0, 1, 0, 0, 0;
 0, 1, 0, 0, 0;
 0, 0, 1, 0, 0;
 0, 0, 1, 0, 0;
 0, 0, 1, 0, 0;
 0, 0, 1, 0, 0;
 0, 0, 1, 0, 0;
 0, 0, 0, 1, 0;
 0, 0, 0, 1, 0;
 0, 0, 0, 1, 0;
 0, 0, 0, 1, 0;
 0, 0, 0, 1, 0;
 0, 0, 0, 0, 1;
 0, 0, 0, 0, 1;
 0, 0, 0, 0, 1;
 0, 0, 0, 0, 1;
 0, 0, 0, 0, 1;
 0, 0, 0, 0, 0;    <<--- it wont assign anymore 
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0;
 0, 0, 0, 0, 0]
edit flag offensive delete link more

Comments

@ StevenPuttemans any idea what to do?

Tomna gravatar imageTomna ( 2017-05-31 09:36:44 -0600 )edit

I am not sure why you do not get what to do. Simple make a row for each training sample, giving it the correct corresponding 1 hot encoding label? It seems you are missing the point and fixating to much on the actual code.

StevenPuttemans gravatar imageStevenPuttemans ( 2017-06-01 02:35:15 -0600 )edit

@StevenPuttemans i do understand that i should make a row for each training sample but what i dont understand is based on what the 1 will be placed at which column ? so far what i see is its index like 0 then index 0 will contain the 1

Tomna gravatar imageTomna ( 2017-06-01 04:49:21 -0600 )edit
1

Imagine you have 3 classes [car pedestrian dog] and then 3 samples of each class in a row, then your labels will be

[1 0 0; //car
 1 0 0; //car
 1 0 0; //car
 0 1 0; //pedestrian
 0 1 0; //pedestrian
 0 1 0; //pedestrian
 0 0 1; //dog
 0 0 1; //dog
 0 0 1] //dog
StevenPuttemans gravatar imageStevenPuttemans ( 2017-06-01 05:52:38 -0600 )edit

I do not think we can make it any clearer.

StevenPuttemans gravatar imageStevenPuttemans ( 2017-06-01 05:52:57 -0600 )edit

@StevenPuttemans i do understand how it works but the thing is i have 9 charachter and only 5 classess so my only solution is to increase the number of classes to 9 which i am not sure if correct since the layers output is 5

[1,0,0,0,0,0,0,0,0;  //image 1 
[1,0,0,0,0,0,0,0,0;  //image 1 
[1,0,0,0,0,0,0,0,0;  //image 1 
[0,1,0,0,0,0,0,0,0;  //image 2 
[0,1,0,0,0,0,0,0,0;  //image 2 
[0,1,0,0,0,0,0,0,0;  //image 2
Tomna gravatar imageTomna ( 2017-06-01 06:07:24 -0600 )edit

@Tomna you are not getting it, if you have 9 characters, then you should have 9 output classes, If not then you did something wrong

StevenPuttemans gravatar imageStevenPuttemans ( 2017-06-01 06:58:37 -0600 )edit

this means

  Mat layers = new Mat(3, 1, CvType.CV_32SC1);
    layers.row(0).setTo(new Scalar(4440));
    layers.row(1).setTo(new Scalar(2000));
    layers.row(2).setTo(new Scalar(9));  <---- here 

knn.setLayerSizes(layers);
trainingLabels = new Mat(45, 9, CvType.CV_32F, Scalar.all(0)); <----here 

int index = 0;
int numImgPerClass = 5;
int rowstart = 0;
for (int i = 0; i < 9; i++) {
    trainingLabels.submat(rowstart, numImgPerClass, i, i + 1).setTo(new Scalar(1));
    rowstart += 5;
    numImgPerClass += 5;
}
Tomna gravatar imageTomna ( 2017-06-01 07:04:15 -0600 )edit

@StevenPuttemans could you check the updated code and see if you can help me understand why i get a 0 as an output no matter what the user input image is ? i mean the trainig part and going down and thank you :)

Tomna gravatar imageTomna ( 2017-06-01 07:10:51 -0600 )edit

@Tomna it is looking more and more that we are making your code... I do not have the time for this... hope you understand this.

StevenPuttemans gravatar imageStevenPuttemans ( 2017-06-01 08:25:48 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-05-30 15:42:43 -0600

Seen: 1,638 times

Last updated: Jun 01 '17