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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With