home *** CD-ROM | disk | FTP | other *** search
- /* =======================================================
- Neural Network Classes for the NeXT Computer
- Written by: Ralph Zazula
- University of Arizona - Fall 1991
- zazula@pri.com (NeXT Mail)
- ==========================================================*/
- #import "BackPropEngine.h"
-
- double *error;
-
- @implementation BackPropEngine
-
- - inputs { return inputs; }
- - hidden { return hidden; }
- - outputs { return outputs; }
- - (double)getEta { return ETA; }
- - setEta:(double)newEta { ETA = newEta; return self;}
- - (double)getError { return Error; }
-
- - init
- {
- [super init];
-
- inputs = [[List alloc] init];
- hidden = [[List alloc] init];
- outputs = [[List alloc] init];
- random = [[Random alloc] init];
-
- ETA = 0.9;
- ALPHA = 0.9;
- Error = 0.0;
-
- return self;
- }
-
- - initWithInputs:(int)Nin hidden:(int)Nhid outputs:(int)Nout
- {
- int i,j;
-
- [self init];
-
- //
- // create the nodes
- //
- for(i=0; i<Nin; i++)
- [inputs addObject:[[[Neuron alloc] init]
- setRandom:random]];
- for(i=0; i<Nhid; i++)
- [hidden addObject:[[[Neuron alloc] init]
- setRandom:random]];
- for(i=0; i<Nout; i++)
- [outputs addObject:[[[Neuron alloc] init]
- setRandom:random]];
-
- //
- // make the connections
- //
- for(j=0; j<Nhid; j++)
- for(i=0; i<Nin; i++)
- [[hidden objectAt:j] connect:[inputs objectAt:i]];
- for(j=0; j<Nout; j++)
- for(i=0; i<Nhid; i++)
- [[outputs objectAt:j] connect:[hidden objectAt:i]];
- //
- // allocate other variables
- //
- error = (double *)malloc((Nout+1)*sizeof(double));
-
- return self;
- }
-
- - applyInput:(double *)input
- {
- int i;
-
- for(i=0; i<[inputs count]; i++)
- [[inputs objectAt:i] setOutput:(double)input[i]];
-
- for(i=0; i<[hidden count]; i++)
- [[hidden objectAt:i] step];
-
- for(i=0; i<[outputs count]; i++)
- [[outputs objectAt:i] step];
-
- return self;
- }
-
- - correctWithTarget:(double *)target
- {
- int i,j,k;
- id oNode, hNode, iNode;
- double O, delta;
-
- //
- // correct the hidden->output weights
- // and update the error
- //
- Error=0.0;
- for(i=0; i<[outputs count]; i++) {
- oNode = [outputs objectAt:i];
- O = [oNode lastOutput];
- error[i] = target[i] - O;
- Error += error[i]*error[i]/2.0;
- for(j=0; j<[hidden count]; j++) {
- hNode = [hidden objectAt:j];
- [oNode changeWeightFor:hNode
- by:error[i]*[hNode lastOutput]*ETA*O*(1-O)];
- }
- }
- //
- // correct the input->hidden weights
- //
- for(k=0; k<[inputs count]; k++) {
- iNode = [inputs objectAt:k];
- for(j=0; j<[hidden count]; j++) {
- hNode = [hidden objectAt:j];
- delta = 0.0;
- for(i=0; i<[outputs count]; i++) {
- oNode = [outputs objectAt:i];
- O = [oNode lastOutput];
- delta +=O*(1-O)*error[i]*[oNode getWeightFor:hNode];
- }
- [hNode changeWeightFor:iNode
- by:delta*ETA*[iNode lastOutput]*
- [hNode lastOutput]*(1-[hNode lastOutput])];
- }
- }
-
- return self;
- }
-
- @end
-