XCSF  1.4.7
XCSF learning classifier system
neural_layer_recurrent.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 
25 #include "neural_layer_recurrent.h"
26 #include "blas.h"
27 #include "neural_activations.h"
28 #include "neural_layer_connected.h"
29 #include "sam.h"
30 #include "utils.h"
31 
32 #define N_MU (6)
33 
37 static const int MU_TYPE[N_MU] = {
44 };
45 
50 static void
52 {
54  l->state = calloc(l->n_outputs, sizeof(double));
55  l->prev_state = calloc(l->n_outputs, sizeof(double));
56  l->mu = malloc(sizeof(double) * N_MU);
57 }
58 
63 static void
65 {
67  l->state = realloc(l->state, l->n_outputs * sizeof(double));
68  l->prev_state = realloc(l->prev_state, l->n_outputs * sizeof(double));
69 }
70 
75 static void
76 free_layer_arrays(const struct Layer *l)
77 {
78  free(l->state);
79  free(l->prev_state);
80  free(l->mu);
81 }
82 
87 static void
88 malloc_layers(struct Layer *l)
89 {
90  l->input_layer = malloc(sizeof(struct Layer));
91  l->self_layer = malloc(sizeof(struct Layer));
92  l->output_layer = malloc(sizeof(struct Layer));
93 }
94 
99 static void
101 {
104 }
105 
110 static void
112 {
115 }
116 
121 static void
123 {
126 }
127 
133 static bool
134 mutate_eta(struct Layer *l)
135 {
136  if ((l->options & LAYER_EVOLVE_ETA) && layer_mutate_eta(l, l->mu[0])) {
137  l->input_layer->eta = l->eta;
138  l->self_layer->eta = l->eta;
139  l->output_layer->eta = l->eta;
140  return true;
141  }
142  return false;
143 }
144 
150 static bool
152 {
153  if (l->options & LAYER_EVOLVE_NEURONS) {
154  const int n = layer_mutate_neurons(l->self_layer, l->mu[1]);
155  if (n != 0) {
162  l->out_w = l->n_outputs;
163  l->out_h = 1;
164  l->out_c = 1;
165  l->output = l->output_layer->output;
166  l->delta = l->output_layer->delta;
171  return true;
172  }
173  }
174  return false;
175 }
176 
182 static bool
184 {
185  bool mod = false;
186  if (l->options & LAYER_EVOLVE_CONNECT) {
187  if (layer_mutate_connectivity(l->input_layer, l->mu[2], l->mu[3])) {
188  mod = true;
189  }
190  if (layer_mutate_connectivity(l->self_layer, l->mu[2], l->mu[3])) {
191  mod = true;
192  }
193  if (layer_mutate_connectivity(l->output_layer, l->mu[2], l->mu[3])) {
194  mod = true;
195  }
197  }
198  return mod;
199 }
200 
206 static bool
208 {
209  bool mod = false;
210  if (l->options & LAYER_EVOLVE_WEIGHTS) {
211  if (layer_mutate_weights(l->input_layer, l->mu[4])) {
212  mod = true;
213  }
214  if (layer_mutate_weights(l->self_layer, l->mu[4])) {
215  mod = true;
216  }
217  if (layer_mutate_weights(l->output_layer, l->mu[4])) {
218  mod = true;
219  }
220  }
221  return mod;
222 }
223 
229 static bool
231 {
232  if (l->options & LAYER_EVOLVE_FUNCTIONS &&
233  layer_mutate_functions(l, l->mu[5])) {
234  l->output_layer->function = l->function;
235  return true;
236  }
237  return false;
238 }
239 
245 void
246 neural_layer_recurrent_init(struct Layer *l, const struct ArgsLayer *args)
247 {
248  l->options = layer_args_opt(args);
249  l->function = args->function;
250  l->n_inputs = args->n_inputs;
251  l->n_outputs = args->n_init;
252  l->max_outputs = args->n_max;
253  l->out_w = l->n_outputs;
254  l->out_c = 1;
255  l->out_h = 1;
256  struct ArgsLayer *cargs = layer_args_copy(args);
257  cargs->type = CONNECTED; // recurrent layer is composed of 3 connected
258  cargs->function = LINEAR; // input layer and self layer are linear
259  l->input_layer = layer_init(cargs);
260  cargs->n_inputs = cargs->n_init; // n_init inputs to self and output layers
261  l->self_layer = layer_init(cargs);
262  cargs->function = args->function; // output activation
263  l->output_layer = layer_init(cargs);
264  free(cargs);
265  l->output = l->output_layer->output;
266  l->delta = l->output_layer->delta;
267  l->eta = l->input_layer->eta;
268  l->self_layer->eta = l->eta;
269  l->output_layer->eta = l->eta;
274  sam_init(l->mu, N_MU, MU_TYPE);
275 }
276 
282 struct Layer *
284 {
285  if (src->type != RECURRENT) {
286  printf("neural_layer_recurrent_copy(): incorrect source layer type\n");
287  exit(EXIT_FAILURE);
288  }
289  struct Layer *l = malloc(sizeof(struct Layer));
290  layer_defaults(l);
291  l->type = src->type;
292  l->layer_vptr = src->layer_vptr;
293  l->options = src->options;
294  l->function = src->function;
295  l->n_inputs = src->n_inputs;
296  l->n_outputs = src->n_outputs;
297  l->max_outputs = src->max_outputs;
298  l->out_w = src->out_w;
299  l->out_c = src->out_c;
300  l->out_h = src->out_h;
301  l->n_active = src->n_active;
302  l->eta = src->eta;
304  l->self_layer = layer_copy(src->self_layer);
306  l->output = l->output_layer->output;
307  l->delta = l->output_layer->delta;
309  memcpy(l->mu, src->mu, sizeof(double) * N_MU);
310  memcpy(l->prev_state, src->prev_state, sizeof(double) * src->n_outputs);
311  return l;
312 }
313 
318 void
320 {
324  free(l->input_layer);
325  free(l->self_layer);
326  free(l->output_layer);
328 }
329 
334 void
336 {
340 }
341 
348 void
349 neural_layer_recurrent_forward(const struct Layer *l, const struct Net *net,
350  const double *input)
351 {
352  memcpy(l->prev_state, l->state, sizeof(double) * l->n_outputs);
353  layer_forward(l->input_layer, net, input);
355  memcpy(l->state, l->input_layer->output, sizeof(double) * l->n_outputs);
356  blas_axpy(l->n_outputs, 1, l->self_layer->output, 1, l->state, 1);
357  layer_forward(l->output_layer, net, l->state);
358 }
359 
367 void
368 neural_layer_recurrent_backward(const struct Layer *l, const struct Net *net,
369  const double *input, double *delta)
370 {
371  memset(l->input_layer->delta, 0, sizeof(double) * l->n_outputs);
372  memset(l->self_layer->delta, 0, sizeof(double) * l->n_outputs);
374  memcpy(l->input_layer->delta, l->self_layer->delta,
375  sizeof(double) * l->n_outputs);
376  layer_backward(l->self_layer, net, l->prev_state, 0);
377  layer_backward(l->input_layer, net, input, delta);
378 }
379 
384 void
386 {
387  if (l->options & LAYER_SGD_WEIGHTS && l->eta > 0) {
391  }
392 }
393 
399 void
400 neural_layer_recurrent_resize(struct Layer *l, const struct Layer *prev)
401 {
402  layer_resize(l->input_layer, prev);
403  l->n_inputs = l->input_layer->n_inputs;
406 }
407 
413 double *
415 {
416  return l->output;
417 }
418 
424 bool
426 {
427  sam_adapt(l->mu, N_MU, MU_TYPE);
428  bool mod = false;
429  mod = mutate_eta(l) ? true : mod;
430  mod = mutate_neurons(l) ? true : mod;
431  mod = mutate_connectivity(l) ? true : mod;
432  mod = mutate_weights(l) ? true : mod;
433  mod = mutate_functions(l) ? true : mod;
434  return mod;
435 }
436 
442 void
443 neural_layer_recurrent_print(const struct Layer *l, const bool print_weights)
444 {
445  char *json_str = neural_layer_recurrent_json_export(l, print_weights);
446  printf("%s\n", json_str);
447  free(json_str);
448 }
449 
457 char *
459  const bool return_weights)
460 {
461  cJSON *json = cJSON_CreateObject();
462  cJSON_AddStringToObject(json, "type", "recurrent");
463  cJSON_AddStringToObject(json, "activation",
465  cJSON_AddNumberToObject(json, "n_inputs", l->n_inputs);
466  cJSON_AddNumberToObject(json, "n_outputs", l->n_outputs);
467  cJSON_AddNumberToObject(json, "eta", l->eta);
468  cJSON *mutation = cJSON_CreateDoubleArray(l->mu, N_MU);
469  cJSON_AddItemToObject(json, "mutation", mutation);
470  char *weights_str = layer_weight_json(l->input_layer, return_weights);
471  cJSON *il = cJSON_Parse(weights_str);
472  free(weights_str);
473  cJSON_AddItemToObject(json, "input_layer", il);
474  weights_str = layer_weight_json(l->self_layer, return_weights);
475  cJSON *sl = cJSON_Parse(weights_str);
476  free(weights_str);
477  cJSON_AddItemToObject(json, "self_layer", sl);
478  weights_str = layer_weight_json(l->output_layer, return_weights);
479  cJSON *ol = cJSON_Parse(weights_str);
480  free(weights_str);
481  cJSON_AddItemToObject(json, "output_layer", ol);
482  char *string = cJSON_Print(json);
483  cJSON_Delete(json);
484  return string;
485 }
486 
493 size_t
494 neural_layer_recurrent_save(const struct Layer *l, FILE *fp)
495 {
496  size_t s = 0;
497  s += fwrite(&l->n_inputs, sizeof(int), 1, fp);
498  s += fwrite(&l->n_outputs, sizeof(int), 1, fp);
499  s += fwrite(&l->max_outputs, sizeof(int), 1, fp);
500  s += fwrite(&l->options, sizeof(uint32_t), 1, fp);
501  s += fwrite(&l->function, sizeof(int), 1, fp);
502  s += fwrite(&l->eta, sizeof(double), 1, fp);
503  s += fwrite(&l->n_active, sizeof(int), 1, fp);
504  s += fwrite(l->mu, sizeof(double), N_MU, fp);
505  s += fwrite(l->state, sizeof(double), l->n_outputs, fp);
506  s += fwrite(l->prev_state, sizeof(double), l->n_outputs, fp);
507  s += layer_save(l->input_layer, fp);
508  s += layer_save(l->self_layer, fp);
509  s += layer_save(l->output_layer, fp);
510  return s;
511 }
512 
519 size_t
520 neural_layer_recurrent_load(struct Layer *l, FILE *fp)
521 {
522  size_t s = 0;
523  s += fread(&l->n_inputs, sizeof(int), 1, fp);
524  s += fread(&l->n_outputs, sizeof(int), 1, fp);
525  s += fread(&l->max_outputs, sizeof(int), 1, fp);
526  s += fread(&l->options, sizeof(uint32_t), 1, fp);
527  s += fread(&l->function, sizeof(int), 1, fp);
528  s += fread(&l->eta, sizeof(double), 1, fp);
529  s += fread(&l->n_active, sizeof(int), 1, fp);
530  l->out_w = l->n_outputs;
531  l->out_c = 1;
532  l->out_h = 1;
534  s += fread(l->mu, sizeof(double), N_MU, fp);
535  s += fread(l->state, sizeof(double), l->n_outputs, fp);
536  s += fread(l->prev_state, sizeof(double), l->n_outputs, fp);
537  malloc_layers(l);
538  s += layer_load(l->input_layer, fp);
539  s += layer_load(l->self_layer, fp);
540  s += layer_load(l->output_layer, fp);
541  return s;
542 }
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
Basic linear algebra functions.
const char * neural_activation_string(const int a)
Returns the name of a specified activation function.
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.
Definition: neural_layer.c:176
void layer_defaults(struct Layer *l)
Initialises a layer to default values.
Definition: neural_layer.c:413
int layer_mutate_neurons(const struct Layer *l, const double mu)
Returns the number of neurons to add or remove from a layer.
Definition: neural_layer.c:106
bool layer_mutate_functions(struct Layer *l, const double mu)
Mutates a layer's activation function by random selection.
Definition: neural_layer.c:283
char * layer_weight_json(const struct Layer *l, const bool return_weights)
Returns a json formatted string representation of a layer's weights.
Definition: neural_layer.c:324
void layer_guard_outputs(const struct Layer *l)
Check number of outputs is within bounds.
Definition: neural_layer.c:595
void layer_add_neurons(struct Layer *l, const int N)
Adds N neurons to a layer. Negative N removes neurons.
Definition: neural_layer.c:130
bool layer_mutate_eta(struct Layer *l, const double mu)
Mutates the gradient descent rate of a neural layer.
Definition: neural_layer.c:88
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...
Definition: neural_layer.c:252
static void layer_rand(struct Layer *l)
Randomises a layer.
Definition: neural_layer.h:259
static void layer_resize(struct Layer *l, const struct Layer *prev)
Resizes a layer using the previous layer's inputs.
Definition: neural_layer.h:228
#define LAYER_EVOLVE_ETA
Layer may evolve rate of gradient descent.
Definition: neural_layer.h:55
#define LAYER_EVOLVE_FUNCTIONS
Layer may evolve functions.
Definition: neural_layer.h:53
static size_t layer_save(const struct Layer *l, FILE *fp)
Writes the layer to a file.
Definition: neural_layer.h:373
static struct Layer * layer_init(const struct ArgsLayer *args)
Creates and initialises a new layer.
Definition: neural_layer.h:356
static struct Layer * layer_copy(const struct Layer *src)
Creates and returns a copy of a specified layer.
Definition: neural_layer.h:239
#define LAYER_EVOLVE_WEIGHTS
Layer may evolve weights.
Definition: neural_layer.h:51
static void layer_free(const struct Layer *l)
Frees the memory used by the layer.
Definition: neural_layer.h:249
static void layer_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates the error through a layer.
Definition: neural_layer.h:194
static size_t layer_load(struct Layer *l, FILE *fp)
Reads the layer from a file.
Definition: neural_layer.h:387
#define LAYER_EVOLVE_NEURONS
Layer may evolve neurons.
Definition: neural_layer.h:52
#define LAYER_EVOLVE_CONNECT
Layer may evolve connectivity.
Definition: neural_layer.h:56
static void layer_update(const struct Layer *l)
Updates the weights and biases of a layer.
Definition: neural_layer.h:205
#define RECURRENT
Layer type recurrent.
Definition: neural_layer.h:33
static void layer_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates an input through the layer.
Definition: neural_layer.h:181
#define LAYER_SGD_WEIGHTS
Layer may perform gradient descent.
Definition: neural_layer.h:54
#define CONNECTED
Layer type connected.
Definition: neural_layer.h:29
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.
size_t neural_layer_recurrent_save(const struct Layer *l, FILE *fp)
Writes a recurrent layer to a file.
size_t neural_layer_recurrent_load(struct Layer *l, FILE *fp)
Reads a recurrent layer from a file.
void neural_layer_recurrent_update(const struct Layer *l)
Updates the weights and biases of a recurrent layer.
void neural_layer_recurrent_resize(struct Layer *l, const struct Layer *prev)
Resizes a recurrent layer if the previous layer has changed size.
static bool mutate_eta(struct Layer *l)
Mutates the gradient descent rate used to update a recurrent layer.
struct Layer * neural_layer_recurrent_copy(const struct Layer *src)
Initialises and creates a copy of one recurrent layer from another.
bool neural_layer_recurrent_mutate(struct Layer *l)
Mutates a recurrent layer.
void neural_layer_recurrent_rand(struct Layer *l)
Randomises a recurrent layer weights.
static void free_layer_arrays(const struct Layer *l)
Free memory used by a recurrent layer.
static void malloc_layer_arrays(struct Layer *l)
Allocate memory used by a recurrent layer.
void neural_layer_recurrent_init(struct Layer *l, const struct ArgsLayer *args)
Initialises a recurrent layer.
static void set_layer_n_weights(struct Layer *l)
Sets the total number of weights in a recurrent layer.
static void realloc_layer_arrays(struct Layer *l)
Resize memory used by a recurrent layer.
#define N_MU
Number of mutation rates applied to a recurrent layer.
char * neural_layer_recurrent_json_export(const struct Layer *l, const bool return_weights)
Returns a json formatted string representation of a recurrent layer.
static bool mutate_neurons(struct Layer *l)
Mutates the number of neurons in a recurrent layer.
double * neural_layer_recurrent_output(const struct Layer *l)
Returns the output from a recurrent layer.
static bool mutate_functions(struct Layer *l)
Mutates the activation function of a recurrent layer.
static void set_layer_n_active(struct Layer *l)
Sets the number of active (non-zero) weights in a recurrent layer.
static const int MU_TYPE[(6)]
Self-adaptation method for mutating a recurrent layer.
static bool mutate_weights(struct Layer *l)
Mutates the magnitude of weights and biases in a recurrent layer.
static void set_layer_n_biases(struct Layer *l)
Sets the total number of biases in a recurrent layer.
static void malloc_layers(struct Layer *l)
Allocate memory for the sub-layers.
void neural_layer_recurrent_free(const struct Layer *l)
Free memory used by a recurrent layer.
void neural_layer_recurrent_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates a recurrent layer.
static bool mutate_connectivity(struct Layer *l)
Mutates the number of active weights in a recurrent layer.
void neural_layer_recurrent_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates a recurrent layer.
void neural_layer_recurrent_print(const struct Layer *l, const bool print_weights)
Prints a recurrent layer.
An implementation of a recurrent layer of perceptrons.
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.
int function
Activation function.
int n_max
Maximum number of units / neurons.
int n_inputs
Number of inputs.
int type
Layer type: CONNECTED, DROPOUT, etc.
Neural network layer data structure.
Definition: neural_layer.h:73
double * output
Current neuron outputs (after activation function)
Definition: neural_layer.h:76
struct Layer * input_layer
Recursive layer input.
Definition: neural_layer.h:102
double * state
Current neuron states (before activation function)
Definition: neural_layer.h:75
int n_inputs
Number of layer inputs.
Definition: neural_layer.h:90
int n_biases
Number of layer biases.
Definition: neural_layer.h:95
double * mu
Mutation rates.
Definition: neural_layer.h:84
int function
Layer activation function.
Definition: neural_layer.h:97
struct LayerVtbl const * layer_vptr
Functions acting on layers.
Definition: neural_layer.h:100
int max_outputs
Maximum number of neurons in the layer.
Definition: neural_layer.h:92
int n_weights
Number of layer weights.
Definition: neural_layer.h:94
struct Layer * output_layer
Recursive layer output.
Definition: neural_layer.h:104
int n_outputs
Number of layer outputs.
Definition: neural_layer.h:91
struct Layer * self_layer
Recursive layer self.
Definition: neural_layer.h:103
int n_active
Number of active weights / connections.
Definition: neural_layer.h:96
double * prev_state
Previous state for recursive layers.
Definition: neural_layer.h:101
int out_w
Pool, Conv, and Upsample.
Definition: neural_layer.h:130
int type
Layer type: CONNECTED, DROPOUT, etc.
Definition: neural_layer.h:74
int out_c
Pool, Conv, and Upsample.
Definition: neural_layer.h:132
double * delta
Delta for updating weights.
Definition: neural_layer.h:83
uint32_t options
Bitwise layer options permitting evolution, SGD, etc.
Definition: neural_layer.h:77
int out_h
Pool, Conv, and Upsample.
Definition: neural_layer.h:131
double eta
Gradient descent rate.
Definition: neural_layer.h:85
Neural network data structure.
Definition: neural.h:48
Utility functions for random number handling, etc.