XCSF 1.4.8
XCSF learning classifier system
Loading...
Searching...
No Matches
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"
30#include "neural_layer_lstm.h"
32#include "neural_layer_noise.h"
36#include "utils.h"
37
44void
45pred_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
57void
58pred_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
72void
73pred_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
90void
91pred_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
105void
106pred_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
121void
122pred_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
136bool
137pred_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
152bool
153pred_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
167double
168pred_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
182size_t
183pred_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
198size_t
199pred_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
215double
216pred_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
239int
240pred_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
267int
268pred_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
291int
292pred_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
305void
306pred_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;
315 } else { // if only one layer, must use output layer
316 h = net->head->layer;
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
348void
349pred_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
391char *
392pred_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
413void
414pred_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
430void
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
464char *
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}
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
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
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
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].
#define SOFTMAX
Layer type softmax.
static struct Layer * layer_init(const struct ArgsLayer *args)
Creates and initialises a new layer.
#define CONVOLUTIONAL
Layer type convolutional.
#define CONNECTED
Layer type connected.
void layer_args_init(struct ArgsLayer *args)
Sets layer parameters to default values.
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.
char * layer_args_json_import(struct ArgsLayer *args, cJSON *json)
Sets the layer parameters from a cJSON object.
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.
char * pred_neural_param_json_import(struct XCSF *xcsf, cJSON *json)
Sets the neural network parameters from a cJSON object.
int pred_neural_layers(const struct XCSF *xcsf, const struct Cl *c)
Returns the number of layers within a neural network prediction.
bool pred_neural_mutate(const struct XCSF *xcsf, const struct Cl *c)
Mutates a neural network prediction.
size_t pred_neural_save(const struct XCSF *xcsf, const struct Cl *c, FILE *fp)
Writes a neural network prediction to a file.
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.
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.
void pred_neural_print(const struct XCSF *xcsf, const struct Cl *c)
Prints a neural network prediction.
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
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.
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.
void pred_neural_json_import(const struct XCSF *xcsf, struct Cl *c, const cJSON *json)
Creates a neural prediction from a cJSON object.
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.
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.
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.
double pred_neural_size(const struct XCSF *xcsf, const struct Cl *c)
Returns the size of a neural network prediction.
void pred_neural_param_defaults(struct XCSF *xcsf)
Initialises default neural prediction parameters.
size_t pred_neural_load(const struct XCSF *xcsf, struct Cl *c, FILE *fp)
Reads a neural network prediction from a file.
char * pred_neural_json_export(const struct XCSF *xcsf, const struct Cl *c)
Returns a json formatted string representation of a neural prediction.
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.
int n_inputs
Number of layer inputs.
int n_filters
Conv.
double * c
LSTM.
int max_outputs
Maximum number of neurons in the layer.
double * h
LSTM.
double * i
LSTM.
int n_outputs
Number of layer outputs.
int n_active
Number of active weights / connections.
int type
Layer type: CONNECTED, DROPOUT, etc.
double eta
Gradient descent rate.
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.