Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCR with perceptron neural network of Aforge.net answers wrong

I tried to make OCR by perceptrons with Aforge.Net in C#. I learned my network with nine 30*30 pictures in binary. But in the results, it recognizes everything as 'C'. this is the code:

    private void button1_Click(object sender, EventArgs e)
    {
        AForge.Neuro.ActivationNetwork network = new AForge.Neuro.ActivationNetwork(new AForge.Neuro.BipolarSigmoidFunction(2), 900, 3);
        network.Randomize();
        AForge.Neuro.Learning.PerceptronLearning learning = new AForge.Neuro.Learning.PerceptronLearning(network);
        learning.LearningRate =1 ;
        double[][] input = new double[9][];
        for (int i = 0; i < 9; i++)
        {
            input[i] = new double[900];
        }
   //Reading A images
        for (int i = 1; i <= 3; i++)
        {
            Bitmap a = AForge.Imaging.Image.FromFile(path + "\\a" + i + ".bmp");
            for (int j = 0; j < 30; j++)
                for (int k = 0; k < 30; k++)
                {
                    if (a.GetPixel(j, k).ToKnownColor() == KnownColor.White)
                    {
                        input[i-1][j * 10 + k] = -1;
                    }
                    else
                        input[i-1][j * 10 + k] = 1;
                }
           // showImage(a);

        }
   //Reading B images
        for (int i = 1; i <= 3; i++)
        {
            Bitmap a = AForge.Imaging.Image.FromFile(path + "\\b" + i + ".bmp");
            for (int j = 0; j < 30; j++)
                for (int k = 0; k < 30; k++)
                {
                    if (a.GetPixel(j , k).ToKnownColor() == KnownColor.White)
                    {
                        input[i + 2][j * 10 + k] = -1;
                    }
                    else
                        input[i + 2][j * 10 + k] = 1;
                }
           // showImage(a);

        }
   //Reading C images
        for (int i = 1; i <= 3; i++)
        {
            Bitmap a = AForge.Imaging.Image.FromFile(path + "\\c" + i + ".bmp");
            for (int j = 0; j < 30; j++)
                for (int k = 0; k < 30; k++)
                {
                    if (a.GetPixel(j , k ).ToKnownColor() == KnownColor.White)
                    {
                        input[i + 5][j * 10 + k] = -1;
                    }
                    else
                        input[i + 5][j * 10 + k] = 1;
                }
           // showImage(a);

        }

        bool needToStop = false;
        int iteration = 0;
        while (!needToStop)
        {
            double error = learning.RunEpoch(input, new double[9][] { new double[3] { 1, -1, -1 },new double[3] { 1, -1, -1 },new double[3] { 1, -1, -1 },//A
                new double[3] { -1, 1, -1 },new double[3] { -1, 1, -1 },new double[3] { -1, 1, -1 },//B
                new double[3] { -1, -1, 1 },new double[3] { -1, -1, 1 },new double[3] { -1, -1, 1 } }//C
                    /*new double[9][]{ input[0],input[0],input[0],input[1],input[1],input[1],input[2],input[2],input[2]}*/
                );
            //learning.LearningRate -= learning.LearningRate / 1000;
            if (error == 0)
                break;
            else if (iteration < 1000)
                iteration++;
            else
                needToStop = true;
            System.Diagnostics.Debug.WriteLine("{0} {1}", error, iteration);
        }
        Bitmap b = AForge.Imaging.Image.FromFile(path + "\\b1.bmp");
    //Reading A Sample to test Netwok
        double[] sample = new double[900];
        for (int j = 0; j < 30; j++)
            for (int k = 0; k < 30; k++)
            {
                if (b.GetPixel(j , k ).ToKnownColor() == KnownColor.White)
                {
                    sample[j * 30 + k] = -1;
                }
                else
                    sample[j * 30 + k] = 1;
            }
        foreach (double d in network.Compute(sample))
            System.Diagnostics.Debug.WriteLine(d);//Output is Always C = {-1,-1,1}
    }

I really wanted to know why it answers wrong.

like image 244
Navid Nabavi Avatar asked Dec 22 '12 16:12

Navid Nabavi


1 Answers

While loading your initial 30x30 images into a double[900] array in the input structure you are using the following calculation:

for (int j = 0; j < 30; j++)
    for (int k = 0; k < 30; k++)
    {
        if (a.GetPixel(j, k).ToKnownColor() == KnownColor.White)
            input[i-1][j * 10 + k] = -1;
        else
            input[i-1][j * 10 + k] = 1;
    }

Your offset calculation is wrong here. You need to change j * 10 + k to j * 30 + k or you will get invalid results. Later you use the correct offset calculation while loading the test image, which is why it's not being matched correctly against the corrupted samples.

You should write a method to load a bitmap into a double[900] array and call it for each image, instead of writing the same code multiple times. This helps to reduce problems like this, where different results are given by two pieces of code that should return the same result.

like image 113
Corey Avatar answered Oct 23 '22 03:10

Corey