1 /* -*- Mode: C++; -*- */
2 /* VER: $Id: ANN.cpp,v 1.4.2.2 2011/12/31 02:51:47 berniw Exp $ */
3 // copyright (c) 2004 by Christos Dimitrakakis <dimitrak@idiap.ch>
4 /***************************************************************************
5 * *
6 * This program is free software; you can redistribute it and/or modify *
7 * it under the terms of the GNU General Public License as published by *
8 * the Free Software Foundation; either version 2 of the License, or *
9 * (at your option) any later version. *
10 * *
11 ***************************************************************************/
12
13 #include <cstring>
14 #include <learning/ANN.h>
15 #include <learning/string_utils.h>
16 #include <learning/Distribution.h>
17
18
19 #undef ANN_DBUG
20
21 //==========================================================
22 // NewANN
23 //----------------------------------------------------------
24 /// Create a new ANN
NewANN(int n_inputs,int n_outputs)25 ANN *NewANN(int n_inputs, int n_outputs)
26 {
27 ANN *ann = NULL;
28
29 if (!(ann = AllocM(ANN, 1))) {
30 Serror("Could not allocate ANN\n");
31 return NULL;
32 }
33 ann->x = NULL;
34 ann->y = NULL;
35 ann->t = NULL;
36 ann->d = NULL;
37 ann->error = NULL;
38 ann->c = NULL;
39 ann->a = 0.1f;
40 ann->lambda = 0.9f;
41 ann->zeta = 0.9f;
42 ann->n_inputs = n_inputs;
43 ann->n_outputs = n_outputs;
44 ann->batch_mode = false;
45
46
47 /* outputs are not allocated */
48 //logmsg ("Creating ANN with %d inputs and %d outputs\n", n_inputs, n_outputs);
49 if (!(ann->error = AllocM(real, n_outputs))) {
50 Serror("Could not allocate errors\n");
51 DeleteANN(ann);
52 return NULL;
53 }
54
55 if (!(ann->d = AllocM(real, n_outputs))) {
56 Serror("Could not allocate derivatives\n");
57 DeleteANN(ann);
58 return NULL;
59 }
60
61 if (!(ann->c = List())) {
62 Serror("Could not allocate list\n");
63 DeleteANN(ann);
64 return NULL;
65 }
66 #ifdef ANN_DBUG
67 message("Creating ANN with %d inputs and %d outputs", n_inputs,
68 n_outputs);
69 #endif
70 return ann;
71 }
72
73 //==========================================================
74 // DeleteANN
75 //----------------------------------------------------------
76 /// Delete a neural network
DeleteANN(ANN * ann)77 int DeleteANN(ANN * ann)
78 {
79 if (!ann) {
80 Swarning("Attempting to delete NULL ANN\n");
81 return DEC_ARG_INVALID;
82 }
83
84 if (ann->error) {
85 FreeM(ann->error);
86 }
87
88 //if (ann->x) {
89 // FreeM (ann->x);
90 //}
91
92 if (ann->d) {
93 FreeM(ann->d);
94 }
95
96 /* We must clear all allocations in the list */
97 if (ann->c) {
98 ClearList(ann->c);
99 ann->c = NULL;
100 }
101
102 FreeM(ann);
103 return 0;
104 }
105
106
107 //==========================================================
108 // ANN_AddHiddenLayer()
109 //----------------------------------------------------------
110 /// Add a hidden layer with n_nodes
ANN_AddHiddenLayer(ANN * ann,int n_nodes)111 int ANN_AddHiddenLayer(ANN * ann, int n_nodes)
112 {
113 #ifdef ANN_DBUG
114 message("Adding Hidden layer with %d nodes", n_nodes);
115 #endif
116
117 LISTITEM *item = LastListItem(ann->c);
118 if (item) {
119 Layer *p = (Layer *) item->obj;
120 ANN_AddLayer(ann, p->n_outputs, n_nodes, p->y);
121 } else {
122 ANN_AddLayer(ann, ann->n_inputs, n_nodes, ann->x);
123 }
124 return 0;
125 }
126
127 //==========================================================
128 // ANN_AddRBFHiddenLayer()
129 //----------------------------------------------------------
130 /// Add an RBF layer with n_nodes
ANN_AddRBFHiddenLayer(ANN * ann,int n_nodes)131 int ANN_AddRBFHiddenLayer(ANN * ann, int n_nodes)
132 {
133 #ifdef ANN_DBUG
134 message("Adding Hidden layer with %d nodes", n_nodes);
135 #endif
136 LISTITEM *item = LastListItem(ann->c);
137 if (item) {
138 Layer *p = (Layer *) item->obj;
139 ANN_AddRBFLayer(ann, p->n_outputs, n_nodes, p->y);
140 } else {
141 ANN_AddRBFLayer(ann, ann->n_inputs, n_nodes, ann->x);
142 }
143 return 0;
144 }
145
146
147
148 //==========================================================
149 // ANN_AddLayer()
150 //----------------------------------------------------------
151 /// Low-level code to add a weighted sum layer
ANN_AddLayer(ANN * ann,int n_inputs,int n_outputs,real * x)152 Layer *ANN_AddLayer(ANN * ann, int n_inputs, int n_outputs, real * x)
153 {
154 Layer *l = NULL;
155 if ((x == NULL) && (ann->c->n)) {
156 Swarning
157 ("Layer connects to null but layer list is not empty\n");
158 }
159
160
161 if (!(l = AllocM(Layer, 1))) {
162 Serror("Could not allocate layer structure\n");
163 return NULL;
164 }
165
166 assert(n_inputs > 0);
167 assert(n_outputs > 0);
168
169 l->n_inputs = n_inputs;
170 l->n_outputs = n_outputs;
171 l->x = x;
172 l->a = ann->a;
173 l->zeta = ann->zeta;
174 l->lambda = ann->lambda;
175 l->forward = &ANN_CalculateLayerOutputs;
176 l->backward = &ANN_Backpropagate;
177 l->f = &htan;
178 l->f_d = &htan_d;
179 //l->f = &dtan;
180 // l->f_d = &dtan_d;
181 l->batch_mode = false;
182 if (!(l->y = AllocM(real, n_outputs))) {
183 Serror("Could not allocate layer outputs\n");
184 ANN_FreeLayer(l);
185 return NULL;
186 }
187 int i;
188 for (i=0; i<n_outputs; i++) {
189 l->y[i] = 0.0;
190 }
191
192 if (!(l->z = AllocM(real, n_outputs))) {
193 Serror("Could not allocate layer activations\n");
194 ANN_FreeLayer(l);
195 return NULL;
196 }
197 for (i=0; i<n_outputs; i++) {
198 l->z[i] = 0.0;
199 }
200 if (!(l->d = AllocM(real, n_inputs + 1 /*bias */ ))) {
201 Serror("Could not allocate layer outputs\n");
202 ANN_FreeLayer(l);
203 return NULL;
204 }
205 for (i=0; i<n_inputs+1; i++) {
206 l->d[i] = 0.0;
207 }
208
209 if (!
210 (l->c =
211 AllocM(Connection, (n_inputs + 1 /*bias */ ) * n_outputs))) {
212 Serror("Could not allocate connections\n");
213 ANN_FreeLayer(l);
214 return NULL;
215 }
216
217 l->rbf = NULL;
218
219 real bound = 2.0f / sqrt((real) n_inputs);
220 for (i = 0; i < n_inputs + 1 /*bias */ ; i++) {
221 Connection *c = &l->c[i * n_outputs];
222 for (int j = 0; j < n_outputs; j++) {
223 c->w = (urandom() - 0.5f)* bound;;
224 c->c = 1;
225 c->e = 0.0f;
226 c->dw = 0.0f;
227 c->v = 1.0;
228 c++;
229 }
230 }
231 ListAppend(ann->c, (void *) l, &ANN_FreeLayer);
232 return l;
233 }
234
235
236 //==========================================================
237 // ANN_AddRBFLayer()
238 //----------------------------------------------------------
239 /// Low-level code to add an RBF layer
ANN_AddRBFLayer(ANN * ann,int n_inputs,int n_outputs,real * x)240 Layer *ANN_AddRBFLayer(ANN * ann, int n_inputs, int n_outputs, real * x)
241 {
242 Layer *l = NULL;
243 if ((x == NULL) && (ann->c->n)) {
244 Swarning
245 ("Layer connects to null and layer list not empty\n");
246 }
247
248 if (!(l = AllocM(Layer, 1))) {
249 Serror("Could not allocate layer structure\n");
250 return NULL;
251 }
252
253 assert(n_inputs > 0);
254 assert(n_outputs > 0);
255
256 l->n_inputs = n_inputs;
257 l->n_outputs = n_outputs;
258 l->x = x;
259 l->a = ann->a;
260 l->forward = &ANN_RBFCalculateLayerOutputs;
261 l->backward = &ANN_RBFBackpropagate;
262 l->f = &Exp;
263 l->f_d = &Exp_d;
264 l->batch_mode = false;
265
266 if (!(l->y = AllocM(real, n_outputs))) {
267 Serror("Could not allocate layer outputs\n");
268 ANN_FreeLayer(l);
269 return NULL;
270 }
271
272 if (!(l->z = AllocM(real, n_outputs))) {
273 Serror("Could not allocate layer activations\n");
274 ANN_FreeLayer(l);
275 return NULL;
276 }
277
278 if (!(l->d = AllocM(real, n_inputs + 1 /*bias */ ))) {
279 Serror("Could not allocate layer outputs\n");
280 ANN_FreeLayer(l);
281 return NULL;
282 }
283
284 if (!
285 (l->rbf =
286 AllocM(RBFConnection,
287 (n_inputs + 1 /*bias */ ) * n_outputs))) {
288 Serror("Could not allocate connections\n");
289 ANN_FreeLayer(l);
290 return NULL;
291 }
292
293 l->c = NULL;
294
295 real bound = 2.0f / sqrt((real) n_inputs);
296 for (int i = 0; i < n_inputs + 1 /*bias */ ; i++) {
297 RBFConnection *c = &l->rbf[i * n_outputs];
298 for (int j = 0; j < n_outputs; j++) {
299 c->w = (urandom() - 0.5f) * bound;;
300 c->m = (urandom() - 0.5f) * 2.0f;
301 c++;
302 }
303 }
304 ListAppend(ann->c, (void *) l, &ANN_FreeLayer);
305 return l;
306 }
307
308
309 //==========================================================
310 // ANN_FreeLayer()
311 //----------------------------------------------------------
312 /// Free this layer - low level
ANN_FreeLayer(void * l)313 void ANN_FreeLayer(void *l)
314 {
315 ANN_FreeLayer((Layer *) l);
316 }
317
318 //==========================================================
319 // ANN_FreeLayer()
320 //----------------------------------------------------------
321 /// Free this layer - low level
ANN_FreeLayer(Layer * l)322 void ANN_FreeLayer(Layer * l)
323 {
324 FreeM(l->y);
325 if (l->z) {
326 FreeM(l->z);
327 }
328 if (l->c) {
329 FreeM(l->c);
330 }
331 if (l->rbf) {
332 FreeM(l->rbf);
333 }
334 FreeM(l->d);
335 FreeM(l);
336
337 }
338
339 //==========================================================
340 // ANN_Init()
341 //----------------------------------------------------------
342 /// Initialise neural network.
343
344 /// Call this function after you have added all the layers.
345 /// It adds an extra output layer.
ANN_Init(ANN * ann)346 int ANN_Init(ANN * ann)
347 {
348 // Add output layer
349 LISTITEM *item = LastListItem(ann->c);
350 Layer *l = NULL;
351 #ifdef ANN_DBUG
352 message("Initialising");
353 #endif
354 if (item) {
355 Layer *p = (Layer *) item->obj;
356 l = ANN_AddLayer(ann, p->n_outputs, ann->n_outputs, p->y);
357 } else {
358 l = ANN_AddLayer(ann, ann->n_inputs, ann->n_outputs,
359 ann->x);
360 }
361 if (l == NULL) {
362 Serror("Could not create final layer\n");
363 DeleteANN(ann);
364 return -1;
365 }
366 ann->y = l->y;
367 l->f = &linear;
368 l->f_d = &linear_d;
369 // ann->t = l->t;
370 return 0;
371 }
372
373
374
375 //==========================================================
376 // ANN_Reset()
377 //----------------------------------------------------------
378 /// Resets the eligbility traces and batch updates.
ANN_Reset(ANN * ann)379 void ANN_Reset(ANN * ann)
380 {
381 LISTITEM *p = FirstListItem(ann->c);
382
383 while (p) {
384 Layer *l = (Layer *) p->obj;
385 for (int i = 0; i < l->n_inputs + 1 /* bias */; i++) {
386 Connection *c = &l->c[i * l->n_outputs];
387 for (int j = 0; j < l->n_outputs; j++) {
388 c->e = 0.0;
389 c->dw = 0.0;
390 c++;
391 }
392 }
393 p = NextListItem (ann->c);
394 }
395 }
396
397
398 //==========================================================
399 // ANN_Input()
400 //----------------------------------------------------------
401 /// Give an input vector to the neural network.
402
403 /// Calculate a new output given the input.
404 /// If the vector length is incorrect, you will have
405 /// trouble.
ANN_Input(ANN * ann,real * x)406 real ANN_Input(ANN * ann, real * x)
407 {
408 LISTITEM *p = FirstListItem(ann->c);
409 Layer *first_layer = (Layer *) p->obj;
410 ann->x = x;
411 first_layer->x = x; // Setup input of first layer
412 // printf ("II: %f\n", ann->x[0]);
413 while (p) {
414 Layer *current_layer = (Layer *) p->obj;
415 // printf ("\tIII: %f\n", current_layer->x[0]);
416 current_layer->forward(current_layer, false);
417 p = NextListItem(ann->c);
418 }
419 return 0.0f;
420 }
421
422 //==========================================================
423 // ANN_StochasticInput()
424 //----------------------------------------------------------
425 /// Stochastically generate an output, depending on parameter
426 /// distributions.
427 /// This is an option for people that understand what they
428 /// are doing.
ANN_StochasticInput(ANN * ann,real * x)429 real ANN_StochasticInput(ANN * ann, real * x)
430 {
431 LISTITEM *p = FirstListItem(ann->c);
432 Layer *first_layer = (Layer *) p->obj;
433 ann->x = x;
434 first_layer->x = x; // Setup input of first layer
435 // printf ("II: %f\n", ann->x[0]);
436 while (p) {
437 Layer *current_layer = (Layer *) p->obj;
438 // printf ("\tIII: %f\n", current_layer->x[0]);
439 current_layer->forward(current_layer, true);
440 p = NextListItem(ann->c);
441 }
442 return 0.0f;
443 }
444
445 //==========================================================
446 // ANN_CalculateLayerOutputs()
447 //----------------------------------------------------------
448 /// Calculate layer outputs
ANN_CalculateLayerOutputs(Layer * current_layer,bool stochastic)449 void ANN_CalculateLayerOutputs(Layer * current_layer, bool stochastic)
450 {
451 int i, j;
452 int n_inputs = current_layer->n_inputs;
453 int n_outputs = current_layer->n_outputs;
454 real *x = current_layer->x;
455 real *y = current_layer->y;
456 real *z = current_layer->z;
457 Connection *c;
458
459 for (j = 0; j < n_outputs; j++) {
460 z[j] = 0.0f;
461 }
462 c = current_layer->c;
463 if (stochastic) {
464 for (i = 0; i < n_inputs; i++) {
465 for (j = 0; j < n_outputs; j++) {
466 // using uniform bounded..
467 real w = c->w + (urandom()-0.5f)*c->v ;
468 z[j] += x[i] * w;
469 c++;
470 }
471 }
472
473 // bias
474 for (j = 0; j < n_outputs; j++) {
475 real w = c->w + (urandom()-0.5f)*c->v ;
476 z[j] += w;
477 c++;
478 }
479 } else {
480 for (i = 0; i < n_inputs; i++) {
481 for (j = 0; j < n_outputs; j++) {
482 z[j] += x[i] * c->w;
483 c++;
484 }
485 }
486
487 // bias
488 for (j = 0; j < n_outputs; j++) {
489 z[j] += c->w;
490 c++;
491 }
492 }
493
494 for (j = 0; j < n_outputs; j++) {
495 y[j] = current_layer->f(z[j]);
496 }
497 }
498
499 //==========================================================
500 // ANN_RBFCalculateLayerOutputs()
501 //----------------------------------------------------------
502 /// Calculate layer outputs
ANN_RBFCalculateLayerOutputs(Layer * current_layer,bool stochastic)503 void ANN_RBFCalculateLayerOutputs(Layer * current_layer, bool stochastic)
504 {
505 int i, j;
506 int n_inputs = current_layer->n_inputs;
507 int n_outputs = current_layer->n_outputs;
508 real *x = current_layer->x;
509 real *y = current_layer->y;
510 real *z = current_layer->z;
511 RBFConnection *c;
512
513
514 for (j = 0; j < n_outputs; j++) {
515 z[j] = 0.0f;
516 }
517
518 c = current_layer->rbf;
519 for (i = 0; i < n_inputs; i++) {
520 real in = x[i];
521 for (j = 0; j < n_outputs; j++, c++) {
522 real o = (in - c->m) * c->w;
523 z[j] += o * o;
524 }
525 }
526
527 for (j = 0; j < n_outputs; j++) {
528 z[j] = -0.5f * z[j];
529 y[j] = current_layer->f(z[j]);
530 }
531 }
532
533
534 //==========================================================
535 // ANN_Train() simple MSE training
536 //----------------------------------------------------------
537
538 /// Perform mean square error training, where the aim is to minimise
539 /// the cost function \f$\sum_i |f(x_i)-t_i|^2\f$, where \f$x_i\f$ is
540 /// input data, \f$f(\cdot)\f$ is the mapping performed by the neural
541 /// network, \f$t_i\f$ is the desired output and \f$i\f$ denotes the example
542 /// index. Under mild assumptions, this is equivalent to minimising
543 /// \f$E\{|f(X)-T|^2\}\f$, the expected value of the squared error.
ANN_Train(ANN * ann,real * x,real * t)544 real ANN_Train(ANN * ann, real * x, real * t)
545 {
546 LISTITEM *p = LastListItem(ann->c);
547 Layer *l = (Layer *) p->obj;
548 real sum = 0.0f;
549 int j;
550
551 ANN_Input(ann, x);
552
553 for (j = 0; j < ann->n_outputs; j++) {
554 real f = l->f_d(ann->y[j]);
555 real e = t[j] - ann->y[j];
556 ann->error[j] = e;
557 ann->d[j] = e * f;
558 sum += e * e;
559 }
560
561 l->backward(p, ann->d, ann->eligibility_traces, 0.0);
562
563 return sum;
564 }
565
566
567 //==========================================================
568 // ANN_Delta_Train() Train with custom cost
569 //----------------------------------------------------------
570 /// \brief Minimise a custom cost function.
571
572 /// The argument delta is a the derivative of the cost function with
573 /// respect to the neural network outputs. In this case you must call
574 /// ANN_Input() yourself. As an example, to use MSE cost with
575 /// ANN_Delta_Train(), you should call ANN_Input() with your data,
576 /// call ANN_GetOutput() to take a look at the outputs and then call
577 /// ANN_DeltaTrain() with a real vector delta equal to the target
578 /// vector minus the ANN output vector. The argument TD is useful if
579 /// you want to separate the calculation of the derivative of the
580 /// output with respect to the parameters from the derivative the cost
581 /// function with respect to the output. This is done in reinforcement
582 /// learning with eligibility traces for example, where the cost
583 /// function depends upon previous outputs.
ANN_Delta_Train(ANN * ann,real * delta,real TD)584 real ANN_Delta_Train(ANN * ann, real* delta, real TD)
585 {
586 LISTITEM *p = LastListItem(ann->c);
587 Layer *l = (Layer *) p->obj;
588 real sum = 0.0f;
589 int j;
590 //ANN_Input(ann, x);
591 for (j = 0; j < ann->n_outputs; j++) {
592 real f = l->f_d(ann->y[j]);
593 real e = delta[j];
594 ann->error[j] = e;
595 ann->d[j] = e * f;
596 sum += e * e;
597 }
598
599 l->backward(p, ann->d, ann->eligibility_traces, TD);
600
601 return sum;
602 }
603
604
605
606 //==========================================================
607 // ANN_Backpropagate
608 //----------------------------------------------------------
609 /// d are the derivatives at the outputs.
ANN_Backpropagate(LISTITEM * p,real * d,bool use_eligibility,real TD)610 real ANN_Backpropagate(LISTITEM * p, real * d, bool use_eligibility, real TD)
611 {
612 int i, j;
613 real f;
614 real a;
615 Layer *l = (Layer *) p->obj;
616 LISTITEM *back = p->prev;
617 Layer *back_layer = NULL;
618 a = l->a;
619 // message ("backing with in: %d",l->x);
620 if (back) {
621 //message ("and to prev");
622 back_layer = (Layer *) back->obj;
623 for (i = 0; i < l->n_inputs; i++) {
624 real der = 0.0f;
625
626 Connection *c = &l->c[i * l->n_outputs];
627 for (j = 0; j < l->n_outputs; j++) {
628 der += c->w * d[j];
629 c++;
630 }
631 f = back_layer->f_d(l->x[i]);
632 der*=f;
633 l->d[i] = der;
634 }
635
636 /* bias */
637 i = l->n_inputs;
638 l->d[i] = 0.0f;
639 Connection *c = &l->c[i * l->n_outputs];
640 for (j = 0; j < l->n_outputs; j++) {
641 l->d[i] += c->w * d[j];
642 c++;
643 }
644 f = back_layer->f_d(1.0f);
645 l->d[i] = l->d[i] * f;
646
647 back_layer->backward(back, l->d, use_eligibility, TD);
648 }
649 //update weights
650 for (i = 0; i < l->n_inputs; i++) {
651 Connection *c = &l->c[i * l->n_outputs];
652 real dx = a * l->x[i];
653 if (l->batch_mode) {
654 for (j = 0; j < l->n_outputs; j++) {
655 real delta;
656 if (use_eligibility) {
657 c->e = c->e * l->lambda + l->x[i]* d[j];
658 delta = a * c->e * TD; //better?
659 c->v += (1.0f - l->zeta)*c->v+(l->zeta)*delta*delta;
660 } else {
661 delta = dx * d[j];
662 }
663 c->dw += delta;
664 c->v = (1.0f - l->zeta)*c->v + (l->zeta)*fabs(delta);
665 if (c->v < 0.01f) c->v = 0.01f;
666 c++;
667 }
668 } else {
669 for (j = 0; j < l->n_outputs; j++) {
670 real delta;
671 if (use_eligibility) {
672 c->e = c->e * l->lambda + l->x[i] * d[j];
673 delta = a * c->e * TD;
674 } else {
675 delta = dx * d[j];
676 }
677 c->w += delta;
678 delta /= a;
679 c->v = (1.0f - l->zeta)*c->v + (l->zeta)*fabs(delta);
680 //printf("%f\n", c->v);
681 if (c->v < 0.01f) c->v = 0.01f;
682 c++;
683 }
684 }
685 }
686 // update bias weight
687 {
688 Connection *c = &l->c[l->n_inputs * l->n_outputs];
689 if (l->batch_mode) {
690 for (j = 0; j < l->n_outputs; j++) {
691 real delta;
692 if (use_eligibility) {
693 c->e = c->e * l->lambda + d[j];
694 delta = a * c->e * TD;
695 } else {
696 delta = a * d[j];
697 }
698 c->dw += delta;
699 c->v = (1.0 - l->zeta)*c->v + (l->zeta)*fabs(delta);
700 if (c->v < 0.01f) c->v = 0.01f;
701 c++;
702 }
703 } else {
704 for (j = 0; j < l->n_outputs; j++) {
705 real delta;
706 if (use_eligibility) {
707 c->e = c->e * l->lambda + d[j];
708 delta = a * c->e * TD; //better?
709 } else {
710 delta = a * d[j];
711 }
712 c->w += delta;
713 c->v = (1.0f - l->zeta)*c->v + (l->zeta)*fabs(delta);
714 if (c->v < 0.01f) c->v = 0.01f;
715 c++;
716 }
717 }
718 }
719 return 0.0f;
720 }
721
722 //==========================================================
723 // ANN_RBFBackpropagate
724 //----------------------------------------------------------
725 /// Backpropagation for an RBF layer.
726 /// \bug Currently RBF layers lack the functionality of sigmoid ones.
ANN_RBFBackpropagate(LISTITEM * p,real * d,bool use_eligibility,real TD)727 real ANN_RBFBackpropagate(LISTITEM * p, real * d, bool use_eligibility, real TD)
728 {
729 int i, j;
730 real f;
731 real a;
732 Layer *l = (Layer *) p->obj;
733 LISTITEM *back = p->prev;
734 Layer *back_layer = NULL;
735 a = l->a;
736
737 if (back) {
738 back_layer = (Layer *) back->obj;
739 for (i = 0; i < l->n_inputs; i++) {
740 l->d[i] = 0.0f;
741 RBFConnection *c = &l->rbf[i * l->n_outputs];
742 for (j = 0; j < l->n_outputs; j++) {
743 real dx = l->x[i] - c->m;
744 real dm = d[j] * dx * c->w * c->w;
745 l->d[j] -= dm;
746 c++;
747 }
748 f = back_layer->f_d(l->x[i]);
749 l->d[i] = l->d[i] * f;
750 }
751 back_layer->backward(back, l->d, use_eligibility, TD);
752 }
753
754 return 0.0f;
755 //update weights
756 for (i = 0; i < l->n_inputs; i++) {
757 RBFConnection *c = &l->rbf[i * l->n_outputs];
758 real dx = l->x[i] - c->m;
759 for (j = 0; j < l->n_outputs; j++) {
760 real dy = d[j];
761 real dx2 = a * dy * dx * c->w;
762 real dm = dx2 * c->w;
763 real dw = dx2 * dx;
764 c->m += dm;
765 c->w += dw;
766 c++;
767 }
768 }
769 return 0.0f;
770 }
771
772 /// Perform batch adaptation
ANN_LayerBatchAdapt(Layer * l)773 void ANN_LayerBatchAdapt(Layer * l)
774 {
775 int i, j;
776
777 if (l->batch_mode == false) {
778 Serror("Batch adapt yet not in batch mode!");
779 }
780 //update weights
781 for (i = 0; i < l->n_inputs; i++) {
782 Connection *c = &l->c[i * l->n_outputs];
783 for (j = 0; j < l->n_outputs; j++) {
784 c->w += c->dw;
785 c++;
786 }
787 }
788 // update bias weight
789 {
790 Connection *c = &l->c[l->n_inputs * l->n_outputs];
791 for (j = 0; j < l->n_outputs; j++) {
792 c->w += c->dw;
793 c++;
794 }
795 }
796 }
797
798 //==========================================================
799 // ANN_Test()
800 //----------------------------------------------------------
801 /// Given an input and test pattern, return the MSE between the network's output and the test pattern.
ANN_Test(ANN * ann,real * x,real * t)802 real ANN_Test(ANN * ann, real * x, real * t)
803 {
804 //LISTITEM *p = LastListItem(ann->c);
805 //Layer *l = (Layer *) p->obj;
806 real sum = 0.0f;
807 int j;
808 ANN_Input(ann, x);
809
810 for (j = 0; j < ann->n_outputs; j++) {
811 //real f = l->f_d(ann->y[j]);
812 real e = t[j] - ann->y[j];
813 ann->error[j] = e;
814 ann->d[j] =0.0;// e * f;
815 sum += e * e;
816 }
817 return sum;
818 }
819
820 //==========================================================
821 // ANN_GetOutput()
822 //----------------------------------------------------------
823 /// Get the output for the current input.
ANN_GetOutput(ANN * ann)824 real *ANN_GetOutput(ANN * ann)
825 {
826 return ann->y;
827 }
828
829 //==========================================================
830 // ANN_GetError()
831 //----------------------------------------------------------
832 /// Get the error for the current input/output pair.
ANN_GetError(ANN * ann)833 real ANN_GetError(ANN * ann)
834 {
835 real sum = 0.0;
836 for (int i=0; i<ann->n_outputs; i++) {
837 real e = ann->error[i];
838 sum += e*e;
839 }
840 return (real) sqrt(sum);
841 }
842
843 //==========================================================
844 // ANN_GetErrorVector()
845 //----------------------------------------------------------
846 /// Return the error vector for pattern.
ANN_GetErrorVector(ANN * ann)847 real* ANN_GetErrorVector(ANN * ann)
848 {
849 return ann->error;
850 }
851
852 //==========================================================
853 // ANN_SetLearningRate()
854 //----------------------------------------------------------
855 /// Set the learning rate to a
ANN_SetLearningRate(ANN * ann,real a)856 void ANN_SetLearningRate(ANN * ann, real a)
857 {
858 LISTITEM *c;
859
860 ann->a = a;
861 c = FirstListItem(ann->c);
862 while (c) {
863 Layer *l = (Layer *) c->obj;
864 l->a = a;
865 c = NextListItem(ann->c);
866 }
867 }
868 //==========================================================
869 // ANN_SetLambda()
870 //----------------------------------------------------------
871 /// Set lambda, eligibility decay.
ANN_SetLambda(ANN * ann,real lambda)872 void ANN_SetLambda(ANN * ann, real lambda)
873 {
874 LISTITEM *c;
875
876 ann->lambda = lambda;
877 c = FirstListItem(ann->c);
878 while (c) {
879 Layer *l = (Layer *) c->obj;
880 l->lambda = lambda;
881 c = NextListItem(ann->c);
882 }
883 }
884
885 //==========================================================
886 // ANN_SetZeta()
887 //----------------------------------------------------------
888 /// Set zeta, parameter variance smoothing. Useful for
889 /// ANN_StochasticInput()
ANN_SetZeta(ANN * ann,real zeta)890 void ANN_SetZeta(ANN * ann, real zeta)
891 {
892 LISTITEM *c;
893
894 ann->zeta = zeta;
895 c = FirstListItem(ann->c);
896 while (c) {
897 Layer *l = (Layer *) c->obj;
898 l->zeta = zeta;
899 c = NextListItem(ann->c);
900 }
901 }
902 //==========================================================
903 // ANN_SetBatchMode
904 //----------------------------------------------------------
905 /// Set batch updates.
ANN_SetBatchMode(ANN * ann,bool batch)906 void ANN_SetBatchMode(ANN * ann, bool batch)
907 {
908 LISTITEM *c;
909
910 ann->batch_mode = batch;
911 c = FirstListItem(ann->c);
912 while (c) {
913 Layer *l = (Layer *) c->obj;
914 l->batch_mode = batch;
915 c = NextListItem(ann->c);
916 }
917 }
918
919 //==========================================================
920 // ANN_BatchAdapt
921 //----------------------------------------------------------
922 /// Adapt the parameters after a series of patterns has been seen.
ANN_BatchAdapt(ANN * ann)923 void ANN_BatchAdapt(ANN * ann)
924 {
925 LISTITEM *c;
926
927 c = FirstListItem(ann->c);
928 while (c) {
929 Layer *l = (Layer *) c->obj;
930 ANN_LayerBatchAdapt(l);
931 c = NextListItem(ann->c);
932 }
933 }
934
935
936
937 //==========================================================
938 // ANN_ShowWeights()
939 //----------------------------------------------------------
940 /// Dump the weights on stdout.
ANN_ShowWeights(ANN * ann)941 real ANN_ShowWeights(ANN * ann)
942 {
943 LISTITEM *c;
944 real sum = 0.0f;
945 c = FirstListItem(ann->c);
946 while (c) {
947 Layer *l = (Layer *) c->obj;
948 sum += ANN_LayerShowWeights(l);
949 c = NextListItem(ann->c);
950 }
951 return sum;
952 }
953
954 //==========================================================
955 // ANN_LayerShowWeights()
956 //----------------------------------------------------------
957 /// Dump the weights of a particular layer on stdout.
ANN_LayerShowWeights(Layer * l)958 real ANN_LayerShowWeights(Layer * l)
959 {
960 int i, j;
961 Connection *c = l->c;
962 real sum = 0.0f;
963 for (i = 0; i < l->n_inputs + 1 /*bias */ ; i++) {
964 for (j = 0; j < l->n_outputs; j++) {
965 sum += (c->w) * (c->w); //printf ("%f ", c->w);
966 printf("%f ", c->w);
967 c++;
968 }
969 }
970 // printf ("%f ", sum);
971 return sum;
972 }
973
974
975 //==========================================================
976 // ANN_ShowInputs()
977 //----------------------------------------------------------
978 /// Dump inputs to all layers on stdout.
ANN_ShowInputs(ANN * ann)979 real ANN_ShowInputs(ANN * ann)
980 {
981 LISTITEM *c;
982 real sum = 0.0f;
983 c = FirstListItem(ann->c);
984 while (c) {
985 Layer *l = (Layer *) c->obj;
986 sum += ANN_LayerShowInputs(l);
987 c = NextListItem(ann->c);
988 }
989 return sum;
990 }
991
992 //==========================================================
993 // ANN_LayerShowInputs()
994 //----------------------------------------------------------
995 /// Dump inputs to a particular layer on stdout.
ANN_LayerShowInputs(Layer * l)996 real ANN_LayerShowInputs(Layer * l)
997 {
998 int i;
999 real sum = 0.0f;
1000 for (i = 0; i < l->n_inputs; i++) {
1001 printf("#%f ", l->x[i]);
1002 }
1003 printf("-->");
1004 for (i = 0; i < l->n_outputs; i++) {
1005 printf("#(%f)%f ", l->f(l->z[i]), l->y[i]);
1006 }
1007
1008 printf("\n");
1009 return sum;
1010 }
1011
1012
1013 //==========================================================
1014 // ANN_ShowOutputs()
1015 //----------------------------------------------------------
1016 /// Dump outputs to stdout
ANN_ShowOutputs(ANN * ann)1017 void ANN_ShowOutputs(ANN * ann)
1018 {
1019 int i;
1020
1021 for (i = 0; i < ann->n_outputs; i++) {
1022 printf("%f ", ann->y[i]);
1023 }
1024 printf("\n");
1025 }
1026
1027
1028
1029 //==========================================================
1030 // ANN_SetOutputsToLinear()
1031 //----------------------------------------------------------
1032 /// Set outputs to linear
ANN_SetOutputsToLinear(ANN * ann)1033 void ANN_SetOutputsToLinear(ANN * ann)
1034 {
1035 LISTITEM *c;
1036 c = LastListItem(ann->c);
1037 if (c) {
1038 Layer *l = (Layer *) c->obj;
1039 l->f = &linear;
1040 l->f_d = &linear_d;
1041 } else {
1042 Serror("Could not set outputs to linear\n");
1043 }
1044 }
1045
1046 //==========================================================
1047 // ANN_SetOutputsToTanH()
1048 //----------------------------------------------------------
1049 /// Set outputs to hyperbolic tangent.
ANN_SetOutputsToTanH(ANN * ann)1050 void ANN_SetOutputsToTanH(ANN * ann)
1051 {
1052 LISTITEM *c;
1053 c = LastListItem(ann->c);
1054 if (c) {
1055 Layer *l = (Layer *) c->obj;
1056 l->f = &htan;
1057 l->f_d = &htan_d;
1058 } else {
1059 Serror("Could not set outputs to TanH\n");
1060 }
1061 }
1062
1063
1064 //==========================================================
1065 // Exp()
1066 //----------------------------------------------------------
1067 /// Exponential hook
Exp(real x)1068 real Exp(real x)
1069 {
1070 return (real) exp(x);
1071 }
1072
1073 //==========================================================
1074 // Exp_d()
1075 //----------------------------------------------------------
1076 /// Exponential derivative hook
Exp_d(real x)1077 real Exp_d(real x)
1078 {
1079 return x;
1080 }
1081
1082 //==========================================================
1083 // htan()
1084 //----------------------------------------------------------
1085 /// Hyperbolic tangent hook
htan(real x)1086 real htan(real x)
1087 {
1088 return (real) tanh(x);
1089 }
1090
1091 //==========================================================
1092 // htan_d()
1093 //----------------------------------------------------------
1094 /// Hyperbolic tangent derivative hook
htan_d(real x)1095 real htan_d(real x)
1096 {
1097 real f = (real) tanh(x);
1098 return (real) (1.0 - f * f);
1099 }
1100
1101 //==========================================================
1102 // dtan()
1103 //----------------------------------------------------------
1104 /// Discrete htan hook
dtan(real x)1105 real dtan(real x)
1106 {
1107 if (x>1.0) {
1108 return 1.0;
1109 } else if (x<1.0) {
1110 return -1.0;
1111 }
1112 return x;
1113 }
1114
1115 //==========================================================
1116 // dtan_d()
1117 //----------------------------------------------------------
1118 /// Discrete htan derivative hook
dtan_d(real x)1119 real dtan_d(real x)
1120 {
1121 if (x>1.0) {
1122 return 0.0;
1123 } else if (x<-1.0) {
1124 return 0.0;
1125 }
1126 return 1.0;
1127 }
1128
1129 //==========================================================
1130 // linear()
1131 //----------------------------------------------------------
1132 /// linear hook
linear(real x)1133 real linear(real x)
1134 {
1135 return x;
1136 }
1137
1138 //==========================================================
1139 // linear_d()
1140 //----------------------------------------------------------
1141 /// linear derivative hook
linear_d(real x)1142 real linear_d(real x)
1143 {
1144 return 1.0f;
1145 }
1146
1147 /// Check that tags match
CheckMatchingToken(const char * tag,StringBuffer * buf,FILE * f)1148 static inline bool CheckMatchingToken (const char* tag, StringBuffer* buf, FILE* f)
1149 {
1150 int l = 1+strlen(tag);
1151 buf = SetStringBufferLength (buf, l);
1152 if (buf==NULL) {
1153 return false;
1154 }
1155 fread(buf->c, sizeof(char), l, f);
1156
1157 if (strcmp(tag,buf->c)) {
1158 fprintf (stderr, "Expected tag <%s>, found <%s>.\n", tag, buf->c);
1159 return false;
1160 }
1161 return true;
1162 }
1163
1164 /// Write a token
WriteToken(const char * tag,FILE * f)1165 static inline void WriteToken (const char* tag, FILE* f)
1166 {
1167 fwrite (tag, sizeof(char), 1+strlen(tag), f);
1168 }
1169
1170 /// Load an ANN from a filename.
LoadANN(char * filename)1171 ANN* LoadANN(char* filename)
1172 {
1173 FILE* f = fopen (filename, "rb");
1174 if (f) {
1175 ANN* ann = LoadANN (f);
1176 fclose (f);
1177 return ann;
1178 }
1179 return NULL;
1180 }
1181 /// Save the ANN to a filename.
SaveANN(ANN * ann,char * filename)1182 int SaveANN(ANN* ann, char* filename)
1183 {
1184 FILE* f = fopen (filename, "wb");
1185 if (f) {
1186 int r = SaveANN (ann, f);
1187 fclose (f);
1188 return r;
1189 }
1190 return -1;
1191 }
1192
1193 /// Load the ANN from a C file handle.
LoadANN(FILE * f)1194 ANN* LoadANN(FILE* f)
1195 {
1196 if (f==NULL) {
1197 return NULL;
1198 }
1199 StringBuffer* rtag = NewStringBuffer (256);
1200 CheckMatchingToken("VSOUND_ANN", rtag, f);
1201 int n_inputs;
1202 int n_outputs;
1203 fread(&n_inputs, sizeof(int), 1, f);
1204 fread(&n_outputs, sizeof(int), 1, f);
1205 ANN* ann = NewANN (n_inputs, n_outputs);
1206 CheckMatchingToken("Layer Data", rtag, f);
1207 int n_layers;
1208 fread(&n_layers, sizeof(int), 1, f);
1209 for (int i=0; i<n_layers-1; i++) {
1210 int layer_type;
1211 CheckMatchingToken("TYPE", rtag, f);
1212 fread(&layer_type, sizeof(int), 1, f);
1213 int nhu;
1214 CheckMatchingToken("UNITS", rtag, f);
1215 fread(&nhu, sizeof(int), 1, f);
1216 if (layer_type==0) {
1217 ANN_AddHiddenLayer(ann, nhu);
1218 } else {
1219 ANN_AddRBFHiddenLayer(ann, nhu);
1220 }
1221 }
1222 {
1223 int layer_type =0;
1224 ANN_Init(ann);
1225 CheckMatchingToken("Output Type", rtag, f);
1226 fread(&layer_type, sizeof(int), 1, f);
1227 if (layer_type==0) {
1228 ANN_SetOutputsToLinear(ann);
1229 } else {
1230 ANN_SetOutputsToTanH(ann);
1231 }
1232 }
1233
1234 LISTITEM* list_item = FirstListItem(ann->c);
1235 while (list_item) {
1236 Layer* l = (Layer*) list_item->obj;
1237 CheckMatchingToken("Connections", rtag, f);
1238 int size = (l->n_inputs + 1 /*bias*/) * l->n_outputs;
1239 fread(l->c, size, sizeof(Connection), f);
1240 list_item = NextListItem (ann->c);
1241 }
1242 CheckMatchingToken("END", rtag, f);
1243
1244 FreeStringBuffer (&rtag);
1245 return ann;
1246 }
1247
1248 /// Save the ANN to a C file handle.
SaveANN(ANN * ann,FILE * f)1249 int SaveANN(ANN* ann, FILE* f)
1250 {
1251 if (f==NULL) {
1252 return -1;
1253 }
1254
1255 StringBuffer* rtag = NewStringBuffer (256);
1256
1257 WriteToken("VSOUND_ANN", f);
1258 fwrite(&ann->n_inputs, sizeof(int), 1, f);
1259 fwrite(&ann->n_outputs, sizeof(int), 1, f);
1260 WriteToken("Layer Data", f);
1261 int n_layers = 0;
1262 LISTITEM* list_item = FirstListItem(ann->c);
1263 while (list_item) {
1264 n_layers++;
1265 list_item = NextListItem (ann->c);
1266 }
1267 fwrite(&n_layers, sizeof(int), 1, f);
1268 list_item = FirstListItem(ann->c);
1269 for (int i=0; i<n_layers-1; i++) {
1270 Layer* l = (Layer*) list_item->obj;
1271
1272 int layer_type = 0;
1273 WriteToken("TYPE", f);
1274 fwrite(&layer_type, sizeof(int), 1, f);
1275
1276 int nhu = l->n_outputs;
1277 WriteToken("UNITS", f);
1278 fwrite(&nhu, sizeof(int), 1, f);
1279 list_item = NextListItem (ann->c);
1280 }
1281 WriteToken("Output Type", f);
1282 {
1283 int layer_type = 0;
1284 LISTITEM *c;
1285 c = LastListItem(ann->c);
1286 if (c) {
1287 Layer *l = (Layer *) c->obj;
1288 if (l->f==&linear) {
1289 layer_type = 0;
1290 } else {
1291 layer_type = 1;
1292 }
1293 }
1294 fwrite(&layer_type, sizeof(int), 1, f);
1295 }
1296 list_item = FirstListItem(ann->c);
1297 while(list_item) {
1298 Layer* l = (Layer*) list_item->obj;
1299 WriteToken("Connections", f);
1300 int size = (l->n_inputs + 1 /*bias*/) * l->n_outputs;
1301 fwrite(l->c, size, sizeof(Connection), f);
1302 list_item = NextListItem(ann->c);
1303 }
1304 WriteToken("END", f);
1305
1306 FreeStringBuffer (&rtag);
1307 return 0;
1308 }
1309