XCSF 1.4.8
XCSF learning classifier system
Loading...
Searching...
No Matches
neural_layer_maxpool.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_activations.h"
26#include "utils.h"
27#include <float.h>
28
33static void
35{
37 l->indexes = calloc(l->n_outputs, sizeof(int));
38 l->output = calloc(l->n_outputs, sizeof(double));
39 l->delta = calloc(l->n_outputs, sizeof(double));
40}
41
46static void
48{
50 l->indexes = realloc(l->indexes, sizeof(int) * l->n_outputs);
51 l->output = realloc(l->output, sizeof(double) * l->n_outputs);
52 l->delta = realloc(l->delta, sizeof(double) * l->n_outputs);
53}
54
60void
61neural_layer_maxpool_init(struct Layer *l, const struct ArgsLayer *args)
62{
63 l->height = args->height;
64 l->width = args->width;
65 l->channels = args->channels;
66 l->pad = args->pad;
67 l->size = args->size;
68 l->stride = args->stride;
69 l->out_w = (l->width + l->pad - l->size) / l->stride + 1;
70 l->out_h = (l->height + l->pad - l->size) / l->stride + 1;
71 l->out_c = l->channels;
72 l->n_outputs = l->out_h * l->out_w * l->out_c;
73 l->max_outputs = l->n_outputs;
74 l->n_inputs = l->height * l->width * l->channels;
76}
77
83struct Layer *
85{
86 if (src->type != MAXPOOL) {
87 printf("neural_layer_maxpool_copy(): incorrect source layer type\n");
88 exit(EXIT_FAILURE);
89 }
90 struct Layer *l = malloc(sizeof(struct Layer));
92 l->type = src->type;
93 l->layer_vptr = src->layer_vptr;
94 l->height = src->height;
95 l->width = src->width;
96 l->channels = src->channels;
97 l->pad = src->pad;
98 l->size = src->size;
99 l->stride = src->stride;
100 l->out_w = src->out_w;
101 l->out_h = src->out_h;
102 l->out_c = src->out_c;
103 l->n_outputs = src->n_outputs;
104 l->max_outputs = src->max_outputs;
105 l->n_inputs = src->n_inputs;
107 return l;
108}
109
114void
116{
117 free(l->indexes);
118 free(l->output);
119 free(l->delta);
120}
121
126void
128{
129 (void) l;
130}
131
142static int
143max_pool(const struct Layer *l, const double *input, const int i, const int j,
144 const int k)
145{
146 const int w_offset = -l->pad / 2;
147 const int h_offset = w_offset;
148 double max = -DBL_MAX;
149 int max_index = -1;
150 for (int n = 0; n < l->size; ++n) {
151 for (int m = 0; m < l->size; ++m) {
152 const int cur_h = h_offset + i * l->stride + n;
153 const int cur_w = w_offset + j * l->stride + m;
154 const int index = cur_w + l->width * (cur_h + l->height * k);
155 if (cur_h >= 0 && cur_h < l->height && cur_w >= 0 &&
156 cur_w < l->width && index < l->n_inputs && input[index] > max) {
157 max_index = index;
158 max = input[index];
159 }
160 }
161 }
162 if (max_index < 0 || max_index >= l->n_inputs) {
163 printf("max_pool() error: invalid max_index: (%d)\n", max_index);
164 layer_print(l, false);
165 exit(EXIT_FAILURE);
166 }
167 return max_index;
168}
169
176void
177neural_layer_maxpool_forward(const struct Layer *l, const struct Net *net,
178 const double *input)
179{
180 (void) net;
181 for (int k = 0; k < l->channels; ++k) {
182 for (int i = 0; i < l->out_h; ++i) {
183 for (int j = 0; j < l->out_w; ++j) {
184 const int out_index = j + l->out_w * (i + l->out_h * k);
185 if (out_index < l->n_outputs) {
186 const int max_index = max_pool(l, input, i, j, k);
187 l->indexes[out_index] = max_index;
188 l->output[out_index] = input[max_index];
189 }
190 }
191 }
192 }
193}
194
202void
203neural_layer_maxpool_backward(const struct Layer *l, const struct Net *net,
204 const double *input, double *delta)
205{
206 (void) net;
207 (void) input;
208 if (delta) {
209 for (int i = 0; i < l->n_outputs; ++i) {
210 delta[l->indexes[i]] += l->delta[i];
211 }
212 }
213}
214
219void
221{
222 (void) l;
223}
224
230bool
232{
233 (void) l;
234 return false;
235}
236
242void
243neural_layer_maxpool_resize(struct Layer *l, const struct Layer *prev)
244{
245 const int w = prev->out_w;
246 const int h = prev->out_h;
247 const int c = prev->out_c;
248 l->height = h;
249 l->width = w;
250 l->channels = c;
251 l->n_inputs = h * w * c;
252 l->out_w = (w + l->pad - l->size) / l->stride + 1;
253 l->out_h = (h + l->pad - l->size) / l->stride + 1;
254 l->out_c = c;
255 l->n_outputs = l->out_h * l->out_w * l->out_c;
256 l->max_outputs = l->n_outputs;
258}
259
265double *
267{
268 return l->output;
269}
270
276void
277neural_layer_maxpool_print(const struct Layer *l, const bool print_weights)
278{
279 char *json_str = neural_layer_maxpool_json_export(l, print_weights);
280 printf("%s\n", json_str);
281 free(json_str);
282}
283
291char *
293 const bool return_weights)
294{
295 (void) return_weights;
296 cJSON *json = cJSON_CreateObject();
297 cJSON_AddStringToObject(json, "type", "maxpool");
298 cJSON_AddNumberToObject(json, "n_inputs", l->n_inputs);
299 cJSON_AddNumberToObject(json, "n_outputs", l->n_outputs);
300 cJSON_AddNumberToObject(json, "height", l->height);
301 cJSON_AddNumberToObject(json, "width", l->width);
302 cJSON_AddNumberToObject(json, "channels", l->channels);
303 cJSON_AddNumberToObject(json, "size", l->size);
304 cJSON_AddNumberToObject(json, "stride", l->stride);
305 cJSON_AddNumberToObject(json, "pad", l->pad);
306 cJSON_AddNumberToObject(json, "out_w", l->out_w);
307 cJSON_AddNumberToObject(json, "out_h", l->out_h);
308 cJSON_AddNumberToObject(json, "out_c", l->out_c);
309 char *string = cJSON_Print(json);
310 cJSON_Delete(json);
311 return string;
312}
313
320size_t
321neural_layer_maxpool_save(const struct Layer *l, FILE *fp)
322{
323 size_t s = 0;
324 s += fwrite(&l->height, sizeof(int), 1, fp);
325 s += fwrite(&l->width, sizeof(int), 1, fp);
326 s += fwrite(&l->channels, sizeof(int), 1, fp);
327 s += fwrite(&l->pad, sizeof(int), 1, fp);
328 s += fwrite(&l->out_w, sizeof(int), 1, fp);
329 s += fwrite(&l->out_h, sizeof(int), 1, fp);
330 s += fwrite(&l->out_c, sizeof(int), 1, fp);
331 s += fwrite(&l->n_outputs, sizeof(int), 1, fp);
332 s += fwrite(&l->max_outputs, sizeof(int), 1, fp);
333 s += fwrite(&l->n_inputs, sizeof(int), 1, fp);
334 s += fwrite(&l->size, sizeof(int), 1, fp);
335 s += fwrite(&l->stride, sizeof(int), 1, fp);
336 return s;
337}
338
345size_t
347{
348 size_t s = 0;
349 s += fread(&l->height, sizeof(int), 1, fp);
350 s += fread(&l->width, sizeof(int), 1, fp);
351 s += fread(&l->channels, sizeof(int), 1, fp);
352 s += fread(&l->pad, sizeof(int), 1, fp);
353 s += fread(&l->out_w, sizeof(int), 1, fp);
354 s += fread(&l->out_h, sizeof(int), 1, fp);
355 s += fread(&l->out_c, sizeof(int), 1, fp);
356 s += fread(&l->n_outputs, sizeof(int), 1, fp);
357 s += fread(&l->max_outputs, sizeof(int), 1, fp);
358 s += fread(&l->n_inputs, sizeof(int), 1, fp);
359 s += fread(&l->size, sizeof(int), 1, fp);
360 s += fread(&l->stride, sizeof(int), 1, fp);
362 return s;
363}
Neural network activation functions.
void layer_defaults(struct Layer *l)
Initialises a layer to default values.
void layer_guard_outputs(const struct Layer *l)
Check number of outputs is within bounds.
#define MAXPOOL
Layer type maxpooling.
static void layer_print(const struct Layer *l, const bool print_weights)
Prints the layer.
static int max_pool(const struct Layer *l, const double *input, const int i, const int j, const int k)
Returns the index of the maximum input value corresponding to a specified output height,...
void neural_layer_maxpool_print(const struct Layer *l, const bool print_weights)
Prints a maxpooling layer.
void neural_layer_maxpool_init(struct Layer *l, const struct ArgsLayer *args)
Initialises a 2D maxpooling layer.
void neural_layer_maxpool_rand(struct Layer *l)
Dummy function since maxpooling layers have no weights.
void neural_layer_maxpool_resize(struct Layer *l, const struct Layer *prev)
Resizes a maxpooling layer if the previous layer has changed size.
double * neural_layer_maxpool_output(const struct Layer *l)
Returns the output from a maxpooling layer.
void neural_layer_maxpool_update(const struct Layer *l)
Dummy function since a maxpooling layer has no weights.
struct Layer * neural_layer_maxpool_copy(const struct Layer *src)
Initialises and creates a copy of one maxpooling layer from another.
void neural_layer_maxpool_free(const struct Layer *l)
Free memory used by a maxpooling layer.
bool neural_layer_maxpool_mutate(struct Layer *l)
Dummy function since a maxpooling layer cannot be mutated.
static void malloc_layer_arrays(struct Layer *l)
Allocate memory used by a maxpooling layer.
static void realloc_layer_arrays(struct Layer *l)
Resize memory used by a maxpooling layer.
size_t neural_layer_maxpool_save(const struct Layer *l, FILE *fp)
Writes a maxpooling layer to a file.
void neural_layer_maxpool_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates a maxpooling layer.
size_t neural_layer_maxpool_load(struct Layer *l, FILE *fp)
Reads a maxpooling layer from a file.
void neural_layer_maxpool_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates a maxpooling layer.
char * neural_layer_maxpool_json_export(const struct Layer *l, const bool return_weights)
Returns a json formatted string representation of a maxpooling layer.
An implementation of a 2D maxpooling layer.
Parameters for initialising a neural network layer.
int pad
Pool and Conv.
int channels
Pool, Conv, and Upsample.
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.
double * output
Current neuron outputs (after activation function)
int size
Pool and Conv.
int pad
Pool and Conv.
int stride
Pool, Conv, and Upsample.
int n_inputs
Number of layer inputs.
int channels
Pool, Conv, and Upsample.
double * c
LSTM.
int height
Pool, Conv, and Upsample.
struct LayerVtbl const * layer_vptr
Functions acting on layers.
int max_outputs
Maximum number of neurons in the layer.
double * h
LSTM.
int width
Pool, Conv, and Upsample.
double * i
LSTM.
int n_outputs
Number of layer outputs.
int out_w
Pool, Conv, and Upsample.
int type
Layer type: CONNECTED, DROPOUT, etc.
int out_c
Pool, Conv, and Upsample.
int * indexes
Pool.
double * delta
Delta for updating weights.
int out_h
Pool, Conv, and Upsample.
Neural network data structure.
Definition neural.h:48
Utility functions for random number handling, etc.