XCSF 1.4.8
XCSF learning classifier system
Loading...
Searching...
No Matches
neural_layer_lstm.c
Go to the documentation of this file.
1/*
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation, either version 3 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 */
15
26#include "neural_layer_lstm.h"
27#include "blas.h"
28#include "neural_activations.h"
30#include "sam.h"
31#include "utils.h"
32
33#define N_MU (6)
34
46
51static void
53{
54 l->n_weights = l->uf->n_weights + l->ui->n_weights + l->ug->n_weights +
55 l->uo->n_weights + l->wf->n_weights + l->wi->n_weights +
56 l->wg->n_weights + l->wo->n_weights;
57}
58
63static void
65{
66 l->n_biases = l->uf->n_biases + l->ui->n_biases + l->ug->n_biases +
67 l->uo->n_biases + l->wf->n_biases + l->wi->n_biases + l->wg->n_biases +
68 l->wo->n_biases;
69}
70
75static void
77{
78 l->n_active = l->uf->n_active + l->ui->n_active + l->ug->n_active +
79 l->uo->n_active + l->wf->n_active + l->wi->n_active + l->wg->n_active +
80 l->wo->n_active;
81}
82
87static void
89{
91 l->delta = calloc(l->n_outputs, sizeof(double));
92 l->output = calloc(l->n_outputs, sizeof(double));
93 l->state = calloc(l->n_outputs, sizeof(double));
94 l->prev_state = calloc(l->n_outputs, sizeof(double));
95 l->prev_cell = calloc(l->n_outputs, sizeof(double));
96 l->cell = calloc(l->n_outputs, sizeof(double));
97 l->f = calloc(l->n_outputs, sizeof(double));
98 l->i = calloc(l->n_outputs, sizeof(double));
99 l->g = calloc(l->n_outputs, sizeof(double));
100 l->o = calloc(l->n_outputs, sizeof(double));
101 l->c = calloc(l->n_outputs, sizeof(double));
102 l->h = calloc(l->n_outputs, sizeof(double));
103 l->temp = calloc(l->n_outputs, sizeof(double));
104 l->temp2 = calloc(l->n_outputs, sizeof(double));
105 l->temp3 = calloc(l->n_outputs, sizeof(double));
106 l->dc = calloc(l->n_outputs, sizeof(double));
107}
108
113static void
115{
116 l->uf = malloc(sizeof(struct Layer));
117 l->ui = malloc(sizeof(struct Layer));
118 l->ug = malloc(sizeof(struct Layer));
119 l->uo = malloc(sizeof(struct Layer));
120 l->wf = malloc(sizeof(struct Layer));
121 l->wi = malloc(sizeof(struct Layer));
122 l->wg = malloc(sizeof(struct Layer));
123 l->wo = malloc(sizeof(struct Layer));
124}
125
130static void
131free_layer_arrays(const struct Layer *l)
132{
133 free(l->delta);
134 free(l->output);
135 free(l->state);
136 free(l->prev_state);
137 free(l->prev_cell);
138 free(l->cell);
139 free(l->f);
140 free(l->i);
141 free(l->g);
142 free(l->o);
143 free(l->c);
144 free(l->h);
145 free(l->temp);
146 free(l->temp2);
147 free(l->temp3);
148 free(l->dc);
149}
150
155static void
156set_eta(struct Layer *l)
157{
158 l->eta = l->uf->eta;
159 l->ui->eta = l->eta;
160 l->ug->eta = l->eta;
161 l->uo->eta = l->eta;
162 l->wf->eta = l->eta;
163 l->wi->eta = l->eta;
164 l->wg->eta = l->eta;
165 l->wo->eta = l->eta;
166}
167
172static void
173reset_layer_deltas(const struct Layer *l)
174{
175 size_t size = l->n_outputs * sizeof(double);
176 memset(l->wf->delta, 0, size);
177 memset(l->wi->delta, 0, size);
178 memset(l->wg->delta, 0, size);
179 memset(l->wo->delta, 0, size);
180 memset(l->uf->delta, 0, size);
181 memset(l->ui->delta, 0, size);
182 memset(l->ug->delta, 0, size);
183 memset(l->uo->delta, 0, size);
184}
185
191static bool
193{
194 if (layer_mutate_eta(l->uf, l->mu[0])) {
195 set_eta(l);
196 return true;
197 }
198 return false;
199}
200
206static bool
208{
209 const int n = layer_mutate_neurons(l->uf, l->mu[1]);
210 if (n != 0) {
211 layer_add_neurons(l->uf, n);
212 layer_add_neurons(l->ui, n);
213 layer_add_neurons(l->ug, n);
214 layer_add_neurons(l->uo, n);
215 layer_add_neurons(l->wf, n);
216 layer_add_neurons(l->wi, n);
217 layer_add_neurons(l->wg, n);
218 layer_add_neurons(l->wo, n);
219 layer_resize(l->wf, l->uf);
220 layer_resize(l->wi, l->uf);
221 layer_resize(l->wg, l->uf);
222 layer_resize(l->wo, l->uf);
223 l->n_outputs = l->uf->n_outputs;
224 l->out_w = l->n_outputs;
225 l->out_c = 1;
226 l->out_h = 1;
232 return true;
233 }
234 return false;
235}
236
242static bool
244{
245 bool mod = false;
246 mod = layer_mutate_connectivity(l->uf, l->mu[2], l->mu[3]) ? true : mod;
247 mod = layer_mutate_connectivity(l->ui, l->mu[2], l->mu[3]) ? true : mod;
248 mod = layer_mutate_connectivity(l->ug, l->mu[2], l->mu[3]) ? true : mod;
249 mod = layer_mutate_connectivity(l->uo, l->mu[2], l->mu[3]) ? true : mod;
250 mod = layer_mutate_connectivity(l->wf, l->mu[2], l->mu[3]) ? true : mod;
251 mod = layer_mutate_connectivity(l->wi, l->mu[2], l->mu[3]) ? true : mod;
252 mod = layer_mutate_connectivity(l->wg, l->mu[2], l->mu[3]) ? true : mod;
253 mod = layer_mutate_connectivity(l->wo, l->mu[2], l->mu[3]) ? true : mod;
255 return mod;
256}
257
263static bool
265{
266 bool mod = false;
267 mod = layer_mutate_weights(l->uf, l->mu[4]) ? true : mod;
268 mod = layer_mutate_weights(l->ui, l->mu[4]) ? true : mod;
269 mod = layer_mutate_weights(l->ug, l->mu[4]) ? true : mod;
270 mod = layer_mutate_weights(l->uo, l->mu[4]) ? true : mod;
271 mod = layer_mutate_weights(l->wf, l->mu[4]) ? true : mod;
272 mod = layer_mutate_weights(l->wi, l->mu[4]) ? true : mod;
273 mod = layer_mutate_weights(l->wg, l->mu[4]) ? true : mod;
274 mod = layer_mutate_weights(l->wo, l->mu[4]) ? true : mod;
275 return mod;
276}
277
283void
284neural_layer_lstm_init(struct Layer *l, const struct ArgsLayer *args)
285{
286 l->options = layer_args_opt(args);
287 l->function = args->function;
289 l->n_inputs = args->n_inputs;
290 l->n_outputs = args->n_init;
291 l->max_outputs = args->n_max;
292 l->out_w = l->n_outputs;
293 l->out_c = 1;
294 l->out_h = 1;
295 l->eta_max = args->eta;
296 l->momentum = args->momentum;
298 l->decay = args->decay;
299 struct ArgsLayer *cargs = layer_args_copy(args);
300 cargs->type = CONNECTED; // lstm is composed of 8 connected layers
301 cargs->function = LINEAR;
302 l->uf = layer_init(cargs); // input layers
303 l->ui = layer_init(cargs);
304 l->ug = layer_init(cargs);
305 l->uo = layer_init(cargs);
306 cargs->n_inputs = cargs->n_init;
307 l->wf = layer_init(cargs); // self layers
308 l->wi = layer_init(cargs);
309 l->wg = layer_init(cargs);
310 l->wo = layer_init(cargs);
311 free(cargs);
315 set_eta(l);
317 l->mu = malloc(sizeof(double) * N_MU);
318 sam_init(l->mu, N_MU, MU_TYPE);
319}
320
326struct Layer *
328{
329 if (src->type != LSTM) {
330 printf("neural_layer_lstm_copy(): incorrect source layer type\n");
331 exit(EXIT_FAILURE);
332 }
333 struct Layer *l = malloc(sizeof(struct Layer));
335 l->type = src->type;
336 l->layer_vptr = src->layer_vptr;
337 l->function = src->function;
339 l->options = src->options;
340 l->n_inputs = src->n_inputs;
341 l->n_outputs = src->n_outputs;
342 l->out_w = src->out_w;
343 l->out_h = src->out_h;
344 l->out_c = src->out_c;
345 l->n_weights = src->n_weights;
346 l->n_biases = src->n_biases;
347 l->n_active = src->n_active;
348 l->eta = src->eta;
349 l->eta_max = src->eta_max;
350 l->momentum = src->momentum;
351 l->decay = src->decay;
353 l->max_outputs = src->max_outputs;
354 l->uf = layer_copy(src->uf);
355 l->ui = layer_copy(src->ui);
356 l->ug = layer_copy(src->ug);
357 l->uo = layer_copy(src->uo);
358 l->wf = layer_copy(src->wf);
359 l->wi = layer_copy(src->wi);
360 l->wg = layer_copy(src->wg);
361 l->wo = layer_copy(src->wo);
363 l->mu = malloc(sizeof(double) * N_MU);
364 memcpy(l->mu, src->mu, sizeof(double) * N_MU);
365 return l;
366}
367
372void
374{
375 layer_free(l->uf);
376 layer_free(l->ui);
377 layer_free(l->ug);
378 layer_free(l->uo);
379 layer_free(l->wf);
380 layer_free(l->wi);
381 layer_free(l->wg);
382 layer_free(l->wo);
383 free(l->uf);
384 free(l->ui);
385 free(l->ug);
386 free(l->uo);
387 free(l->wf);
388 free(l->wi);
389 free(l->wg);
390 free(l->wo);
392 free(l->mu);
393}
394
399void
401{
402 layer_rand(l->uf);
403 layer_rand(l->ui);
404 layer_rand(l->ug);
405 layer_rand(l->uo);
406 layer_rand(l->wf);
407 layer_rand(l->wi);
408 layer_rand(l->wg);
409 layer_rand(l->wo);
410}
411
418void
419neural_layer_lstm_forward(const struct Layer *l, const struct Net *net,
420 const double *input)
421{
422 layer_forward(l->uf, net, input);
423 layer_forward(l->ui, net, input);
424 layer_forward(l->ug, net, input);
425 layer_forward(l->uo, net, input);
426 layer_forward(l->wf, net, l->h);
427 layer_forward(l->wi, net, l->h);
428 layer_forward(l->wg, net, l->h);
429 layer_forward(l->wo, net, l->h);
430 memcpy(l->f, l->wf->output, sizeof(double) * l->n_outputs);
431 blas_axpy(l->n_outputs, 1, l->uf->output, 1, l->f, 1);
432 memcpy(l->i, l->wi->output, sizeof(double) * l->n_outputs);
433 blas_axpy(l->n_outputs, 1, l->ui->output, 1, l->i, 1);
434 memcpy(l->g, l->wg->output, sizeof(double) * l->n_outputs);
435 blas_axpy(l->n_outputs, 1, l->ug->output, 1, l->g, 1);
436 memcpy(l->o, l->wo->output, sizeof(double) * l->n_outputs);
437 blas_axpy(l->n_outputs, 1, l->uo->output, 1, l->o, 1);
442 memcpy(l->temp, l->i, sizeof(double) * l->n_outputs);
443 blas_mul(l->n_outputs, l->g, 1, l->temp, 1);
444 blas_mul(l->n_outputs, l->f, 1, l->c, 1);
445 blas_axpy(l->n_outputs, 1, l->temp, 1, l->c, 1);
446 memcpy(l->h, l->c, sizeof(double) * l->n_outputs);
448 blas_mul(l->n_outputs, l->o, 1, l->h, 1);
449 memcpy(l->cell, l->c, sizeof(double) * l->n_outputs);
450 memcpy(l->output, l->h, sizeof(double) * l->n_outputs);
451}
452
460void
461neural_layer_lstm_backward(const struct Layer *l, const struct Net *net,
462 const double *input, double *delta)
463{
465 memcpy(l->temp3, l->delta, sizeof(double) * l->n_outputs);
466 memcpy(l->temp, l->c, sizeof(double) * l->n_outputs);
468 memcpy(l->temp2, l->temp3, sizeof(double) * l->n_outputs);
469 blas_mul(l->n_outputs, l->o, 1, l->temp2, 1);
471 blas_axpy(l->n_outputs, 1, l->dc, 1, l->temp2, 1);
472 memcpy(l->temp, l->c, sizeof(double) * l->n_outputs);
474 blas_mul(l->n_outputs, l->temp3, 1, l->temp, 1);
476 memcpy(l->wo->delta, l->temp, sizeof(double) * l->n_outputs);
477 layer_backward(l->wo, net, l->prev_state, 0);
478 memcpy(l->uo->delta, l->temp, sizeof(double) * l->n_outputs);
479 layer_backward(l->uo, net, input, delta);
480 memcpy(l->temp, l->temp2, sizeof(double) * l->n_outputs);
481 blas_mul(l->n_outputs, l->i, 1, l->temp, 1);
483 memcpy(l->wg->delta, l->temp, sizeof(double) * l->n_outputs);
484 layer_backward(l->wg, net, l->prev_state, 0);
485 memcpy(l->ug->delta, l->temp, sizeof(double) * l->n_outputs);
486 layer_backward(l->ug, net, input, delta);
487 memcpy(l->temp, l->temp2, sizeof(double) * l->n_outputs);
488 blas_mul(l->n_outputs, l->g, 1, l->temp, 1);
490 memcpy(l->wi->delta, l->temp, sizeof(double) * l->n_outputs);
491 layer_backward(l->wi, net, l->prev_state, 0);
492 memcpy(l->ui->delta, l->temp, sizeof(double) * l->n_outputs);
493 layer_backward(l->ui, net, input, delta);
494 memcpy(l->temp, l->temp2, sizeof(double) * l->n_outputs);
495 blas_mul(l->n_outputs, l->prev_cell, 1, l->temp, 1);
497 memcpy(l->wf->delta, l->temp, sizeof(double) * l->n_outputs);
498 layer_backward(l->wf, net, l->prev_state, 0);
499 memcpy(l->uf->delta, l->temp, sizeof(double) * l->n_outputs);
500 layer_backward(l->uf, net, input, delta);
501 memcpy(l->temp, l->temp2, sizeof(double) * l->n_outputs);
502 blas_mul(l->n_outputs, l->f, 1, l->temp, 1);
503 memcpy(l->dc, l->temp, sizeof(double) * l->n_outputs);
504}
505
510void
512{
513 if (l->options & LAYER_SGD_WEIGHTS && l->eta > 0) {
514 layer_update(l->wf);
515 layer_update(l->wi);
516 layer_update(l->wg);
517 layer_update(l->wo);
518 layer_update(l->uf);
519 layer_update(l->ui);
520 layer_update(l->ug);
521 layer_update(l->uo);
522 }
523}
524
530void
531neural_layer_lstm_resize(struct Layer *l, const struct Layer *prev)
532{
533 layer_resize(l->uf, prev);
534 layer_resize(l->ui, prev);
535 layer_resize(l->ug, prev);
536 layer_resize(l->uo, prev);
537 layer_resize(l->uf, prev);
538 l->n_inputs = prev->n_outputs;
542}
543
549double *
551{
552 return l->output;
553}
554
560bool
562{
563 sam_adapt(l->mu, N_MU, MU_TYPE);
564 bool mod = false;
565 if ((l->options & LAYER_EVOLVE_ETA) && mutate_eta(l)) {
566 mod = true;
567 }
569 mod = true;
570 }
572 mod = true;
573 }
575 mod = true;
576 }
577 if ((l->options & LAYER_EVOLVE_FUNCTIONS) &&
578 layer_mutate_functions(l, l->mu[5])) {
579 mod = true;
580 }
581 return mod;
582}
583
589void
590neural_layer_lstm_print(const struct Layer *l, const bool print_weights)
591{
592 char *json_str = neural_layer_lstm_json_export(l, print_weights);
593 printf("%s\n", json_str);
594 free(json_str);
595}
596
604char *
605neural_layer_lstm_json_export(const struct Layer *l, const bool return_weights)
606{
607 cJSON *json = cJSON_CreateObject();
608 cJSON_AddStringToObject(json, "type", "lstm");
609 cJSON_AddStringToObject(json, "activation",
611 cJSON_AddStringToObject(json, "recurrent_activation",
613 cJSON_AddNumberToObject(json, "n_inputs", l->n_inputs);
614 cJSON_AddNumberToObject(json, "n_outputs", l->n_outputs);
615 cJSON_AddNumberToObject(json, "eta", l->eta);
616 cJSON *mutation = cJSON_CreateDoubleArray(l->mu, N_MU);
617 cJSON_AddItemToObject(json, "mutation", mutation);
618 char *weights_str = layer_weight_json(l->uf, return_weights);
619 cJSON *uf = cJSON_Parse(weights_str);
620 free(weights_str);
621 cJSON_AddItemToObject(json, "uf_layer", uf);
622 weights_str = layer_weight_json(l->ui, return_weights);
623 cJSON *ui = cJSON_Parse(weights_str);
624 free(weights_str);
625 cJSON_AddItemToObject(json, "ui_layer", ui);
626 weights_str = layer_weight_json(l->ug, return_weights);
627 cJSON *ug = cJSON_Parse(weights_str);
628 free(weights_str);
629 cJSON_AddItemToObject(json, "ug_layer", ug);
630 weights_str = layer_weight_json(l->uo, return_weights);
631 cJSON *uo = cJSON_Parse(weights_str);
632 free(weights_str);
633 cJSON_AddItemToObject(json, "uo_layer", uo);
634 weights_str = layer_weight_json(l->wf, return_weights);
635 cJSON *wf = cJSON_Parse(weights_str);
636 free(weights_str);
637 cJSON_AddItemToObject(json, "wf_layer", wf);
638 weights_str = layer_weight_json(l->wi, return_weights);
639 cJSON *wi = cJSON_Parse(weights_str);
640 free(weights_str);
641 cJSON_AddItemToObject(json, "wi_layer", wi);
642 weights_str = layer_weight_json(l->wg, return_weights);
643 cJSON *wg = cJSON_Parse(weights_str);
644 free(weights_str);
645 cJSON_AddItemToObject(json, "wg_layer", wg);
646 weights_str = layer_weight_json(l->wo, return_weights);
647 cJSON *wo = cJSON_Parse(weights_str);
648 free(weights_str);
649 cJSON_AddItemToObject(json, "wo_layer", wo);
650 char *string = cJSON_Print(json);
651 cJSON_Delete(json);
652 return string;
653}
654
661size_t
662neural_layer_lstm_save(const struct Layer *l, FILE *fp)
663{
664 size_t s = 0;
665 s += fwrite(&l->n_inputs, sizeof(int), 1, fp);
666 s += fwrite(&l->n_outputs, sizeof(int), 1, fp);
667 s += fwrite(&l->n_weights, sizeof(int), 1, fp);
668 s += fwrite(&l->n_biases, sizeof(int), 1, fp);
669 s += fwrite(&l->max_outputs, sizeof(int), 1, fp);
670 s += fwrite(&l->n_active, sizeof(int), 1, fp);
671 s += fwrite(&l->eta, sizeof(double), 1, fp);
672 s += fwrite(&l->eta_max, sizeof(double), 1, fp);
673 s += fwrite(&l->momentum, sizeof(double), 1, fp);
674 s += fwrite(&l->decay, sizeof(double), 1, fp);
675 s += fwrite(&l->max_neuron_grow, sizeof(int), 1, fp);
676 s += fwrite(&l->options, sizeof(uint32_t), 1, fp);
677 s += fwrite(l->mu, sizeof(double), N_MU, fp);
678 s += fwrite(l->state, sizeof(double), l->n_outputs, fp);
679 s += fwrite(l->prev_state, sizeof(double), l->n_outputs, fp);
680 s += fwrite(l->cell, sizeof(double), l->n_outputs, fp);
681 s += fwrite(l->f, sizeof(double), l->n_outputs, fp);
682 s += fwrite(l->i, sizeof(double), l->n_outputs, fp);
683 s += fwrite(l->g, sizeof(double), l->n_outputs, fp);
684 s += fwrite(l->o, sizeof(double), l->n_outputs, fp);
685 s += fwrite(l->c, sizeof(double), l->n_outputs, fp);
686 s += fwrite(l->h, sizeof(double), l->n_outputs, fp);
687 s += fwrite(l->temp, sizeof(double), l->n_outputs, fp);
688 s += fwrite(l->temp2, sizeof(double), l->n_outputs, fp);
689 s += fwrite(l->temp3, sizeof(double), l->n_outputs, fp);
690 s += fwrite(l->dc, sizeof(double), l->n_outputs, fp);
691 s += layer_save(l->uf, fp);
692 s += layer_save(l->ui, fp);
693 s += layer_save(l->ug, fp);
694 s += layer_save(l->uo, fp);
695 s += layer_save(l->wf, fp);
696 s += layer_save(l->wi, fp);
697 s += layer_save(l->wg, fp);
698 s += layer_save(l->wo, fp);
699 return s;
700}
701
708size_t
709neural_layer_lstm_load(struct Layer *l, FILE *fp)
710{
711 size_t s = 0;
712 s += fread(&l->n_inputs, sizeof(int), 1, fp);
713 s += fread(&l->n_outputs, sizeof(int), 1, fp);
714 s += fread(&l->n_weights, sizeof(int), 1, fp);
715 s += fread(&l->n_biases, sizeof(int), 1, fp);
716 s += fread(&l->max_outputs, sizeof(int), 1, fp);
717 s += fread(&l->n_active, sizeof(int), 1, fp);
718 s += fread(&l->eta, sizeof(double), 1, fp);
719 s += fread(&l->eta_max, sizeof(double), 1, fp);
720 s += fread(&l->momentum, sizeof(double), 1, fp);
721 s += fread(&l->decay, sizeof(double), 1, fp);
722 s += fread(&l->max_neuron_grow, sizeof(int), 1, fp);
723 s += fread(&l->options, sizeof(uint32_t), 1, fp);
724 l->out_w = l->n_outputs;
725 l->out_c = 1;
726 l->out_h = 1;
728 l->mu = malloc(sizeof(double) * N_MU);
729 s += fread(l->mu, sizeof(double), N_MU, fp);
730 s += fread(l->state, sizeof(double), l->n_outputs, fp);
731 s += fread(l->prev_state, sizeof(double), l->n_outputs, fp);
732 s += fread(l->cell, sizeof(double), l->n_outputs, fp);
733 s += fread(l->f, sizeof(double), l->n_outputs, fp);
734 s += fread(l->i, sizeof(double), l->n_outputs, fp);
735 s += fread(l->g, sizeof(double), l->n_outputs, fp);
736 s += fread(l->o, sizeof(double), l->n_outputs, fp);
737 s += fread(l->c, sizeof(double), l->n_outputs, fp);
738 s += fread(l->h, sizeof(double), l->n_outputs, fp);
739 s += fread(l->temp, sizeof(double), l->n_outputs, fp);
740 s += fread(l->temp2, sizeof(double), l->n_outputs, fp);
741 s += fread(l->temp3, sizeof(double), l->n_outputs, fp);
742 s += fread(l->dc, sizeof(double), l->n_outputs, fp);
743 malloc_layers(l);
744 s += layer_load(l->uf, fp);
745 s += layer_load(l->ui, fp);
746 s += layer_load(l->ug, fp);
747 s += layer_load(l->uo, fp);
748 s += layer_load(l->wf, fp);
749 s += layer_load(l->wi, fp);
750 s += layer_load(l->wg, fp);
751 s += layer_load(l->wo, fp);
752 return s;
753}
void blas_axpy(const int N, const double ALPHA, const double *X, const int INCX, double *Y, const int INCY)
Multiplies vector X by the scalar ALPHA and adds it to the vector Y.
Definition blas.c:138
void blas_mul(const int N, const double *X, const int INCX, double *Y, const int INCY)
Multiplies vector X by the vector Y and stores the result in vector Y.
Definition blas.c:217
Basic linear algebra functions.
const char * neural_activation_string(const int a)
Returns the name of a specified activation function.
void neural_gradient_array(const double *state, double *delta, const int n, const int a)
Applies a gradient function to a vector of neuron states.
void neural_activate_array(double *state, double *output, const int n, const int a)
Applies an activation function to a vector of neuron states.
Neural network activation functions.
#define LINEAR
Linear [-inf,inf].
bool layer_mutate_connectivity(struct Layer *l, const double mu_enable, const double mu_disable)
Mutates a layer's connectivity by zeroing weights.
void layer_defaults(struct Layer *l)
Initialises a layer to default values.
int layer_mutate_neurons(const struct Layer *l, const double mu)
Returns the number of neurons to add or remove from a layer.
bool layer_mutate_functions(struct Layer *l, const double mu)
Mutates a layer's activation function by random selection.
void layer_guard_outputs(const struct Layer *l)
Check number of outputs is within bounds.
void layer_add_neurons(struct Layer *l, const int N)
Adds N neurons to a layer. Negative N removes neurons.
char * layer_weight_json(const struct Layer *l, const bool return_weights)
Returns a json formatted string representation of a layer's weights.
bool layer_mutate_eta(struct Layer *l, const double mu)
Mutates the gradient descent rate of a neural layer.
bool layer_mutate_weights(struct Layer *l, const double mu)
Mutates a layer's weights and biases by adding random numbers from a Gaussian normal distribution wit...
static void layer_rand(struct Layer *l)
Randomises a layer.
static void layer_resize(struct Layer *l, const struct Layer *prev)
Resizes a layer using the previous layer's inputs.
#define LAYER_EVOLVE_ETA
Layer may evolve rate of gradient descent.
#define LAYER_EVOLVE_FUNCTIONS
Layer may evolve functions.
static size_t layer_save(const struct Layer *l, FILE *fp)
Writes the layer to a file.
#define LAYER_EVOLVE_WEIGHTS
Layer may evolve weights.
static void layer_free(const struct Layer *l)
Frees the memory used by the layer.
static void layer_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates the error through a layer.
static size_t layer_load(struct Layer *l, FILE *fp)
Reads the layer from a file.
#define LSTM
Layer type LSTM.
#define LAYER_EVOLVE_NEURONS
Layer may evolve neurons.
#define LAYER_EVOLVE_CONNECT
Layer may evolve connectivity.
static void layer_update(const struct Layer *l)
Updates the weights and biases of a layer.
static struct Layer * layer_init(const struct ArgsLayer *args)
Creates and initialises a new layer.
static void layer_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates an input through the layer.
static struct Layer * layer_copy(const struct Layer *src)
Creates and returns a copy of a specified layer.
#define LAYER_SGD_WEIGHTS
Layer may perform gradient descent.
#define CONNECTED
Layer type connected.
uint32_t layer_args_opt(const struct ArgsLayer *args)
Returns a bitstring representing the permissions granted by a layer.
struct ArgsLayer * layer_args_copy(const struct ArgsLayer *src)
Creates and returns a copy of specified layer parameters.
An implementation of a fully-connected layer of perceptrons.
void neural_layer_lstm_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates an LSTM layer.
void neural_layer_lstm_rand(struct Layer *l)
Randomises an LSTM layer weights.
bool neural_layer_lstm_mutate(struct Layer *l)
Mutates an LSTM layer.
static bool mutate_eta(struct Layer *l)
Mutates the gradient descent rate used to update an LSTM layer.
char * neural_layer_lstm_json_export(const struct Layer *l, const bool return_weights)
Returns a json formatted string representation of an LSTM layer.
void neural_layer_lstm_free(const struct Layer *l)
Free memory used by an LSTM layer.
double * neural_layer_lstm_output(const struct Layer *l)
Returns the output from an LSTM layer.
static void free_layer_arrays(const struct Layer *l)
Free memory used by an LSTM layer.
static void malloc_layer_arrays(struct Layer *l)
Allocate memory used by an LSTM layer.
size_t neural_layer_lstm_load(struct Layer *l, FILE *fp)
Reads an LSTM layer from a file.
static void set_layer_n_weights(struct Layer *l)
Sets the total number of weights in an LSTM layer.
void neural_layer_lstm_resize(struct Layer *l, const struct Layer *prev)
Resizes an LSTM layer if the previous layer has changed size.
#define N_MU
Number of mutation rates applied to an LSTM layer.
static bool mutate_neurons(struct Layer *l)
Mutates the number of neurons in an LSTM layer.
void neural_layer_lstm_print(const struct Layer *l, const bool print_weights)
Prints an LSTM layer.
static void set_layer_n_active(struct Layer *l)
Sets the number of active (non-zero) weights in an LSTM layer.
static const int MU_TYPE[(6)]
Self-adaptation method for mutating an LSTM layer.
size_t neural_layer_lstm_save(const struct Layer *l, FILE *fp)
Writes an LSTM layer to a file.
static bool mutate_weights(struct Layer *l)
Mutates the magnitude of weights and biases in an LSTM layer.
static void reset_layer_deltas(const struct Layer *l)
Zeros the deltas used to update an LSTM layer.
static void set_layer_n_biases(struct Layer *l)
Sets the total number of biases in an LSTM layer.
void neural_layer_lstm_update(const struct Layer *l)
Updates the weights and biases of an LSTM layer.
static void malloc_layers(struct Layer *l)
Allocate memory for the sub-layers.
struct Layer * neural_layer_lstm_copy(const struct Layer *src)
Initialises and creates a copy of one LSTM layer from another.
void neural_layer_lstm_init(struct Layer *l, const struct ArgsLayer *args)
Initialises a long short-term memory layer.
static bool mutate_connectivity(struct Layer *l)
Mutates the number of active weights in an LSTM layer.
static void set_eta(struct Layer *l)
Sets the gradient descent rate used to update an LSTM layer.
void neural_layer_lstm_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates an LSTM layer.
An implementation of a long short-term memory layer.
void sam_init(double *mu, const int N, const int *type)
Initialises self-adaptive mutation rates.
Definition sam.c:43
void sam_adapt(double *mu, const int N, const int *type)
Self-adapts mutation rates.
Definition sam.c:68
Self-adaptive mutation functions.
#define SAM_RATE_SELECT
Ten normally distributed rates.
Definition sam.h:29
Parameters for initialising a neural network layer.
int n_init
Initial number of units / neurons / filters.
double decay
Weight decay for gradient descent.
double momentum
Momentum for gradient descent.
int function
Activation function.
int max_neuron_grow
Maximum number neurons to add per mutation event.
double eta
Gradient descent rate.
int n_max
Maximum number of units / neurons.
int n_inputs
Number of inputs.
int type
Layer type: CONNECTED, DROPOUT, etc.
int recurrent_function
Recurrent activation function.
Neural network layer data structure.
struct Layer * wf
LSTM.
double * output
Current neuron outputs (after activation function)
double decay
Weight decay for gradient descent.
struct Layer * wo
LSTM.
double * state
Current neuron states (before activation function)
struct Layer * uo
LSTM.
int recurrent_function
LSTM.
int max_neuron_grow
Maximum number neurons to add per mutation event.
struct Layer * ug
LSTM.
int n_inputs
Number of layer inputs.
double * g
LSTM.
int n_biases
Number of layer biases.
double * mu
Mutation rates.
int function
Layer activation function.
double * c
LSTM.
double * temp
LSTM.
struct Layer * wg
LSTM.
struct LayerVtbl const * layer_vptr
Functions acting on layers.
int max_outputs
Maximum number of neurons in the layer.
double * h
LSTM.
int n_weights
Number of layer weights.
double * dc
LSTM.
double * temp3
LSTM.
double eta_max
Maximum gradient descent rate.
struct Layer * uf
LSTM.
double * i
LSTM.
double * temp2
LSTM.
double * o
LSTM.
int n_outputs
Number of layer outputs.
int n_active
Number of active weights / connections.
struct Layer * ui
LSTM.
double * prev_state
Previous state for recursive layers.
int out_w
Pool, Conv, and Upsample.
int type
Layer type: CONNECTED, DROPOUT, etc.
double * cell
LSTM.
int out_c
Pool, Conv, and Upsample.
struct Layer * wi
LSTM.
double * delta
Delta for updating weights.
uint32_t options
Bitwise layer options permitting evolution, SGD, etc.
double * f
LSTM.
double * prev_cell
LSTM.
int out_h
Pool, Conv, and Upsample.
double eta
Gradient descent rate.
double momentum
Momentum for gradient descent.
Neural network data structure.
Definition neural.h:48
Utility functions for random number handling, etc.