/****************************************************************************
Neural Network Library example program: a simple character classifier.
Copyright (C) 1998 Daniel Franklin
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************/
#include <nnwork.h>
#include <iostream.h>
#include <iomanip.h>
#include <ctype.h>
#include <stdlib.h>
#include <time.h>
extern float Alphabet [26][35];
// Copy size elements from source [] to destination []
void copy_array (float destination [], float source [], int size)
{
for (int i = 0; i < size; i++)
destination [i] = source [i];
}
// Add some noise to data []
void noisify (float data [], int size, float range)
{
for (int i = 0; i < size; i++)
data [i] += (range - 2 * range * random () / float (RAND_MAX));
}
// Print the width x height character in data []
void print_char (float data [], int height, int width)
{
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++)
if (data [j + i * width] >= 0)
cout << "#";
else
cout << " ";
cout << endl;
}
cout << endl;
}
int main ()
{ // you can safely adjust the size of the hidden layer (the middle argument)
nnwork brain (35, 60, 26);
float result [26];
char character;
float range, max;
int max_idx, i, j, N;
unsigned long t;
float data [35];
// Initially, all cell entries other than result [0] are "false"
// note that "result" is used both for training (desired result) and running.
for (i = 1; i < 26; i++)
result [i] = 0.1;
srandom (time (0));
cout << "Train or read from file (t|f)? ";
cin >> character;
// For some reason the network starts learning faster when it starts at A.
// Don't ask me why.
N = 0;
if (character == 't') {
for (i = 0; i < 100; i++) {
if (N == 26)
N--;
result [N] = 0.9;
// Copy one of the letters
copy_array (data, Alphabet [N], 35);
// Introduce some noise
noisify (data, 35, 1.0);
// Train the network
brain.train (data, result, 0.000001, 0.3);
result [N] = 0.1;
if (!(i % 10)) cout << "Trained run number " << i << endl;
N = int (26.0 * random () / float (RAND_MAX));
}
// Save the data
brain.save ("char_recognition.nnw");
// Or attempt to load the data
} else if (!brain.load ("char_recognition.nnw")) {
cerr << "File not found.\n";
return -1;
}
// Pick a letter
cout << "Choose a letter (A-Z or a-z): ";
cin >> character;
if (!isalpha (character)) {
cerr << "Error: must be alphabetic character\n";
return -1;
}
copy_array (data, Alphabet [toupper (character) - 'A'], 35);
cout << "Max. amplitude of additive noise (suggest 1.5, i.e. +1.5 -> -1.5)? ";
cin >> range;
// Introduce some noise
noisify (data, 35, range);
cout << "The character presented to the neural network:\n";
// Display the character + noise
print_char (data, 7, 5);
brain.run (data, result);
max = 0.;
max_idx = 0;
// Get the best match
for (i = 0; i < 26; i++)
if (result [i] > max) {
max = result [i];
max_idx = i;
}
cout << "Best match: " << char ('A' + max_idx) << endl;
return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1