Ask Your Question
0

Neural Networks with CVANN_MLP

asked 2013-10-02 13:30:43 -0600

sp_mic88 gravatar image

updated 2013-10-02 13:38:00 -0600

berak gravatar image

I am programming in C++ with Visual Studio 2012 and Opencv 2.4.6. I have a set of training images for which I have calculated the feature vectors. These feature vectors should become the input of my neural network, realized with the class CvANN_MLP. Every feature vector is composed of 60 attributes, 59 are the "inputs" of the neural network, and the last is the "output", that can be only 1 or 0. I have realized this neural network:

CvANN_MLP machineBrain;

double td[NUMERO_ESEMPI_TOTALE][60]; 

CvMat* trainData = cvCreateMat(NUMERO_ESEMPI_TOTALE, 59, CV_32FC1); 

CvMat* trainClasses = cvCreateMat(NUMERO_ESEMPI_TOTALE, 1, CV_32FC1); 

CvMat* sampleWts = cvCreateMat(NUMERO_ESEMPI_TOTALE, 1, CV_32FC1); 
//The matrix representation of our ANN. We'll have four layers.
CvMat* neuralLayers = cvCreateMat(4, 1, CV_32SC1);
CvMat trainData1, trainClasses1, neuralLayers1, sampleWts1;

cvGetRows(trainData, &trainData1, 0, NUMERO_ESEMPI_TOTALE);
cvGetRows(trainClasses, &trainClasses1, 0, NUMERO_ESEMPI_TOTALE);
cvGetRows(trainClasses, &trainClasses1, 0, NUMERO_ESEMPI_TOTALE);
cvGetRows(sampleWts, &sampleWts1, 0, NUMERO_ESEMPI_TOTALE);
cvGetRows(neuralLayers, &neuralLayers1, 0, 4);



cvSet1D(&neuralLayers1, 0, cvScalar(59));
cvSet1D(&neuralLayers1, 1, cvScalar(3));
cvSet1D(&neuralLayers1, 2, cvScalar(3));
cvSet1D(&neuralLayers1, 3, cvScalar(1));



for(int i=0;i<NUMERO_ESEMPI_TOTALE;i++){
    for(int j=0;j<59;j++){
        td[i][j] = featureVect[i][j];
    }
    if(i<45){
        td[i][59] = 0; //è una bocca!
    }else{
        td[i][59] = 1; //non è una bocca!
    }
}

//Mettiamo insieme i training data
for (int i=0; i<NUMERO_ESEMPI_TOTALE; i++){
    //I 59 input 
    for(int j=0;j<59;j++){
        cvSetReal2D(&trainData1, i, 0, td[i][j]);
    }
    //Output
    cvSet1D(&trainClasses1, i, cvScalar(td[i][59]));
    //I pesi (vengono tutti settati a 1)
    cvSet1D(&sampleWts1, i, cvScalar(1));
}


machineBrain.create(neuralLayers);
cout<<"Rete creata"<<endl;

//Train it with our data.
machineBrain.train(trainData,trainClasses,sampleWts,0,CvANN_MLP_TrainParams(cvTermCriteria(CV_TERMCRIT_ITER+CV_TERMCRIT_EPS,100000,/*1.0*/0.01/*riprovare 0.01*/),CvANN_MLP_TrainParams::BACKPROP,0.001,0.05));
cout<<"Rete addestrata"<<endl;

 Mat pred(num_test_sample, 1, CV_32FC1);
Mat pred1(num_test_sample, 1, CV_32FC1);
for(int i=0;i<NUMERO_ESEMPI_TEST; i++){
    float _sample[59];
    CvMat sample = cvMat(1, 59, CV_32FC1, _sample);
    float _predout[1];
    CvMat predout = cvMat(1, 1, CV_32FC1, _predout);
    for(int j=0;j<59;j++){
        sample.data.fl[j] = featureVectTest[i][j];
    }
    machineBrain.predict(&sample, &predout);
    cout<<endl<<predout.data.fl[i]<<endl;//risultato predizione!
    pred.at<float>(i,0)=predout.data.fl[i];
    pred1.at<float>(i,0)=predout.data.fl[i];
    file<<"Value Image "<<i<<": "<<predout.data.fl[i]<<"\n";
}

The values that are returned are of this type:

 Value Image 0: 0.475639
 Value Image 1: 0
 Value Image 2: 4.2039e-044
 Value Image 3: 1.4013e-045
 Value Image 4: -7.88636e-016
 Value Image 5: 1.31722e-043
 Value Image 6: 4.2039e-044
 Value Image 7: 1.4013e-045
 Value Image 8: 0.0154511
 Value Image 9: 0.00100189
 Value Image 10: 0.00161414
 Value Image 11: 0.0449422
 Value Image 12: 7.5433
 Value Image 13: 65.8052
 Value Image 14: 24.301
 Value Image 15: 19.7311
 Value Image 16: 0.985553
 Value Image 17: 0.965309
 Value Image 18: 0.971295

So I haven't results of 0 ... (more)

edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted
1

answered 2013-10-03 05:25:45 -0600

Nghia gravatar image

By default CvANN_MLP uses a CvANN_MLP::SIGMOID_SYM activation function (aka tanh). This means it expects output values to range between [-1,1] instead of [0,1]. So just transform your training output. For some weird reason CvANN_MLP does not support a standard sigmoid function, where the output range is between [0,1].

Also, you might be accessing the wrong matrix elements for the predicted value (based on the fact you got values over 1). I think it should be predout.data.fl[0], not predout.data.fl[i] (predout is a 1x1 matrix).

edit flag offensive delete link more

Comments

Yes, it has to be predout.data.fl[0]. But now, all the values are equal. Why? What's wrong in the code?

sp_mic88 gravatar imagesp_mic88 ( 2013-10-03 11:06:54 -0600 )edit

Did you change the range to [-1,1] ?

Nghia gravatar imageNghia ( 2013-10-05 02:37:01 -0600 )edit

Yes, but it gives me the same results for every sample.

sp_mic88 gravatar imagesp_mic88 ( 2013-10-05 04:30:33 -0600 )edit

As a sanity check, try changing your network to 2 layers (input/output) to eliminate possible training error due to two hidden layers. And also verify your feature vector for the different samples are indeed different.

Nghia gravatar imageNghia ( 2013-10-05 20:38:34 -0600 )edit

I tried to change the entire set of training images on which I have calculated the feature vector. I also changed the network so that it is formed of only two levels (input / output). Even in this case the network does not predict, returns the same value for each feature vector of test.

sp_mic88 gravatar imagesp_mic88 ( 2013-10-06 02:40:13 -0600 )edit

Another check, print the return value from machineBrain.train(....). It is the number of iterations taken to train the network. Also, what is the constant predicted value you keep getting?

Nghia gravatar imageNghia ( 2013-10-06 02:59:29 -0600 )edit

Ok, the number of iterations is: 2 and the predicted value is: -1.17204 with exactly the parameter's values of the code above (it should be wrong because I should have values in the range [-1,1]). The classes of training are -1 and 1 and the layers of the net are two, one of 59 inputs and one of 1 output.

sp_mic88 gravatar imagesp_mic88 ( 2013-10-06 03:12:50 -0600 )edit

Seems like your training is busted. I would try the default training parameters, by removing CvANN_MLP_TrainParams(...), and setting the parameter where sampleWts is to NULL, to simplify things.

Nghia gravatar imageNghia ( 2013-10-06 03:28:16 -0600 )edit

The problem doesn't change. Now, I'll try to create the network in a new project. Anyway, thanks for all this help!

sp_mic88 gravatar imagesp_mic88 ( 2013-10-06 03:40:28 -0600 )edit

I am facing similar problem. did you get any solution?

hardik gravatar imagehardik ( 2013-10-22 03:54:40 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2013-10-02 13:30:43 -0600

Seen: 1,674 times

Last updated: Oct 03 '13