/*
main.cpp
Main driver for adaline network
Written by Keith Hughes, 21 May, 1999
CSC 143, North Seattle Community College
*/
#include <fstream.h>
#include <stdlib.h>
#include <time.h>
#include "adaline.h"
// How many samples we'll take to check out what our current
// error rate for the network is.
static int ERROR_RESOLUTION = 1000;
// What we want the overall error rate of the network to be
// before we finish training it.
static double NETWORK_ERROR_TOLERANCE = 0.001;
// When training for a particular problem, we want our error
// rate to be below this value.
static double INDIVIDUAL_ERROR_TOLERANCE = 0.01;
double ErrorRate(AdalineNet &);
void GroupTest(AdalineNet &, char *);
void Train(AdalineNet &, double);
/*
double f(x, y)
The function we want to train the network to mimic.
Doesn't really matter what the function is as long as it is
linearly separable.
*/
double f(double x, double y) {
return ((-5.0 * x - 2.0) / 4.0 >= y) ? 1.0 : -1.0;
}
/*
int main(void)
Main driver for the neural simulator.
Creates a simple two layer Adaline network, train it against
random samples against the f() function given above, then
do a final test to see how it is performing.
*/
int
main(void)
{
// srand((unsigned int) time(NULL));
// cout << "Creating an AdalineNet an1(3)..." << endl;
// AdalineNet an1(3);
// cout << "Write to file \"testfile.txt\" " << endl;
// ofstream test("testfile.txt);
// an1.WriteToFile(test);
ifstream test1("testfile.txt");
cout << "Creating an empty AdalineNet an..." << endl;
AdalineNet an;
cout << "Reading from file \"testfile.txt\" " << endl;
an.ReadFromFile(test1);
cout << "Write to file \"testfile2.txt\" " << endl;
ofstream test2("testfile2.txt");
an.WriteToFile(test2);
// Starting and ending times of our training run.
time_t begin, end;
cout << "Welcome to the Adaline Network Simulator V1.0\n\n";
// Tell user what we're doing and open file for output data.
cout << "Creating network.\n\n";
// Create the network with two layers, give two nodes in the input
// layer and 1 in the output layer and connect the neurons together
AdalineNet n(2);
// Let's see how the initial network does.
GroupTest(n, "Initial test");
// Train the network, timing how long it takes.
cout << "\n\nTraining" << endl;
begin = time(NULL);
Train(n, NETWORK_ERROR_TOLERANCE);
end = time(NULL);
cout << "\n\nDone training (" << end - begin <<
" seconds)" << endl;
// Now demonstrate that our error has gone down, but isn't
// exact.
cout << "\n\n";
GroupTest(n, "Final test");
// yeah, it all worked.
return 0;
}
/*
double ErrorRate(AdalineNet &n)
Calculate the current error rate of adaline network <n>.
We hand the network a series of random problems, count how many
it gets wrong, and return the percentage wrong.
*/
double
ErrorRate(AdalineNet &n)
{
// Inputs to the problem
double x, y;
// How many wrong answers we've seen.
int count = 0;
// Run a series of problems.
for (int problem = 0; problem < ERROR_RESOLUTION; problem++) {
// Create the problem values
x = ((double)rand()/(double)RAND_MAX) * 2.0 - 1.0;
y = ((double)rand()/(double)RAND_MAX) * 2.0 - 1.0;
// Make the network calculate an answer
n.SetInputValue(0, x);
n.SetInputValue(1, y);
n.Fire();
// Increase error count if we didn't get it.
if (f(x,y) != n.GetOutputValue(0))
count++;
}
// Return the percentage wrong.
return (double)count/(double)ERROR_RESOLUTION;
}
/*
void GroupTest(AdalineNet &n, char *label)
Run several error rate tests on the network, printing out the
error rate of each test. Label each test with <label>.
*/
void
GroupTest(
AdalineNet &n,
char *label
)
{
cout << label << " 1: " << ErrorRate(n) << endl;
cout << label << " 2: " << ErrorRate(n) << endl;
cout << label << " 3: " << ErrorRate(n) << endl;
cout << label << " 4: " << ErrorRate(n) << endl;
cout << label << " 5: " << ErrorRate(n) << endl;
cout << label << " 6: " << ErrorRate(n) << endl;
}
/*
void Train(AdalineNet &n, double errorThreshold)
Train network <n> by handing it problems until the error
rate for the network goes below a certain thershold.
*/
void
Train(
AdalineNet &n,
double errorThreshold
)
{
// Output we want from the network from a given set of inputs
double desiredOutput;
// The inputs we'll give the network for the function at hand.
double x, y;
// Current error in caculating a network output with
// what we want.
double error;
// Create a learning situation. We'll feed test cases with
// known answers into the system until we get an
// error rate from the whole network that is liveable.
while (ErrorRate(n) >= errorThreshold) {
// Generate two numbers between +1.0.
x = ((double)rand()/(double)RAND_MAX) * 2.0 - 1.0;
y = ((double)rand()/(double)RAND_MAX) * 2.0 - 1.0;
// What our desired output is.
desiredOutput = f(x,y);
// These numbers will be our inputs into the network
n.SetInputValue(0, x);
n.SetInputValue(1, y);
// We'll keep feeding these two number to the network and
// firing it to calculate a result that we would like to be
// the same as f(x,y).
// We'll calculate the error between what the network
// calculates and what f(x,y) actually returns. While
// the error isn't within the desired error tolerance,
// we'll force the network to learn.
do {
n.Fire();
error = desiredOutput - n.GetOutputValue(0);
// Still not close enough. Force the network to learn
n.DesiredOutput(desiredOutput);
n.Learn();
} while (error >= INDIVIDUAL_ERROR_TOLERANCE);
}
}
Back Top