Dear everyone,
Thanks a lot for having helped me in debugging my source code.Well,although I've got zero error, I'm not able to train the network well.If there is someone who understands back propagation network well, I would be grateful if he/she could help me to find a solution to my problem.Please,below is a copy of my source code.I hope to get a reply as soon as possible.
Thnx.
#include <iostream.h>
#include <math.h>
#include <stdlib.h>
#include<time.h>
const int MAX_INP = 5; // Maximum number of nodes in input layer
const int MIP = MAX_INP+1; //Extra unit used for thresholding
const int MAX_HID = 10; // Maximum number of nodes in hidden layer
const int MAX_OUT = 2; // Maximum number of nodes in output layer
const int MOT = MAX_OUT+1;
const int MAX_PAT = 4; //Maximum number of training patterns
const int MPT = MAX_PAT+1;
const float INP_PATTERNS[MPT][MIP] = {{0,0,0,0,0,1},{0,0,0,0,1,0},{0,0,0,1,0,0},
{0,0,1,0,0,0},{0,1,0,0,0,0}};
const float OUT_PATTERNS[MPT][MOT] =
{{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
struct layer{
float weight[MIP];//Weights assgned to the network
float weight_change[MIP];//Change in weights
float threshold;//Threshold used in the network
float a; //activation
float error; //Error between the layers
};
float test_pattern[MIP];//Array to hold input patterns
float target_output[MOT];//Array to hold output patterns
layer input_layer[MIP]; //Input layer
layer hidden_layer[MAX_HID+1]; //Hidden layer
layer output_layer[MOT]; //Output layer
//Declarations of all the functions used in the network
class CBackPNet{
public:
int contin();
float random_num();
float sigmoid(float);
void get_test_pattern();
void random_weights();
void run_input_units();
void run_hidden_units();
void run_output_units();
void feed_forward();
void display_results();
void calculate_mean_squared_error();
void calculate_output_layer_errors();
void calculate_hidden_layer_errors();
void calculate_input_layer_errors();
void test_network();
void adjust_weight();
void back_propagate();
void blank_changes();
void train_network();
};
// Prompts user to enter input values
void CBackPNet:: get_test_pattern()
{
cout << endl;
cout << "INPUT PARAMETERS" << endl;
for (int i = 1; i <= MAX_INP; i++)
{
cout << i << " . ";
cout<<"Machine Diameter: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"Machine Gauge: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"No. of Needles: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"LFA: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"Yarn Count: ";
cin >> test_pattern;
}
}
// Get a random number in the range 0 to 1 as a float
float CBackPNet:: random_num ()
{ return (rand()+0.0)/RAND_MAX; }
//Assign random numbers for each of the different layers
void CBackPNet:: random_weights ()
{ for (int i = 1; i <= MAX_INP; i++)
{ for (int j = 1; j <= MAX_INP; j++)
input_layer.weight[j] = random_num();
cout<<"input_layer["<<i<<"].weight["<<j<<"]=";
cout<<random_num()<<endl;
}
for ( i = 1; i <= MAX_HID; i++)
{ for (int j = 1; j <= MAX_INP; j++)
hidden_layer.weight[j] = random_num();
cout<<"hidden_layer["<<i<<"].weight["<<j<<"]=";
cout<<random_num()<<endl;
}
for ( i = 1; i <= MAX_OUT; i++)
{ for (int j = 1; j <= MAX_HID; j++)
output_layer.weight[j] = random_num();
cout<<"output_layer["<<i<<"].weight["<<j<<"]=";
cout<<random_num()<<endl;
}
}
//Definition of Sigmoid transfer function
float CBackPNet::sigmoid (float num)
{
return (float)(1/(1+exp(-num)));
}
//
void CBackPNet:: run_input_units ()
{ float sum;
for (int i = 1; i <= MAX_INP; i++)
{ sum = 0;
for (int j = 1; j <= MAX_INP; j++)
sum += input_layer.weight[j] * test_pattern[j];
input_layer.a = sigmoid(sum - input_layer.threshold);
}
}
void CBackPNet:: run_hidden_units ()
{ float sum;
for (int i = 1; i <= MAX_HID; i++)
{ sum = 0;
for (int j = 1; j <= MAX_INP; j++)
sum += hidden_layer.weight[j] * input_layer[j].a;
hidden_layer.a = sigmoid(sum - hidden_layer.threshold);
}
}
void CBackPNet:: run_output_units ()
{ float sum;
for (int i = 1; i <= MAX_OUT; i++)
{ sum = 0;
for (int j = 1; j <= MAX_HID; j++)
sum += output_layer.weight[j] * hidden_layer[j].a;
output_layer.a = sigmoid(sum - output_layer.threshold);
}
}
void CBackPNet:: feed_forward ()
{
run_input_units();
run_hidden_units();
run_output_units();
}
// This procedure displays the results of the test on the screen.
void CBackPNet:: display_results ()
{ cout << endl << "INPUTS: ";
for (int i = 1; i <= MAX_INP; i++)
cout << test_pattern << " ";
cout << endl << "OUTPUTS: ";
for (i = 1; i <= MAX_OUT; i++)
cout << output_layer.a << " ";
cout << endl;
}
int CBackPNet:: contin ()
{ char k;
cout << endl << " Do you want another test pattern? (Press Y or N) ";
do
{ cin >> k; }
while (k != 'Y' && k != 'y' && k != 'N' && k != 'n');
if (k == 'Y' || k == 'y')
return 1;
else
return 0;
}
void CBackPNet:: test_network ()
{
cout<<endl;
do
{ get_test_pattern();
feed_forward();
display_results();
}
while (contin() == 1);
}
void CBackPNet:: calculate_mean_squared_error()
{ float error_function;
float target_output[MOT]={0.05,0.95};
float sum=0;
for (int j = 1; j <= MAX_OUT; j++)
sum+=pow((target_output[j] - output_layer[j].a),2);
error_function= 0.5* sum;
cout<<"Error Function:";
cout<<error_function<<" ";
cout<<endl;
}
void CBackPNet:: calculate_output_layer_errors ()
{ for (int j = 1; j <= MAX_OUT; j++)
output_layer[j].error = output_layer[j].a * (1 - output_layer[j].a) * (target_output[j] - output_layer[j].a);
}
void CBackPNet:: calculate_hidden_layer_errors ()
{ float sum;
for (int i = 1; i <= MAX_HID; i++)
{ sum = 0;
for (int j = 1; j <= MAX_OUT; j++)
sum += output_layer[j].error * output_layer[j].weight;
hidden_layer.error = hidden_layer.a * (1 - hidden_layer.a) * sum;
}
}
void CBackPNet:: calculate_input_layer_errors ()
{ float sum;
for (int i = 1; i <= MAX_INP; i++)
{ sum = 0;
for (int j = 1; j <= MAX_HID; j++)
sum += hidden_layer[j].error * hidden_layer[j].weight;
input_layer.error = input_layer.a * (1 - input_layer.a) * sum;
}
}
void CBackPNet:: adjust_weight()
{ const float learn_coeff = 0.9; // Learning rate
const float momentum = 0.9; // Momentum parameter
for (int j = 1; j <= MAX_OUT; j++)
{ for (int i = 1; i <= MAX_HID; i++)
{ output_layer[j].weight_change = learn_coeff * output_layer[j].error * hidden_layer.a + momentum * output_layer[j].weight_change;
output_layer[j].weight += output_layer[j].weight_change;
}
}
for (j = 1; j <= MAX_HID; j++)
{ for (int i = 1; i <= MAX_INP; i++)
{ hidden_layer[j].weight_change = learn_coeff * hidden_layer[j].error * input_layer.a + momentum * hidden_layer[j].weight_change;
hidden_layer[j].weight += hidden_layer[j].weight_change;
}
}
for (j = 1; j <= MAX_INP; j++)
{ for (int i = 1; i <= MAX_INP; i++)
{ input_layer[j].weight_change = learn_coeff * input_layer[j].error * test_pattern + momentum * input_layer[j].weight_change;
input_layer[j].weight += input_layer[j].weight_change;
}
}
}
void CBackPNet:: back_propagate ()
{
calculate_mean_squared_error();
calculate_output_layer_errors();
calculate_hidden_layer_errors();
calculate_input_layer_errors();
adjust_weight();
}
// At the start of back propagation, there are no weight changes to
// influence the next cycle, so clear the arrays
void CBackPNet:: blank_changes ()
{ for (int j = 1; j <= MAX_INP; j++)
{ for (int i = 1; i <= MAX_INP; i++)
input_layer[j].weight_change = 0;
}
for (j = 1; j <= MAX_HID; j++)
{ for (int i = 1; i <= MAX_INP; i++)
hidden_layer[j].weight_change = 0;
}
for (j = 1; j <= MAX_OUT; j++)
{ for (int i = 1; i <= MAX_HID; i++)
output_layer[j].weight_change = 0;
}
}
void CBackPNet:: train_network ()
{ long num_cycles;
cout << endl;
cout << "Enter the number of training cycles : ";
cin >> num_cycles;
blank_changes();
for (long loop = 1; loop <= num_cycles; loop++)
for (int pat = 1; pat <= MAX_PAT; pat++)
{ for (int i = 1; i <= MAX_INP; i++)
test_pattern = INP_PATTERNS[pat];
for (i = 1; i <= MAX_OUT; i++)
target_output = OUT_PATTERNS[pat];
feed_forward();
back_propagate();
}
}
int main ()
{
CBackPNet neural;
neural.random_weights();
neural.test_network();
neural.calculate_mean_squared_error();
neural.train_network();
neural.test_network();
return 0;
}
Thanks a lot for having helped me in debugging my source code.Well,although I've got zero error, I'm not able to train the network well.If there is someone who understands back propagation network well, I would be grateful if he/she could help me to find a solution to my problem.Please,below is a copy of my source code.I hope to get a reply as soon as possible.
Thnx.
#include <iostream.h>
#include <math.h>
#include <stdlib.h>
#include<time.h>
const int MAX_INP = 5; // Maximum number of nodes in input layer
const int MIP = MAX_INP+1; //Extra unit used for thresholding
const int MAX_HID = 10; // Maximum number of nodes in hidden layer
const int MAX_OUT = 2; // Maximum number of nodes in output layer
const int MOT = MAX_OUT+1;
const int MAX_PAT = 4; //Maximum number of training patterns
const int MPT = MAX_PAT+1;
const float INP_PATTERNS[MPT][MIP] = {{0,0,0,0,0,1},{0,0,0,0,1,0},{0,0,0,1,0,0},
{0,0,1,0,0,0},{0,1,0,0,0,0}};
const float OUT_PATTERNS[MPT][MOT] =
{{0,0,0},{0,0,0},{0,0,0},{0,0,0},{0,0,0}};
struct layer{
float weight[MIP];//Weights assgned to the network
float weight_change[MIP];//Change in weights
float threshold;//Threshold used in the network
float a; //activation
float error; //Error between the layers
};
float test_pattern[MIP];//Array to hold input patterns
float target_output[MOT];//Array to hold output patterns
layer input_layer[MIP]; //Input layer
layer hidden_layer[MAX_HID+1]; //Hidden layer
layer output_layer[MOT]; //Output layer
//Declarations of all the functions used in the network
class CBackPNet{
public:
int contin();
float random_num();
float sigmoid(float);
void get_test_pattern();
void random_weights();
void run_input_units();
void run_hidden_units();
void run_output_units();
void feed_forward();
void display_results();
void calculate_mean_squared_error();
void calculate_output_layer_errors();
void calculate_hidden_layer_errors();
void calculate_input_layer_errors();
void test_network();
void adjust_weight();
void back_propagate();
void blank_changes();
void train_network();
};
// Prompts user to enter input values
void CBackPNet:: get_test_pattern()
{
cout << endl;
cout << "INPUT PARAMETERS" << endl;
for (int i = 1; i <= MAX_INP; i++)
{
cout << i << " . ";
cout<<"Machine Diameter: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"Machine Gauge: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"No. of Needles: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"LFA: ";
cin >> test_pattern;
cout << ++i << " . ";
cout<<"Yarn Count: ";
cin >> test_pattern;
}
}
// Get a random number in the range 0 to 1 as a float
float CBackPNet:: random_num ()
{ return (rand()+0.0)/RAND_MAX; }
//Assign random numbers for each of the different layers
void CBackPNet:: random_weights ()
{ for (int i = 1; i <= MAX_INP; i++)
{ for (int j = 1; j <= MAX_INP; j++)
input_layer.weight[j] = random_num();
cout<<"input_layer["<<i<<"].weight["<<j<<"]=";
cout<<random_num()<<endl;
}
for ( i = 1; i <= MAX_HID; i++)
{ for (int j = 1; j <= MAX_INP; j++)
hidden_layer.weight[j] = random_num();
cout<<"hidden_layer["<<i<<"].weight["<<j<<"]=";
cout<<random_num()<<endl;
}
for ( i = 1; i <= MAX_OUT; i++)
{ for (int j = 1; j <= MAX_HID; j++)
output_layer.weight[j] = random_num();
cout<<"output_layer["<<i<<"].weight["<<j<<"]=";
cout<<random_num()<<endl;
}
}
//Definition of Sigmoid transfer function
float CBackPNet::sigmoid (float num)
{
return (float)(1/(1+exp(-num)));
}
//
void CBackPNet:: run_input_units ()
{ float sum;
for (int i = 1; i <= MAX_INP; i++)
{ sum = 0;
for (int j = 1; j <= MAX_INP; j++)
sum += input_layer.weight[j] * test_pattern[j];
input_layer.a = sigmoid(sum - input_layer.threshold);
}
}
void CBackPNet:: run_hidden_units ()
{ float sum;
for (int i = 1; i <= MAX_HID; i++)
{ sum = 0;
for (int j = 1; j <= MAX_INP; j++)
sum += hidden_layer.weight[j] * input_layer[j].a;
hidden_layer.a = sigmoid(sum - hidden_layer.threshold);
}
}
void CBackPNet:: run_output_units ()
{ float sum;
for (int i = 1; i <= MAX_OUT; i++)
{ sum = 0;
for (int j = 1; j <= MAX_HID; j++)
sum += output_layer.weight[j] * hidden_layer[j].a;
output_layer.a = sigmoid(sum - output_layer.threshold);
}
}
void CBackPNet:: feed_forward ()
{
run_input_units();
run_hidden_units();
run_output_units();
}
// This procedure displays the results of the test on the screen.
void CBackPNet:: display_results ()
{ cout << endl << "INPUTS: ";
for (int i = 1; i <= MAX_INP; i++)
cout << test_pattern << " ";
cout << endl << "OUTPUTS: ";
for (i = 1; i <= MAX_OUT; i++)
cout << output_layer.a << " ";
cout << endl;
}
int CBackPNet:: contin ()
{ char k;
cout << endl << " Do you want another test pattern? (Press Y or N) ";
do
{ cin >> k; }
while (k != 'Y' && k != 'y' && k != 'N' && k != 'n');
if (k == 'Y' || k == 'y')
return 1;
else
return 0;
}
void CBackPNet:: test_network ()
{
cout<<endl;
do
{ get_test_pattern();
feed_forward();
display_results();
}
while (contin() == 1);
}
void CBackPNet:: calculate_mean_squared_error()
{ float error_function;
float target_output[MOT]={0.05,0.95};
float sum=0;
for (int j = 1; j <= MAX_OUT; j++)
sum+=pow((target_output[j] - output_layer[j].a),2);
error_function= 0.5* sum;
cout<<"Error Function:";
cout<<error_function<<" ";
cout<<endl;
}
void CBackPNet:: calculate_output_layer_errors ()
{ for (int j = 1; j <= MAX_OUT; j++)
output_layer[j].error = output_layer[j].a * (1 - output_layer[j].a) * (target_output[j] - output_layer[j].a);
}
void CBackPNet:: calculate_hidden_layer_errors ()
{ float sum;
for (int i = 1; i <= MAX_HID; i++)
{ sum = 0;
for (int j = 1; j <= MAX_OUT; j++)
sum += output_layer[j].error * output_layer[j].weight;
hidden_layer.error = hidden_layer.a * (1 - hidden_layer.a) * sum;
}
}
void CBackPNet:: calculate_input_layer_errors ()
{ float sum;
for (int i = 1; i <= MAX_INP; i++)
{ sum = 0;
for (int j = 1; j <= MAX_HID; j++)
sum += hidden_layer[j].error * hidden_layer[j].weight;
input_layer.error = input_layer.a * (1 - input_layer.a) * sum;
}
}
void CBackPNet:: adjust_weight()
{ const float learn_coeff = 0.9; // Learning rate
const float momentum = 0.9; // Momentum parameter
for (int j = 1; j <= MAX_OUT; j++)
{ for (int i = 1; i <= MAX_HID; i++)
{ output_layer[j].weight_change = learn_coeff * output_layer[j].error * hidden_layer.a + momentum * output_layer[j].weight_change;
output_layer[j].weight += output_layer[j].weight_change;
}
}
for (j = 1; j <= MAX_HID; j++)
{ for (int i = 1; i <= MAX_INP; i++)
{ hidden_layer[j].weight_change = learn_coeff * hidden_layer[j].error * input_layer.a + momentum * hidden_layer[j].weight_change;
hidden_layer[j].weight += hidden_layer[j].weight_change;
}
}
for (j = 1; j <= MAX_INP; j++)
{ for (int i = 1; i <= MAX_INP; i++)
{ input_layer[j].weight_change = learn_coeff * input_layer[j].error * test_pattern + momentum * input_layer[j].weight_change;
input_layer[j].weight += input_layer[j].weight_change;
}
}
}
void CBackPNet:: back_propagate ()
{
calculate_mean_squared_error();
calculate_output_layer_errors();
calculate_hidden_layer_errors();
calculate_input_layer_errors();
adjust_weight();
}
// At the start of back propagation, there are no weight changes to
// influence the next cycle, so clear the arrays
void CBackPNet:: blank_changes ()
{ for (int j = 1; j <= MAX_INP; j++)
{ for (int i = 1; i <= MAX_INP; i++)
input_layer[j].weight_change = 0;
}
for (j = 1; j <= MAX_HID; j++)
{ for (int i = 1; i <= MAX_INP; i++)
hidden_layer[j].weight_change = 0;
}
for (j = 1; j <= MAX_OUT; j++)
{ for (int i = 1; i <= MAX_HID; i++)
output_layer[j].weight_change = 0;
}
}
void CBackPNet:: train_network ()
{ long num_cycles;
cout << endl;
cout << "Enter the number of training cycles : ";
cin >> num_cycles;
blank_changes();
for (long loop = 1; loop <= num_cycles; loop++)
for (int pat = 1; pat <= MAX_PAT; pat++)
{ for (int i = 1; i <= MAX_INP; i++)
test_pattern = INP_PATTERNS[pat];
for (i = 1; i <= MAX_OUT; i++)
target_output = OUT_PATTERNS[pat];
feed_forward();
back_propagate();
}
}
int main ()
{
CBackPNet neural;
neural.random_weights();
neural.test_network();
neural.calculate_mean_squared_error();
neural.train_network();
neural.test_network();
return 0;
}