XCSF  1.4.7
XCSF learning classifier system
pred_neural.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 
24 #include "pred_neural.h"
25 #include "neural_activations.h"
26 #include "neural_layer_avgpool.h"
27 #include "neural_layer_connected.h"
29 #include "neural_layer_dropout.h"
30 #include "neural_layer_lstm.h"
31 #include "neural_layer_maxpool.h"
32 #include "neural_layer_noise.h"
33 #include "neural_layer_recurrent.h"
34 #include "neural_layer_softmax.h"
35 #include "neural_layer_upsample.h"
36 #include "utils.h"
37 
44 void
45 pred_neural_init(const struct XCSF *xcsf, struct Cl *c)
46 {
47  struct PredNeural *new = malloc(sizeof(struct PredNeural));
48  neural_create(&new->net, xcsf->pred->largs);
49  c->pred = new;
50 }
51 
57 void
58 pred_neural_free(const struct XCSF *xcsf, const struct Cl *c)
59 {
60  (void) xcsf;
61  struct PredNeural *pred = c->pred;
62  neural_free(&pred->net);
63  free(pred);
64 }
65 
72 void
73 pred_neural_copy(const struct XCSF *xcsf, struct Cl *dest, const struct Cl *src)
74 {
75  (void) xcsf;
76  struct PredNeural *new = malloc(sizeof(struct PredNeural));
77  const struct PredNeural *src_pred = src->pred;
78  neural_copy(&new->net, &src_pred->net);
79  dest->pred = new;
80 }
81 
90 void
91 pred_neural_update(const struct XCSF *xcsf, const struct Cl *c, const double *x,
92  const double *y)
93 {
94  (void) xcsf;
95  const struct PredNeural *pred = c->pred;
96  neural_learn(&pred->net, y, x);
97 }
98 
105 void
106 pred_neural_compute(const struct XCSF *xcsf, const struct Cl *c,
107  const double *x)
108 {
109  struct PredNeural *pred = c->pred;
110  neural_propagate(&pred->net, x, xcsf->explore);
111  for (int i = 0; i < xcsf->y_dim; ++i) {
112  c->prediction[i] = neural_output(&pred->net, i);
113  }
114 }
115 
121 void
122 pred_neural_print(const struct XCSF *xcsf, const struct Cl *c)
123 {
124  char *json_str = pred_neural_json_export(xcsf, c);
125  printf("%s\n", json_str);
126  free(json_str);
127 }
128 
136 bool
137 pred_neural_crossover(const struct XCSF *xcsf, const struct Cl *c1,
138  const struct Cl *c2)
139 {
140  (void) xcsf;
141  (void) c1;
142  (void) c2;
143  return false;
144 }
145 
152 bool
153 pred_neural_mutate(const struct XCSF *xcsf, const struct Cl *c)
154 {
155  (void) xcsf;
156  const struct PredNeural *pred = c->pred;
157  return neural_mutate(&pred->net);
158 }
159 
167 double
168 pred_neural_size(const struct XCSF *xcsf, const struct Cl *c)
169 {
170  (void) xcsf;
171  const struct PredNeural *pred = c->pred;
172  return neural_size(&pred->net);
173 }
174 
182 size_t
183 pred_neural_save(const struct XCSF *xcsf, const struct Cl *c, FILE *fp)
184 {
185  (void) xcsf;
186  const struct PredNeural *pred = c->pred;
187  size_t s = neural_save(&pred->net, fp);
188  return s;
189 }
190 
198 size_t
199 pred_neural_load(const struct XCSF *xcsf, struct Cl *c, FILE *fp)
200 {
201  (void) xcsf;
202  struct PredNeural *new = malloc(sizeof(struct PredNeural));
203  size_t s = neural_load(&new->net, fp);
204  c->pred = new;
205  return s;
206 }
207 
215 double
216 pred_neural_eta(const struct XCSF *xcsf, const struct Cl *c, const int layer)
217 {
218  (void) xcsf;
219  const struct PredNeural *pred = c->pred;
220  const struct Llist *iter = pred->net.tail;
221  int i = 0;
222  while (iter != NULL) {
223  if (i == layer) {
224  return iter->layer->eta;
225  }
226  iter = iter->prev;
227  ++i;
228  }
229  return 0;
230 }
231 
239 int
240 pred_neural_neurons(const struct XCSF *xcsf, const struct Cl *c,
241  const int layer)
242 {
243  (void) xcsf;
244  const struct PredNeural *pred = c->pred;
245  const struct Llist *iter = pred->net.tail;
246  int i = 0;
247  while (iter != NULL) {
248  if (i == layer) {
249  if (iter->layer->type == CONVOLUTIONAL) {
250  return iter->layer->n_filters;
251  }
252  return iter->layer->n_outputs;
253  }
254  iter = iter->prev;
255  ++i;
256  }
257  return 0;
258 }
259 
267 int
268 pred_neural_connections(const struct XCSF *xcsf, const struct Cl *c,
269  const int layer)
270 {
271  (void) xcsf;
272  const struct PredNeural *pred = c->pred;
273  const struct Llist *iter = pred->net.tail;
274  int i = 0;
275  while (iter != NULL) {
276  if (i == layer) {
277  return iter->layer->n_active;
278  }
279  iter = iter->prev;
280  ++i;
281  }
282  return 0;
283 }
284 
291 int
292 pred_neural_layers(const struct XCSF *xcsf, const struct Cl *c)
293 {
294  (void) xcsf;
295  const struct PredNeural *pred = c->pred;
296  const struct Net *net = &pred->net;
297  return net->n_layers;
298 }
299 
305 void
306 pred_neural_expand(const struct XCSF *xcsf, const struct Cl *c)
307 {
308  struct PredNeural *pred = c->pred;
309  struct Net *net = &pred->net;
310  const struct Layer *h = NULL;
311  int n_inputs = 0;
312  if (net->n_layers > 1) { // select top hidden layer
313  h = net->head->next->layer;
314  n_inputs = h->n_outputs;
315  } else { // if only one layer, must use output layer
316  h = net->head->layer;
317  n_inputs = h->n_inputs;
318  }
319  const struct ArgsLayer *largs = xcsf->pred->largs;
320  struct ArgsLayer new;
321  layer_args_init(&new);
322  new.type = CONNECTED;
323  new.function = largs->function;
324  new.n_inputs = n_inputs;
325  new.n_init = h->n_outputs;
326  new.n_max = h->max_outputs;
327  new.evolve_connect = largs->evolve_connect;
328  new.evolve_weights = largs->evolve_weights;
329  new.evolve_functions = largs->evolve_functions;
330  new.evolve_eta = largs->evolve_eta;
331  new.sgd_weights = largs->sgd_weights;
332  new.eta = largs->eta;
333  new.eta_min = largs->eta_min;
334  new.momentum = largs->momentum;
335  new.decay = largs->decay;
336  struct Layer *l = layer_init(&new);
337  const int pos = net->n_layers - 1;
338  neural_insert(net, l, pos);
339  neural_resize(net);
340 }
341 
348 void
349 pred_neural_ae_to_classifier(const struct XCSF *xcsf, const struct Cl *c,
350  const int n_del)
351 {
352  struct PredNeural *pred = c->pred;
353  struct Net *net = &pred->net;
354  struct Layer *l = NULL;
355  // remove decoder layers
356  for (int i = 0; i < n_del && net->n_layers > 1; ++i) {
357  neural_pop(net);
358  }
359  // add new softmax output
360  const struct ArgsLayer *largs = xcsf->pred->largs;
361  struct ArgsLayer new;
362  layer_args_init(&new);
363  new.type = CONNECTED;
364  new.function = LINEAR;
365  new.n_inputs = net->n_outputs;
366  new.n_init = xcsf->y_dim;
367  new.n_max = xcsf->y_dim;
368  new.evolve_connect = largs->evolve_connect;
369  new.evolve_weights = largs->evolve_weights;
370  new.evolve_eta = largs->evolve_eta;
371  new.sgd_weights = largs->sgd_weights;
372  new.eta = largs->eta;
373  new.eta_min = largs->eta_min;
374  new.momentum = largs->momentum;
375  new.decay = largs->decay;
376  l = layer_init(&new);
377  neural_push(net, l);
378  new.type = SOFTMAX;
379  new.n_inputs = xcsf->y_dim;
380  new.scale = 1;
381  l = layer_init(&new);
382  neural_push(net, l);
383 }
384 
391 char *
392 pred_neural_json_export(const struct XCSF *xcsf, const struct Cl *c)
393 {
394  (void) xcsf;
395  const struct PredNeural *pred = c->pred;
396  cJSON *json = cJSON_CreateObject();
397  cJSON_AddStringToObject(json, "type", "neural");
398  char *network_str = neural_json_export(&pred->net, false);
399  cJSON *network = cJSON_Parse(network_str);
400  free(network_str);
401  cJSON_AddItemToObject(json, "network", network);
402  char *string = cJSON_Print(json);
403  cJSON_Delete(json);
404  return string;
405 }
406 
413 void
414 pred_neural_json_import(const struct XCSF *xcsf, struct Cl *c,
415  const cJSON *json)
416 {
417  const cJSON *item = cJSON_GetObjectItem(json, "network");
418  if (item == NULL) {
419  printf("Import error: missing network\n");
420  exit(EXIT_FAILURE);
421  }
422  struct PredNeural *pred = c->pred;
423  neural_json_import(&pred->net, xcsf->pred->largs, item);
424 }
425 
430 void
432 {
433  // hidden layer
434  struct ArgsLayer *la = malloc(sizeof(struct ArgsLayer));
435  layer_args_init(la);
436  la->type = CONNECTED;
437  la->n_inputs = xcsf->x_dim;
438  la->n_init = 10;
439  la->n_max = 100;
440  la->max_neuron_grow = 1;
441  la->function = LOGISTIC;
442  la->evolve_weights = true;
443  la->evolve_neurons = true;
444  la->evolve_connect = true;
445  la->evolve_eta = true;
446  la->sgd_weights = true;
447  la->eta = 0.01;
448  la->momentum = 0.9;
449  xcsf->pred->largs = la;
450  // output layer
451  la->next = layer_args_copy(la);
452  la->next->n_inputs = la->n_init;
453  la->next->n_init = xcsf->y_dim;
454  la->next->n_max = xcsf->y_dim;
455  la->next->evolve_neurons = false;
456 }
457 
464 char *
466 {
467  layer_args_free(&xcsf->pred->largs);
468  for (cJSON *iter = json; iter != NULL; iter = iter->next) {
469  struct ArgsLayer *larg = malloc(sizeof(struct ArgsLayer));
470  layer_args_init(larg);
471  larg->n_inputs = xcsf->x_dim;
472  char *ret = layer_args_json_import(larg, iter->child);
473  if (ret != NULL) {
474  return ret;
475  }
476  if (xcsf->pred->largs == NULL) {
477  xcsf->pred->largs = larg;
478  } else {
479  struct ArgsLayer *layer_iter = xcsf->pred->largs;
480  while (layer_iter->next != NULL) {
481  layer_iter = layer_iter->next;
482  }
483  layer_iter->next = larg;
484  }
485  }
486  layer_args_validate(xcsf->pred->largs);
487  return NULL;
488 }
Definition: __init__.py:1
void neural_push(struct Net *net, struct Layer *l)
Inserts a layer at the head of a neural network.
Definition: neural.c:187
bool neural_mutate(const struct Net *net)
Mutates a neural network.
Definition: neural.c:257
double neural_size(const struct Net *net)
Returns the total number of non-zero weights in a neural network.
Definition: neural.c:450
void neural_create(struct Net *net, struct ArgsLayer *arg)
Initialises and creates a new neural network from a parameter list.
Definition: neural.c:54
double neural_output(const struct Net *net, const int IDX)
Returns the output of a specified neuron in the output layer of a neural network.
Definition: neural.c:369
void neural_resize(const struct Net *net)
Resizes neural network layers as necessary.
Definition: neural.c:290
size_t neural_load(struct Net *net, FILE *fp)
Reads a neural network from a file.
Definition: neural.c:499
void neural_json_import(struct Net *net, const struct ArgsLayer *arg, const cJSON *json)
Creates a neural network from a cJSON object.
Definition: neural.c:434
void neural_learn(const struct Net *net, const double *truth, const double *input)
Performs a gradient descent update on a neural network.
Definition: neural.c:328
void neural_free(struct Net *net)
Frees a neural network.
Definition: neural.c:224
void neural_copy(struct Net *dest, const struct Net *src)
Copies a neural network.
Definition: neural.c:208
void neural_propagate(struct Net *net, const double *input, const bool train)
Forward propagates a neural network.
Definition: neural.c:310
char * neural_json_export(const struct Net *net, const bool return_weights)
Returns a json formatted string representation of a neural network.
Definition: neural.c:407
void neural_pop(struct Net *net)
Removes the layer at the head of a neural network.
Definition: neural.c:197
size_t neural_save(const struct Net *net, FILE *fp)
Writes a neural network to a file.
Definition: neural.c:478
void neural_insert(struct Net *net, struct Layer *l, const int pos)
Inserts a layer into a neural network.
Definition: neural.c:95
Neural network activation functions.
#define LOGISTIC
Logistic [0,1].
#define LINEAR
Linear [-inf,inf].
static struct Layer * layer_init(const struct ArgsLayer *args)
Creates and initialises a new layer.
Definition: neural_layer.h:356
#define SOFTMAX
Layer type softmax.
Definition: neural_layer.h:32
#define CONVOLUTIONAL
Layer type convolutional.
Definition: neural_layer.h:36
#define CONNECTED
Layer type connected.
Definition: neural_layer.h:29
void layer_args_init(struct ArgsLayer *args)
Sets layer parameters to default values.
char * layer_args_json_import(struct ArgsLayer *args, cJSON *json)
Sets the layer parameters from a cJSON object.
void layer_args_free(struct ArgsLayer **largs)
Frees memory used by a list of layer parameters and points to NULL.
void layer_args_validate(struct ArgsLayer *args)
Checks network layer arguments are valid.
struct ArgsLayer * layer_args_copy(const struct ArgsLayer *src)
Creates and returns a copy of specified layer parameters.
An implementation of an average pooling layer.
An implementation of a fully-connected layer of perceptrons.
An implementation of a 2D convolutional layer.
An implementation of a dropout layer.
An implementation of a long short-term memory layer.
An implementation of a 2D maxpooling layer.
An implementation of a Gaussian noise adding layer.
An implementation of a recurrent layer of perceptrons.
An implementation of a softmax layer.
An implementation of a 2D upsampling layer.
int pred_neural_layers(const struct XCSF *xcsf, const struct Cl *c)
Returns the number of layers within a neural network prediction.
Definition: pred_neural.c:292
bool pred_neural_mutate(const struct XCSF *xcsf, const struct Cl *c)
Mutates a neural network prediction.
Definition: pred_neural.c:153
char * pred_neural_json_export(const struct XCSF *xcsf, const struct Cl *c)
Returns a json formatted string representation of a neural prediction.
Definition: pred_neural.c:392
size_t pred_neural_save(const struct XCSF *xcsf, const struct Cl *c, FILE *fp)
Writes a neural network prediction to a file.
Definition: pred_neural.c:183
int pred_neural_connections(const struct XCSF *xcsf, const struct Cl *c, const int layer)
Returns the number of active connections in a neural prediction layer.
Definition: pred_neural.c:268
void pred_neural_compute(const struct XCSF *xcsf, const struct Cl *c, const double *x)
Forward propagates a neural network prediction with a provided input.
Definition: pred_neural.c:106
void pred_neural_print(const struct XCSF *xcsf, const struct Cl *c)
Prints a neural network prediction.
Definition: pred_neural.c:122
void pred_neural_free(const struct XCSF *xcsf, const struct Cl *c)
Frees the memory used by a neural network prediction.
Definition: pred_neural.c:58
void pred_neural_init(const struct XCSF *xcsf, struct Cl *c)
Creates and initialises a neural network prediction.
Definition: pred_neural.c:45
char * pred_neural_param_json_import(struct XCSF *xcsf, cJSON *json)
Sets the neural network parameters from a cJSON object.
Definition: pred_neural.c:465
int pred_neural_neurons(const struct XCSF *xcsf, const struct Cl *c, const int layer)
Returns the number of neurons in a neural prediction layer.
Definition: pred_neural.c:240
void pred_neural_ae_to_classifier(const struct XCSF *xcsf, const struct Cl *c, const int n_del)
Removes prediction (decoder) layers and inserts softmax output layer.
Definition: pred_neural.c:349
void pred_neural_json_import(const struct XCSF *xcsf, struct Cl *c, const cJSON *json)
Creates a neural prediction from a cJSON object.
Definition: pred_neural.c:414
void pred_neural_copy(const struct XCSF *xcsf, struct Cl *dest, const struct Cl *src)
Copies a neural network prediction from one classifier to another.
Definition: pred_neural.c:73
void pred_neural_expand(const struct XCSF *xcsf, const struct Cl *c)
Creates and inserts a hidden layer before the prediction output layer.
Definition: pred_neural.c:306
double pred_neural_eta(const struct XCSF *xcsf, const struct Cl *c, const int layer)
Returns the gradient descent rate of a neural prediction layer.
Definition: pred_neural.c:216
void pred_neural_update(const struct XCSF *xcsf, const struct Cl *c, const double *x, const double *y)
Backward propagates and updates a neural network prediction.
Definition: pred_neural.c:91
bool pred_neural_crossover(const struct XCSF *xcsf, const struct Cl *c1, const struct Cl *c2)
Dummy function since neural predictions do not perform crossover.
Definition: pred_neural.c:137
double pred_neural_size(const struct XCSF *xcsf, const struct Cl *c)
Returns the size of a neural network prediction.
Definition: pred_neural.c:168
void pred_neural_param_defaults(struct XCSF *xcsf)
Initialises default neural prediction parameters.
Definition: pred_neural.c:431
size_t pred_neural_load(const struct XCSF *xcsf, struct Cl *c, FILE *fp)
Reads a neural network prediction from a file.
Definition: pred_neural.c:199
Multi-layer perceptron neural network prediction functions.
Parameters for initialising a neural network layer.
_Bool evolve_weights
Ability to evolve weights.
int n_init
Initial number of units / neurons / filters.
_Bool evolve_neurons
Ability to evolve number of units.
_Bool sgd_weights
Ability to update weights with gradient descent.
_Bool evolve_functions
Ability to evolve activation function.
double decay
Weight decay for gradient descent.
double momentum
Momentum for gradient descent.
int function
Activation function.
_Bool evolve_eta
Ability to evolve gradient descent rate.
int max_neuron_grow
Maximum number neurons to add per mutation event.
double eta
Gradient descent rate.
double eta_min
Current gradient descent rate.
int n_max
Maximum number of units / neurons.
int n_inputs
Number of inputs.
int type
Layer type: CONNECTED, DROPOUT, etc.
struct ArgsLayer * next
Next layer parameters.
_Bool evolve_connect
Ability to evolve weight connectivity.
Classifier data structure.
Definition: xcsf.h:45
void * pred
Prediction structure.
Definition: xcsf.h:50
double * prediction
Current classifier prediction.
Definition: xcsf.h:59
Neural network layer data structure.
Definition: neural_layer.h:73
int n_inputs
Number of layer inputs.
Definition: neural_layer.h:90
int n_filters
Conv.
Definition: neural_layer.h:136
double * c
LSTM.
Definition: neural_layer.h:120
int max_outputs
Maximum number of neurons in the layer.
Definition: neural_layer.h:92
double * h
LSTM.
Definition: neural_layer.h:121
double * i
LSTM.
Definition: neural_layer.h:117
int n_outputs
Number of layer outputs.
Definition: neural_layer.h:91
int n_active
Number of active weights / connections.
Definition: neural_layer.h:96
int type
Layer type: CONNECTED, DROPOUT, etc.
Definition: neural_layer.h:74
double eta
Gradient descent rate.
Definition: neural_layer.h:85
Forward declaration of layer structure.
Definition: neural.h:39
struct Llist * prev
Pointer to the previous layer (forward)
Definition: neural.h:41
struct Layer * layer
Pointer to the layer data structure.
Definition: neural.h:40
struct Llist * next
Pointer to the next layer (backward)
Definition: neural.h:42
Neural network data structure.
Definition: neural.h:48
int n_layers
Number of layers (hidden + output)
Definition: neural.h:49
struct Llist * tail
Pointer to the tail layer (first layer)
Definition: neural.h:54
struct Llist * head
Pointer to the head layer (output layer)
Definition: neural.h:53
int n_outputs
Number of network outputs.
Definition: neural.h:51
Multi-layer perceptron neural network prediction data structure.
Definition: pred_neural.h:35
struct Net net
Neural network.
Definition: pred_neural.h:36
XCSF data structure.
Definition: xcsf.h:85
Utility functions for random number handling, etc.