0

I am trying to learn Cv_ANN_MLP by finding examples. This is what I come up with. I wanted to make a MultiLayer Perceptron to find solution for XOR Problem. After training of "mlp" of type CvANN_MLP, I want to save it to file "mlp.yaml". It is saving but when I load it to use, it doesn't work.

At the very end, there is a function "void mlp(__)". I tried commenting "mlp.load", trained it and saved it. Later I commented the "mlp.save" and "mlp.train" but it is not working.

Thank You!

Full Source code (using OpenCV 2.3.1 with Code::Blocks)

#include <iostream>
#include <math.h>
#include <string>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

void mlp(cv::Mat& trainingData, cv::Mat& trainingClasses, cv::Mat& testData, cv::Mat& testClasses);


float evaluate(cv::Mat& predicted, cv::Mat& actual) {
    assert(predicted.rows == actual.rows);
    int t = 0;
    int f = 0;
    for(int i = 0; i < actual.rows; i++) {
        float p = predicted.at<float>(i,0);
        float a = actual.at<float>(i,0);
        if((p >= 0.5 && a >= 0.5) || (p <= 0.5 &&  a <= 0.5)) {
            t++;
        } else {
            f++;
        }
    }
    cout<<endl<<"( "<<t<<" / "<<t+f<<")"<<endl;
    return (t * 1.0) / (t + f);
}


using namespace cv;

int main(int argc, char* argv)
{
    Mat trainingData(4, 2, CV_32FC1);
    Mat testData(4, 2, CV_32FC1);

    cv::Mat trainResult(trainingData.rows, 1, CV_32FC1);
    cv::Mat testResult(trainingData.rows, 1, CV_32FC1);


    trainingData.at<float>(0, 0) = 0;
    trainingData.at<float>(0, 1) = 0;
    trainResult.at<float>(0, 0) = 0;

    trainingData.at<float>(1, 0) = 0;
    trainingData.at<float>(1, 1) = 1;
    trainResult.at<float>(1, 0) = 1;

    trainingData.at<float>(2, 0) = 1;
    trainingData.at<float>(2, 1) = 0;
    trainResult.at<float>(2, 0) = 1;

    trainingData.at<float>(3, 0) = 1;
    trainingData.at<float>(3, 1) = 1;
    trainResult.at<float>(3, 0) = 0;


    cout<<"Training Data\n "<<trainingData<<"\n\n";
    cout<<"Training Result\n "<<trainResult<<"\n\n";

    testData.at<float>(0, 0) = 0;
    testData.at<float>(0, 1) = 0;
    testResult.at<float>(0, 0) = 0;

    testData.at<float>(1, 0) = 0;
    testData.at<float>(1, 1) = 1;
    testResult.at<float>(1, 0) = 1;

    testData.at<float>(2, 0) = 1;
    testData.at<float>(2, 1) = 0;
    testResult.at<float>(2, 0) = 1;

    testData.at<float>(3, 0) = 1;
    testData.at<float>(3, 1) = 1;
    testResult.at<float>(3, 0) = 0;

    cout<<"Test Data\n "<<testData<<"\n\n";
    cout<<"Test Result\n "<<testResult<<"\n\n";

    mlp(trainingData, trainResult, testData, testResult);

    return 0;
}

void mlp(cv::Mat& trainingData, cv::Mat& trainingClasses, cv::Mat& testData, cv::Mat& testClasses) {

    CvANN_MLP mlp;
    CvANN_MLP_TrainParams params;
    CvTermCriteria criteria;

    mlp.load("mlp.yaml");

    cv::Mat layers = cv::Mat(4, 1, CV_32SC1);


    layers.row(0) = cv::Scalar(2);
    layers.row(1) = cv::Scalar(2);
    layers.row(2) = cv::Scalar(15);
    layers.row(3) = cv::Scalar(1);



    criteria.max_iter = 300;
    criteria.epsilon = 0.00001f;
    criteria.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS;
    params.train_method = CvANN_MLP_TrainParams::BACKPROP;
    params.bp_dw_scale = 0.05f;
    params.bp_moment_scale = 0.05f;
    params.term_crit = criteria;

    mlp.create(layers);


    mlp.train(trainingData, trainingClasses, cv::Mat(), cv::Mat(), params);

    cv::Mat response(1, 1, CV_32FC1);
    cv::Mat predicted(testClasses.rows, 1, CV_32F);
    for(int i = 0; i < testData.rows; i++) {
        cv::Mat response(1, 1, CV_32FC1);
        cv::Mat sample = testData.row(i);

        mlp.predict(sample, response);
        predicted.at<float>(i,0) = response.at<float>(0,0);

        cout<<testData.at<float>(i, 0)<<", "<<testData.at<float>(i, 1)<<" = "<<response.at<float>(0, 0)<<endl;
    }

    cout << "Accuracy_{MLP} = " << evaluate(predicted, testClasses) << endl;



    mlp.save("mlp.yaml");
}
owacoder
  • 4,815
  • 20
  • 47
cppxaxa
  • 135
  • 1
  • 9

1 Answers1

0

After some more testing, I figured it out.

Commenting out mlp.save() also requires me to comment mlp.create().

mlp.create() is replacing layers of mlp object after being loaded from file.

cppxaxa
  • 135
  • 1
  • 9