Ask Your Question
0

OpenCV Neural Networks

asked 2013-12-29 16:53:38 -0600

sploid gravatar image

Hello

I have simple code:

float line0[] = { 1., 0.66666669, 0.66666669, 0.66666669, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.66666669, 0.66666669, 1, 1, 0.66666669, 0.66666669, 0.33333334, 0.33333334, 0.33333334, 0, 0, 0, 0.33333334, 0.33333334, 0.66666669, 0.66666669, 1, 0.66666669, 0.33333334, 0.33333334, 0, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.66666669, 0.66666669 };

float line1[] = { 0.66666669, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.66666669, 0.33333334, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0.33333334, 0.66666669, 0.33333334, 0., 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334 };

float line2[] = { 1., 1., 1., 1., 0.66666669, 0.66666669, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.66666669, 1., 1., 1., 1., 1., 0.66666669, 0.66666669, 0.33333334, 0.33333334,0, 0.33333334, 0.33333334, 0.66666669, 1., 1., 1., 1., 0.66666669, 0.66666669, 0.33333334, 0.33333334, 0, 0.33333334, 0.33333334, 0.66666669, 0.66666669, 1., 1. };

float line3[] = { 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0.33333334, 0., 0., 0.33333334 };

void fill( Mat& mat, int row, float* data, int size ) { for ( int nn = 0; nn < size; ++nn ) { mat.at< float >( row, nn ) = data[ nn ]; } }

void fill2( Mat & mat, int row, float val1, float val2 ) { mat.at< float >( row, 0 ) = val1; mat.at< float >( row, 1 ) = val2; }

int main( int argc, char** argv ) { Mat layer_sizes( 1, 3, CV_32SC1 ); assert( sizeof(line0) == sizeof(line1) && sizeof(line1) == sizeof(line2) && sizeof(line2) == sizeof(line3)); const int el_count = sizeof( line0 ) / sizeof( line0[ 0 ] ); layer_sizes.at<int>( 0 ) = el_count; layer_sizes.at<int>( 1 ) = el_count * 2; layer_sizes.at<int>( 2 ) = 2;

Mat input_mat( 4, el_count, CV_32FC1);
fill( input_mat, 0, line0, el_count );
fill( input_mat, 1, line1, el_count );
fill( input_mat, 2, line2, el_count );
fill( input_mat, 3, line3, el_count );

Mat output_mat( 4, 2, CV_32FC1);
fill2( output_mat, 0, 0., 1. );
fill2( output_mat, 1, 1., 0. );
fill2( output_mat, 2, 0., 1. );
fill2( output_mat, 3, 1., 0. );

Mat weights( 1, 4, CV_32FC1, Scalar::all(1) );

CvANN_MLP mlp( layer_sizes );
mlp.train( input_mat, output_mat, weights );
Mat pred_out;
Mat test_sample( 1, el_count, CV_32FC1 );

fill( test_sample, 0, line0, el_count );
mlp.predict( test_sample, pred_out );
cout << pred_out << endl;

fill( test_sample, 0, line1, el_count );
mlp.predict( test_sample, pred_out );
cout << pred_out << endl;

fill( test_sample, 0, line2, el_count );
mlp.predict( test_sample, pred_out );
cout << pred_out << endl;

fill( test_sample, 0, line3, el_count );
mlp.predict( test_sample, pred_out );
cout << pred_out << endl;

int t = 0;

}

At result I get: [1.4031053 ... (more)

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
3

answered 2014-01-02 08:28:50 -0600

Nghia gravatar image

updated 2014-01-03 02:14:11 -0600

The documentation for the neural network class needs some serious updating. For starter, it does not support a normal sigmoid activation function, that is output between [0,1]. Instead it supports the tanh function, which outputs between [-1,1], so your output matrix should be [-1,1] as well. But even then the output by predict() isn't capped between [-1,1] because it applies 1.7159tanh(2/3*x), a popular modification to avoid numerical saturation. So your output is really capped between [-1.7159, 1.7159], which can be VERY confusing if you're new.

Putting all that aside, you just have to binarise your output to get the desired results. For example:

  • [1.4031053, 0.99364734], max at class 0 so ==> [1,0] (classified wrong)
  • [1.0640485, -0.40310526], max at class 0 so ==> [1,0]
  • [-0.40303019,1.4031053], max at class 1 so ==> [0,1]
  • [0.99389786, -0.40310526], max at class 0 so ==> [1,0]
edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-12-29 16:53:38 -0600

Seen: 525 times

Last updated: Jan 03 '14