Original Post
Hi! Im building a neural network which is suppose to recognize some smilies. Something seems to be wrong but I cant find it. First I train the network 1000 times by calling recognize() and then train() inside a loop. After I do the same but this time only calling recognize() to see have many the NN could recognize. The percentage is allways the same, 25% which is exaclty the probability without the training. The initial values for the link-weights are set to som random real number between -1 and 1. The pixels in the picture is also normalized between -1 and 1. Anyway, I really need som help with this. I have searched my code for the error a long time and I belive I need some help :( Feel free to ask questions about my implementation. This is my first NN.
[SOURCE]
#include <iostream>
#include <fstream>
#include <time.h>
#include <cmath>
#include "Image.h"
#include "Node.h"
#include "Parser.h"
#include "Happy.h"
using namespace std;
void Happy::buildNetwork(vector<Image*> *images) {
int w = (images->at(0))->w;
int h = (images->at(0))->h;
nrOfInput = w * h;
nrOfOutput = 4;
nrOfHidden = (nrOfInput + nrOfOutput) / 2;
Input = new Node[nrOfInput];
for(int i=0; i<nrOfInput; i++) {
Node *n = new Node();
n->initWeights(nrOfHidden);
Input = *n;
}
Hidden = new Node[nrOfHidden];
for(int i=0; i<nrOfHidden; i++) {
Node *n = new Node();
n->initWeights(nrOfOutput);
Hidden = *n;
}
Output = new Node[nrOfOutput];
for(int i=0; i<nrOfOutput; i++) {
Output = *(new Node());
}
}
float Happy::sigmoid(float x) {
return 1.0 / (1.0 + exp(-x));
}
int Happy::recognize(Image *image) {
/* Assign values to the input nodes from the image */
for(int i=0; i<nrOfInput; i++) {
Input.activation = image->pixels;
}
/* Set hidden nodes activation/output */
for(int i=0; i<nrOfHidden; i++) {
double total = 0.0;
for(int j=0; j<nrOfInput; j++) {
total += (Input[j].activation * Input[j].weights);
}
Hidden.activation = sigmoid(total);
}
/* Set output nodes activation/output */
for(int i=0; i<nrOfOutput; i++) {
double total = 0.0;
for(int j=0; j<nrOfHidden; j++) {
total += Hidden[j].activation * Hidden[j].weights;
}
Output.activation = sigmoid(total);
}
/* which output has biggest value? */
int maxIndex = 0;
for(int i =0; i<nrOfOutput; i++) {
if(Output.activation > maxIndex) {
maxIndex = i;
}
}
/* the answers is given 1-4. Thats explains the maxIndex+1 */
if(maxIndex+1 == image->answer) {
correct++;
}
return maxIndex;
}
void Happy::train(Image* image) {
/* Output error */
for(int i=0; i<nrOfOutput; i++) {
double activation = Output.activation;
if(i + 1 == image->answer) {
Output.error = activation * (1 - activation) * (1 - activation);
} else {
Output.error = activation * (1 - activation) * (0 - activation);
}
}
/* Hidden error */
for(int i = 0; i < nrOfHidden; i++) {
double total = 0.0;
for(int j=0; j < nrOfOutput; j++) {
total += Hidden.weights[j] * Output[j].error;
}
Hidden.error = total;
}
/* Input error */
for(int i = 0; i < nrOfInput; i++) {
double total = 0.0;
for(int j=0; j < nrOfHidden; j++) {
total += Input.weights[j] * Hidden[j].error;
}
Input.error = total;
}
/* Update weights for hidden links*/
for(int i = 0; i < nrOfOutput; i++) {
for(int j=0; j < nrOfHidden; j++) {
Hidden[j].weights += (learningRate * Output.error * Hidden[j].activation);
}
}
/* Update weights for input links*/
for(int i = 0; i < nrOfHidden; i++) {
for(int j=0; j < nrOfInput; j++) {
Input[j].weights += (learningRate * Hidden.error * Input[j].activation);
}
}
}
Happy::Happy() {
this->learningRate = 0.2;
}
int main(int argc, char** argv) {
if(argc != 3) {
cout << "you fail" << endl;
} else {
if(!strcmp(argv[1], "train")) {
Parser* p = new Parser();
vector<Image*> *images = p->parseFile(argv[2]);
Happy *h = new Happy();
h->buildNetwork(images);
h->correct = 0;
/* Train */
for(int i = 0;i< 1000; i++) {
h->recognize(images->at(i));
h->train(images->at(i));
}
/* reset the counter */
h->correct = 0;
for(int i = 0;i< 1000; i++) {
h->recognize(images->at(i));
}
cout << "Correct: " << (h->correct/1000.0) * 100 << "%" << endl;
}
}
return 0;
}
[/SOURCE]