I made my first 1 dimensional classification neural network in C++ in which the logic is as follows:
- If input <= 1: f(x) = 1
- If input > 1: f(x) = -1
I made it extremely sloppy at first, but now that I know it works I changed the code to be more generic for number of inputs so I can easily change the size of [x] when I feel so inclined. However the new code is not getting the logic right; It comes out with totally wrong answers and similar weights for all inputs.
* Keep in mind that my variable names are stupid and variable “outputs” is actually the training set.
This is my final output from the program:
Input: 1 ; Class: 1 ; Eval = -1
Weight for node 1: -2
Input: 2 ; Class: -1 ; Eval = -1
Weight for node 2: -2
Input: 3 ; Class: -1 ; Eval = -1
Weight for node 3: -1
The “Class” is what it should be, and “Eval” is what it actually is. Notice the first input does not match it’s training element.
Original Code:
#include <iostream>
using namespace std;
double weights[2] = {0.0};
double classify(double);
int main() {
double inputs[2] = {1.0, 2.0};
double outputs[2] = {1.0, -1.0};
int index = 0;
bool trained = false;
while(!trained) {
trained = true;
cout << inputs[0] << " , " << outputs[0] << " eval = " << classify(inputs[0]) << endl;
cout << inputs[1] << " , " << outputs[1] << " eval = " << classify(inputs[1]) << endl;
cout << "Weights = " << weights[0] << " , " << weights[1] << endl << endl;
index = 0;
while(index < 2) {
double input = inputs[index];
double output = outputs[index];
double dClass = classify(input);
if (dClass != output) {
weights[0] += output * input;
weights[1] += output * 1.0;
trained = false;
}
index++;
}
}
return 0;
}
double classify(double input){
double products[2];
double sum = 0;
double threshhold;
// Sumation of inputs
products[0] = input * weights[0];
products[1] = 1.0 * weights[1];
sum = products[0] + products[1];
// Threshold function
if (sum >= 0.0)
threshhold = 1.0;
else
threshhold = -1.0;
return threshhold;
}
Modified Code:
#include <iostream>
#define NODES 3
using namespace std;
double weights[NODES] = {0.0};
double classify(double);
int main() {
double inputs[NODES] = {1.0, 2.0, 3.0};
double outputs[NODES] = {1.0, -1.0, -1.0};
int index = 0;
bool trained = false;
index = 0;
// While the classifications are incrorrect
while(!trained) {
trained = true;
while(index < NODES) {
double input = inputs[index]; // Input nodes
double output = outputs[index]; // Desired class
double dClass = classify(input); // Calculated class
// If calculated class != desired class:
// adjust the weights
if (dClass != output) {
for(int i = 0; i < NODES - 1; i++)
weights[i] += output * input;
// Bias weight
weights[NODES-1] += output * 1.0;
trained = false;
}
index++;
// Debugging
for(int i = 0; i < NODES; i++){
cout << "Input: " << inputs[i] << " ; Class: " << outputs[i] << " ; Eval = " << dClass << endl;
cout << "Weight for node " << i + 1 << ": " << weights[i] << endl;
}
cout << endl;
}
}
return 0;
}
double classify(double input){
double products[NODES];
double sum = 0;
double threshhold;
// Attach weights to nodes
for(int i = 0; i < NODES - 1; i++)
products[i] = input * weights[i];
// Last node with bias
products[NODES-1] = 1.0 * weights[NODES-1];
// Sumation of inputs
for(int i = 0; i < NODES; i++)
sum += products[i];
// Threshold function
if (sum >= 0.0)
threshhold = 1.0;
else
threshhold = -1.0;
return threshhold;
}
If you can answer this question, then I have a follow up if you feel like giving me input (though it is closer to a conversational question). I am new to implementing neural networks and am curious as to what you all think are the est data structures for an average back propagating, fixed topology ANN, as well as for a dynamic one (that would perhaps be used in neuro evolution). Is there a good neural network implementation convention to go by?
It appears we have a mystery. Before we get too far into it, try making this small change to
main()(just a change in what it prints) and tell us what you get. Don’t just say that it gives the wrong answers or that the desired results are not achieved, tell us what it actually produces.OBSOLETE CODE DELETED
EDIT:
You have two problems. First, you’re a little confused about what this code is doing; the number of nodes and the number of elements in your training set are fundamentally independent, but you’re treating them as identical and getting confused about which one you’re iterating over. Second, you neglect to reset
indexat the end of the inner loop. Change this:to this:
Now it works.