XCSF  1.4.7
XCSF learning classifier system
neural_layer_convolutional.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 "blas.h"
26 #include "image.h"
27 #include "neural_activations.h"
28 #include "sam.h"
29 #include "utils.h"
30 
31 #define N_MU (6)
32 
36 static const int MU_TYPE[N_MU] = {
43 };
44 
50 static int
51 get_out_height(const struct Layer *l)
52 {
53  return (l->height + 2 * l->pad - l->size) / l->stride + 1;
54 }
55 
61 static int
62 get_out_width(const struct Layer *l)
63 {
64  return (l->width + 2 * l->pad - l->size) / l->stride + 1;
65 }
66 
72 static size_t
73 get_workspace_size(const struct Layer *l)
74 {
75  const size_t workspace_size = (size_t) l->out_h * l->out_w * l->size *
76  l->size * l->channels * sizeof(double);
77  if (workspace_size < 1) {
78  printf("neural_layer_convolutional: invalid workspace size\n");
79  layer_print(l, false);
80  exit(EXIT_FAILURE);
81  }
82  return workspace_size;
83 }
84 
89 static void
90 guard_malloc(const struct Layer *l)
91 {
95 }
96 
101 static void
103 {
104  guard_malloc(l);
105  l->delta = calloc(l->n_outputs, sizeof(double));
106  l->state = calloc(l->n_outputs, sizeof(double));
107  l->output = calloc(l->n_outputs, sizeof(double));
108  l->weights = malloc(sizeof(double) * l->n_weights);
109  l->weight_updates = calloc(l->n_weights, sizeof(double));
110  l->weight_active = malloc(sizeof(bool) * l->n_weights);
111  l->biases = malloc(sizeof(double) * l->n_biases);
112  l->bias_updates = calloc(l->n_biases, sizeof(double));
113  l->temp = malloc(get_workspace_size(l));
114  l->mu = malloc(sizeof(double) * N_MU);
115 }
116 
121 static void
123 {
124  guard_malloc(l);
125  l->delta = realloc(l->delta, sizeof(double) * l->n_outputs);
126  l->state = realloc(l->state, sizeof(double) * l->n_outputs);
127  l->output = realloc(l->output, sizeof(double) * l->n_outputs);
128  l->weights = realloc(l->weights, sizeof(double) * l->n_weights);
129  l->weight_updates =
130  realloc(l->weight_updates, sizeof(double) * l->n_weights);
131  l->weight_active = realloc(l->weight_active, sizeof(bool) * l->n_weights);
132  l->biases = realloc(l->biases, sizeof(double) * l->n_biases);
133  l->bias_updates = realloc(l->bias_updates, sizeof(double) * l->n_biases);
134  l->temp = realloc(l->temp, get_workspace_size(l));
135 }
136 
141 void
143 {
144  free(l->delta);
145  free(l->state);
146  free(l->output);
147  free(l->weights);
148  free(l->weight_updates);
149  free(l->weight_active);
150  free(l->biases);
151  free(l->bias_updates);
152  free(l->temp);
153  free(l->mu);
154 }
155 
161 void
162 neural_layer_convolutional_init(struct Layer *l, const struct ArgsLayer *args)
163 {
164  l->options = layer_args_opt(args);
165  l->function = args->function;
166  l->height = args->height;
167  l->width = args->width;
168  l->channels = args->channels;
169  l->n_filters = args->n_init;
170  l->max_outputs = args->n_max;
171  l->stride = args->stride;
172  l->size = args->size;
173  l->pad = args->pad;
174  l->max_neuron_grow = args->max_neuron_grow;
175  l->eta_max = args->eta;
176  l->eta_min = args->eta_min;
177  l->momentum = args->momentum;
178  l->decay = args->decay;
179  l->n_biases = l->n_filters;
180  l->n_weights = l->channels * l->n_filters * l->size * l->size;
181  l->n_active = l->n_weights;
182  l->out_h = get_out_height(l);
183  l->out_w = get_out_width(l);
184  l->out_c = l->n_filters;
185  l->n_inputs = l->width * l->height * l->channels;
186  l->n_outputs = l->out_h * l->out_w * l->out_c;
187  layer_init_eta(l);
189  for (int i = 0; i < l->n_weights; ++i) {
190  l->weights[i] = rand_normal(0, WEIGHT_SD_INIT);
191  l->weight_active[i] = true;
192  }
193  memset(l->biases, 0, sizeof(double) * l->n_biases);
194  sam_init(l->mu, N_MU, MU_TYPE);
195 }
196 
202 struct Layer *
204 {
205  if (src->type != CONVOLUTIONAL) {
206  printf("neural_layer_convolut_copy() incorrect source layer type\n");
207  exit(EXIT_FAILURE);
208  }
209  struct Layer *l = malloc(sizeof(struct Layer));
210  layer_defaults(l);
211  l->type = src->type;
212  l->layer_vptr = src->layer_vptr;
213  l->options = src->options;
214  l->function = src->function;
215  l->height = src->height;
216  l->width = src->width;
217  l->channels = src->channels;
218  l->n_filters = src->n_filters;
219  l->stride = src->stride;
220  l->size = src->size;
221  l->pad = src->pad;
222  l->n_weights = src->n_weights;
223  l->n_active = src->n_active;
224  l->out_h = src->out_h;
225  l->out_w = src->out_w;
226  l->out_c = src->out_c;
227  l->n_outputs = src->n_outputs;
228  l->n_inputs = src->n_inputs;
229  l->max_outputs = src->max_outputs;
231  l->n_biases = src->n_biases;
232  l->momentum = src->momentum;
233  l->decay = src->decay;
234  l->eta = src->eta;
235  l->eta_max = src->eta_max;
236  l->eta_min = src->eta_min;
238  memcpy(l->weights, src->weights, sizeof(double) * src->n_weights);
239  memcpy(l->weight_active, src->weight_active, sizeof(bool) * src->n_weights);
240  memcpy(l->biases, src->biases, sizeof(double) * src->n_biases);
241  memcpy(l->mu, src->mu, sizeof(double) * N_MU);
242  return l;
243 }
244 
249 void
251 {
253 }
254 
261 void
262 neural_layer_convolutional_forward(const struct Layer *l, const struct Net *net,
263  const double *input)
264 {
265  (void) net;
266  const int m = l->n_filters;
267  const int k = l->size * l->size * l->channels;
268  const int n = l->out_w * l->out_h;
269  const double *a = l->weights;
270  double *b = l->temp;
271  double *c = l->state;
272  memset(l->state, 0, sizeof(double) * l->n_outputs);
273  if (l->size == 1) {
274  blas_gemm(0, 0, m, n, k, 1, a, k, input, n, 1, c, n);
275  } else {
276  im2col(input, l->channels, l->height, l->width, l->size, l->stride,
277  l->pad, b);
278  blas_gemm(0, 0, m, n, k, 1, a, k, b, n, 1, c, n);
279  }
280  for (int i = 0; i < l->n_biases; ++i) {
281  for (int j = 0; j < n; ++j) {
282  l->state[i * n + j] += l->biases[i];
283  }
284  }
286 }
287 
295 void
297  const struct Net *net, const double *input,
298  double *delta)
299 {
300  (void) net;
301  const int m = l->n_filters;
302  const int n = l->size * l->size * l->channels;
303  const int k = l->out_w * l->out_h;
304  if (l->options & LAYER_SGD_WEIGHTS) {
306  for (int i = 0; i < l->n_biases; ++i) {
307  l->bias_updates[i] += blas_sum(l->delta + k * i, k);
308  }
309  const double *a = l->delta;
310  double *b = l->temp;
311  double *c = l->weight_updates;
312  if (l->size == 1) {
313  blas_gemm(0, 1, m, n, k, 1, a, k, input, k, 1, c, n);
314  } else {
315  im2col(input, l->channels, l->height, l->width, l->size, l->stride,
316  l->pad, b);
317  blas_gemm(0, 1, m, n, k, 1, a, k, b, k, 1, c, n);
318  }
319  }
320  if (delta) {
321  const double *a = l->weights;
322  const double *b = l->delta;
323  double *c = l->temp;
324  if (l->size == 1) {
325  c = delta;
326  }
327  blas_gemm(1, 0, n, k, m, 1, a, n, b, k, 0, c, k);
328  if (l->size != 1) {
329  col2im(l->temp, l->channels, l->height, l->width, l->size,
330  l->stride, l->pad, delta);
331  }
332  }
333 }
334 
339 void
341 {
342  if (l->options & LAYER_SGD_WEIGHTS && l->eta > 0) {
343  blas_axpy(l->n_biases, l->eta, l->bias_updates, 1, l->biases, 1);
344  blas_scal(l->n_biases, l->momentum, l->bias_updates, 1);
345  if (l->decay > 0) {
346  blas_axpy(l->n_weights, -(l->decay), l->weights, 1,
347  l->weight_updates, 1);
348  }
349  blas_axpy(l->n_weights, l->eta, l->weight_updates, 1, l->weights, 1);
352  }
353 }
354 
360 void
361 neural_layer_convolutional_resize(struct Layer *l, const struct Layer *prev)
362 {
363  const int old_n_outputs = l->n_outputs;
364  const int old_n_weights = l->n_weights;
365  l->width = prev->out_w;
366  l->height = prev->out_h;
367  l->channels = prev->out_c;
368  l->out_w = get_out_width(l);
369  l->out_h = get_out_height(l);
370  l->n_outputs = l->out_h * l->out_w * l->out_c;
371  l->n_inputs = l->width * l->height * l->channels;
372  l->n_weights = l->channels * l->n_filters * l->size * l->size;
374  for (int i = old_n_weights; i < l->n_weights; ++i) {
375  l->weights[i] = rand_normal(0, WEIGHT_SD);
376  l->weight_updates[i] = 0;
377  l->weight_active[i] = true;
378  }
379  for (int i = old_n_outputs; i < l->n_outputs; ++i) {
380  l->delta[i] = 0;
381  l->state[i] = 0;
382  l->output[i] = 0;
383  }
385 }
386 
393 static int
394 neural_layer_convolutional_mutate_filter(const struct Layer *l, const double mu)
395 {
396  int n = 0;
397  if (rand_uniform(0, 0.1) < mu) { // 10x higher probability
398  while (n == 0) {
399  const double m = clamp(rand_normal(0, 0.5), -1, 1);
400  n = (int) round(m * l->max_neuron_grow);
401  }
402  if (l->n_filters + n < 1) {
403  n = -(l->n_filters - 1);
404  } else if (l->n_filters + n > l->max_outputs) {
405  n = l->max_outputs - l->n_filters;
406  }
407  }
408  return n;
409 }
410 
417 static void
419 {
420  const int old_n_biases = l->n_biases;
421  const int old_n_weights = l->n_weights;
422  const int old_n_outputs = l->n_outputs;
423  l->n_filters += N;
424  l->n_biases = l->n_filters;
425  l->out_c = l->n_filters;
426  l->n_weights = l->channels * l->n_filters * l->size * l->size;
427  l->n_outputs = l->out_h * l->out_w * l->out_c;
429  for (int i = old_n_weights; i < l->n_weights; ++i) {
430  l->weights[i] = rand_normal(0, WEIGHT_SD);
431  l->weight_active[i] = true;
432  l->weight_updates[i] = 0;
433  }
434  for (int i = old_n_biases; i < l->n_biases; ++i) {
435  l->biases[i] = 0;
436  l->bias_updates[i] = 0;
437  }
438  for (int i = old_n_outputs; i < l->n_outputs; ++i) {
439  l->output[i] = 0;
440  l->state[i] = 0;
441  l->delta[i] = 0;
442  }
444 }
445 
451 bool
453 {
454  sam_adapt(l->mu, N_MU, MU_TYPE);
455  bool mod = false;
456  if ((l->options & LAYER_EVOLVE_ETA) && layer_mutate_eta(l, l->mu[0])) {
457  mod = true;
458  }
459  if (l->options & LAYER_EVOLVE_NEURONS) {
460  const int n = neural_layer_convolutional_mutate_filter(l, l->mu[1]);
461  if (n != 0) {
463  mod = true;
464  }
465  }
466  if ((l->options & LAYER_EVOLVE_CONNECT) &&
467  layer_mutate_connectivity(l, l->mu[2], l->mu[3])) {
468  mod = true;
469  }
470  if ((l->options & LAYER_EVOLVE_WEIGHTS) &&
471  layer_mutate_weights(l, l->mu[4])) {
472  mod = true;
473  }
474  if ((l->options & LAYER_EVOLVE_FUNCTIONS) &&
475  layer_mutate_functions(l, l->mu[5])) {
476  mod = true;
477  }
478  return mod;
479 }
480 
486 double *
488 {
489  return l->output;
490 }
491 
497 void
499  const bool print_weights)
500 {
501  char *json_str = neural_layer_convolutional_json_export(l, print_weights);
502  printf("%s\n", json_str);
503  free(json_str);
504 }
505 
513 char *
515  const bool return_weights)
516 {
517  cJSON *json = cJSON_CreateObject();
518  cJSON_AddStringToObject(json, "type", "convolutional");
519  cJSON_AddStringToObject(json, "activation",
521  cJSON_AddNumberToObject(json, "n_inputs", l->n_inputs);
522  cJSON_AddNumberToObject(json, "n_outputs", l->n_outputs);
523  cJSON_AddNumberToObject(json, "n_filters", l->n_filters);
524  cJSON_AddNumberToObject(json, "size", l->size);
525  cJSON_AddNumberToObject(json, "stride", l->stride);
526  cJSON_AddNumberToObject(json, "pad", l->pad);
527  cJSON_AddNumberToObject(json, "eta", l->eta);
528  cJSON *mutation = cJSON_CreateDoubleArray(l->mu, N_MU);
529  cJSON_AddItemToObject(json, "mutation", mutation);
530  char *weights_str = layer_weight_json(l, return_weights);
531  cJSON *weights = cJSON_Parse(weights_str);
532  free(weights_str);
533  cJSON_AddItemToObject(json, "weights", weights);
534  char *string = cJSON_Print(json);
535  cJSON_Delete(json);
536  return string;
537 }
538 
545 size_t
546 neural_layer_convolutional_save(const struct Layer *l, FILE *fp)
547 {
548  size_t s = 0;
549  s += fwrite(&l->options, sizeof(uint32_t), 1, fp);
550  s += fwrite(&l->function, sizeof(int), 1, fp);
551  s += fwrite(&l->height, sizeof(int), 1, fp);
552  s += fwrite(&l->width, sizeof(int), 1, fp);
553  s += fwrite(&l->channels, sizeof(int), 1, fp);
554  s += fwrite(&l->n_filters, sizeof(int), 1, fp);
555  s += fwrite(&l->stride, sizeof(int), 1, fp);
556  s += fwrite(&l->size, sizeof(int), 1, fp);
557  s += fwrite(&l->pad, sizeof(int), 1, fp);
558  s += fwrite(&l->out_h, sizeof(int), 1, fp);
559  s += fwrite(&l->out_w, sizeof(int), 1, fp);
560  s += fwrite(&l->out_c, sizeof(int), 1, fp);
561  s += fwrite(&l->n_biases, sizeof(int), 1, fp);
562  s += fwrite(&l->n_outputs, sizeof(int), 1, fp);
563  s += fwrite(&l->n_inputs, sizeof(int), 1, fp);
564  s += fwrite(&l->max_outputs, sizeof(int), 1, fp);
565  s += fwrite(&l->n_weights, sizeof(int), 1, fp);
566  s += fwrite(&l->n_active, sizeof(int), 1, fp);
567  s += fwrite(&l->eta, sizeof(double), 1, fp);
568  s += fwrite(&l->eta_max, sizeof(double), 1, fp);
569  s += fwrite(&l->eta_min, sizeof(double), 1, fp);
570  s += fwrite(&l->momentum, sizeof(double), 1, fp);
571  s += fwrite(&l->decay, sizeof(double), 1, fp);
572  s += fwrite(&l->max_neuron_grow, sizeof(int), 1, fp);
573  s += fwrite(l->weights, sizeof(double), l->n_weights, fp);
574  s += fwrite(l->weight_updates, sizeof(double), l->n_weights, fp);
575  s += fwrite(l->weight_active, sizeof(bool), l->n_weights, fp);
576  s += fwrite(l->biases, sizeof(double), l->n_biases, fp);
577  s += fwrite(l->bias_updates, sizeof(double), l->n_filters, fp);
578  s += fwrite(l->mu, sizeof(double), N_MU, fp);
579  return s;
580 }
581 
588 size_t
590 {
591  size_t s = 0;
592  s += fread(&l->options, sizeof(uint32_t), 1, fp);
593  s += fread(&l->function, sizeof(int), 1, fp);
594  s += fread(&l->height, sizeof(int), 1, fp);
595  s += fread(&l->width, sizeof(int), 1, fp);
596  s += fread(&l->channels, sizeof(int), 1, fp);
597  s += fread(&l->n_filters, sizeof(int), 1, fp);
598  s += fread(&l->stride, sizeof(int), 1, fp);
599  s += fread(&l->size, sizeof(int), 1, fp);
600  s += fread(&l->pad, sizeof(int), 1, fp);
601  s += fread(&l->out_h, sizeof(int), 1, fp);
602  s += fread(&l->out_w, sizeof(int), 1, fp);
603  s += fread(&l->out_c, sizeof(int), 1, fp);
604  s += fread(&l->n_biases, sizeof(int), 1, fp);
605  s += fread(&l->n_outputs, sizeof(int), 1, fp);
606  s += fread(&l->n_inputs, sizeof(int), 1, fp);
607  s += fread(&l->max_outputs, sizeof(int), 1, fp);
608  s += fread(&l->n_weights, sizeof(int), 1, fp);
609  s += fread(&l->n_active, sizeof(int), 1, fp);
610  s += fread(&l->eta, sizeof(double), 1, fp);
611  s += fread(&l->eta_max, sizeof(double), 1, fp);
612  s += fread(&l->eta_min, sizeof(double), 1, fp);
613  s += fread(&l->momentum, sizeof(double), 1, fp);
614  s += fread(&l->decay, sizeof(double), 1, fp);
615  s += fread(&l->max_neuron_grow, sizeof(int), 1, fp);
617  s += fread(l->weights, sizeof(double), l->n_weights, fp);
618  s += fread(l->weight_updates, sizeof(double), l->n_weights, fp);
619  s += fread(l->weight_active, sizeof(bool), l->n_weights, fp);
620  s += fread(l->biases, sizeof(double), l->n_biases, fp);
621  s += fread(l->bias_updates, sizeof(double), l->n_biases, fp);
622  s += fread(l->mu, sizeof(double), N_MU, fp);
623  return s;
624 }
void blas_scal(const int N, const double ALPHA, double *X, const int INCX)
Scales vector X by the scalar ALPHA and overwrites it with the result.
Definition: blas.c:160
double blas_sum(const double *X, const int N)
Returns the sum of the vector X.
Definition: blas.c:232
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_gemm(const int TA, const int TB, const int M, const int N, const int K, const double ALPHA, const double *A, const int lda, const double *B, const int ldb, const double BETA, double *C, const int ldc)
Performs the matrix-matrix multiplication: .
Definition: blas.c:108
Basic linear algebra functions.
void im2col(const double *data_im, const int channels, const int height, const int width, const int ksize, const int stride, const int pad, double *data_col)
Transforms an image vector to a column vector.
Definition: image.c:100
void col2im(const double *data_col, const int channels, const int height, const int width, const int ksize, const int stride, const int pad, double *data_im)
Transforms a column vector to an image vector.
Definition: image.c:63
Image handling 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.
void layer_guard_biases(const struct Layer *l)
Check number of biases is within bounds.
Definition: neural_layer.c:581
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
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_weight_clamp(const struct Layer *l)
Clamps a layer's weights and biases in range [WEIGHT_MIN, WEIGHT_MAX].
Definition: neural_layer.c:365
void layer_guard_outputs(const struct Layer *l)
Check number of outputs is within bounds.
Definition: neural_layer.c:595
void layer_weight_rand(struct Layer *l)
Randomises a layer's weights and biases.
Definition: neural_layer.c:348
void layer_calc_n_active(struct Layer *l)
Recalculates the number of active connections within a layer.
Definition: neural_layer.c:384
void layer_init_eta(struct Layer *l)
Initialises a layer's gradient descent rate.
Definition: neural_layer.c:399
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
void layer_guard_weights(const struct Layer *l)
Check number of weights is within bounds.
Definition: neural_layer.c:609
#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
#define WEIGHT_SD_INIT
Std dev of Gaussian for weight initialisation.
Definition: neural_layer.h:66
#define LAYER_EVOLVE_WEIGHTS
Layer may evolve weights.
Definition: neural_layer.h:51
#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
#define WEIGHT_SD
Std dev of Gaussian for weight resizing.
Definition: neural_layer.h:67
#define LAYER_SGD_WEIGHTS
Layer may perform gradient descent.
Definition: neural_layer.h:54
#define CONVOLUTIONAL
Layer type convolutional.
Definition: neural_layer.h:36
static void layer_print(const struct Layer *l, const bool print_weights)
Prints the layer.
Definition: neural_layer.h:270
uint32_t layer_args_opt(const struct ArgsLayer *args)
Returns a bitstring representing the permissions granted by a layer.
static int get_out_width(const struct Layer *l)
Returns the output width of a convolutional layer.
double * neural_layer_convolutional_output(const struct Layer *l)
Returns the output from a convolutional layer.
void neural_layer_convolutional_update(const struct Layer *l)
Updates the weights and biases of a convolutional layer.
void neural_layer_convolutional_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates a convolutional layer.
void neural_layer_convolutional_resize(struct Layer *l, const struct Layer *prev)
Resizes a convolutional layer if the previous layer has changed size.
static void malloc_layer_arrays(struct Layer *l)
Allocate memory used by a convolutional layer.
static void realloc_layer_arrays(struct Layer *l)
Resize memory used by a convolutional layer.
#define N_MU
Number of mutation rates applied to a convolutional layer.
struct Layer * neural_layer_convolutional_copy(const struct Layer *src)
Initialises and copies one convolutional layer from another.
void neural_layer_convolutional_print(const struct Layer *l, const bool print_weights)
Prints a convolutional layer.
static size_t get_workspace_size(const struct Layer *l)
Returns the memory workspace size for a convolutional layer.
bool neural_layer_convolutional_mutate(struct Layer *l)
Mutates a convolutional layer.
static const int MU_TYPE[(6)]
Self-adaptation method for mutating a convolutional layer.
void neural_layer_convolutional_free(const struct Layer *l)
Free memory used by a convolutional layer.
static int get_out_height(const struct Layer *l)
Returns the output height of a convolutional layer.
size_t neural_layer_convolutional_save(const struct Layer *l, FILE *fp)
Writes a convolutional layer to a file.
static void neural_layer_convolutional_add_filters(struct Layer *l, const int N)
Adds N filters to a layer. Negative N removes filters.
static int neural_layer_convolutional_mutate_filter(const struct Layer *l, const double mu)
Returns the number of kernel filters to add or remove from a layer.
size_t neural_layer_convolutional_load(struct Layer *l, FILE *fp)
Reads a convolutional layer from a file.
static void guard_malloc(const struct Layer *l)
Check memory allocation is within bounds.
void neural_layer_convolutional_rand(struct Layer *l)
Randomises the weights of a convolutional layer.
void neural_layer_convolutional_init(struct Layer *l, const struct ArgsLayer *args)
Initialises a 2D convolutional layer.
void neural_layer_convolutional_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates a convolutional layer.
char * neural_layer_convolutional_json_export(const struct Layer *l, const bool return_weights)
Returns a json formatted string of a convolutional layer.
An implementation of a 2D convolutional 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 pad
Pool and Conv.
double eta_min
Current gradient descent rate.
int channels
Pool, Conv, and Upsample.
int n_max
Maximum number of units / neurons.
int size
Pool and Conv.
int width
Pool, Conv, and Upsample.
int height
Pool, Conv, and Upsample.
int stride
Pool, Conv, and Upsample.
Neural network layer data structure.
Definition: neural_layer.h:73
double * output
Current neuron outputs (after activation function)
Definition: neural_layer.h:76
double decay
Weight decay for gradient descent.
Definition: neural_layer.h:89
int size
Pool and Conv.
Definition: neural_layer.h:133
double * state
Current neuron states (before activation function)
Definition: neural_layer.h:75
int pad
Pool and Conv.
Definition: neural_layer.h:129
int max_neuron_grow
Maximum number neurons to add per mutation event.
Definition: neural_layer.h:93
int stride
Pool, Conv, and Upsample.
Definition: neural_layer.h:134
int n_inputs
Number of layer inputs.
Definition: neural_layer.h:90
int n_biases
Number of layer biases.
Definition: neural_layer.h:95
bool * weight_active
Whether each connection is present in the layer.
Definition: neural_layer.h:79
double * weights
Weights for calculating neuron states.
Definition: neural_layer.h:78
double * weight_updates
Updates to weights.
Definition: neural_layer.h:82
int n_filters
Conv.
Definition: neural_layer.h:136
double * mu
Mutation rates.
Definition: neural_layer.h:84
int channels
Pool, Conv, and Upsample.
Definition: neural_layer.h:128
int function
Layer activation function.
Definition: neural_layer.h:97
double * c
LSTM.
Definition: neural_layer.h:120
int height
Pool, Conv, and Upsample.
Definition: neural_layer.h:126
double * temp
LSTM.
Definition: neural_layer.h:122
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 width
Pool, Conv, and Upsample.
Definition: neural_layer.h:127
int n_weights
Number of layer weights.
Definition: neural_layer.h:94
double * bias_updates
Updates to biases.
Definition: neural_layer.h:81
double eta_max
Maximum gradient descent rate.
Definition: neural_layer.h:86
double * i
LSTM.
Definition: neural_layer.h:117
int n_outputs
Number of layer outputs.
Definition: neural_layer.h:91
double * biases
Biases for calculating neuron states.
Definition: neural_layer.h:80
int n_active
Number of active weights / connections.
Definition: neural_layer.h:96
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_min
Minimum gradient descent rate.
Definition: neural_layer.h:87
double eta
Gradient descent rate.
Definition: neural_layer.h:85
double momentum
Momentum for gradient descent.
Definition: neural_layer.h:88
Neural network data structure.
Definition: neural.h:48
double rand_normal(const double mu, const double sigma)
Returns a random Gaussian with specified mean and standard deviation.
Definition: utils.c:87
double rand_uniform(const double min, const double max)
Returns a uniform random float [min,max].
Definition: utils.c:62
Utility functions for random number handling, etc.
static double clamp(const double a, const double min, const double max)
Returns a float clamped within the specified range.
Definition: utils.h:60