XCSF  1.4.7
XCSF learning classifier system
neural_layer_upsample.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 "neural_layer_upsample.h"
25 #include "neural_activations.h"
26 #include "utils.h"
27 
32 static void
34 {
36  l->output = calloc(l->n_outputs, sizeof(double));
37  l->delta = calloc(l->n_outputs, sizeof(double));
38 }
39 
44 static void
45 free_layer_arrays(const struct Layer *l)
46 {
47  free(l->output);
48  free(l->delta);
49 }
50 
55 void
57 {
59 }
60 
66 void
67 neural_layer_upsample_init(struct Layer *l, const struct ArgsLayer *args)
68 {
69  l->height = args->height;
70  l->width = args->width;
71  l->channels = args->channels;
72  l->stride = args->stride;
73  l->out_c = args->channels;
74  l->out_w = l->width * l->stride;
75  l->out_h = l->height * l->stride;
76  l->n_outputs = l->out_h * l->out_w * l->out_c;
77  l->max_outputs = l->n_outputs;
78  l->n_inputs = l->height * l->width * l->channels;
80 }
81 
87 struct Layer *
89 {
90  if (src->type != UPSAMPLE) {
91  printf("neural_layer_upsample_copy(): incorrect source layer type\n");
92  exit(EXIT_FAILURE);
93  }
94  struct Layer *l = malloc(sizeof(struct Layer));
95  layer_defaults(l);
96  l->type = src->type;
97  l->layer_vptr = src->layer_vptr;
98  l->height = src->height;
99  l->width = src->width;
100  l->channels = src->channels;
101  l->out_w = src->out_w;
102  l->out_h = src->out_h;
103  l->out_c = src->out_c;
104  l->n_outputs = src->n_outputs;
105  l->max_outputs = src->max_outputs;
106  l->n_inputs = src->n_inputs;
107  l->stride = src->stride;
109  return l;
110 }
111 
116 void
118 {
119  (void) l;
120 }
121 
128 void
129 neural_layer_upsample_forward(const struct Layer *l, const struct Net *net,
130  const double *input)
131 {
132  (void) net;
133  const int w = l->width;
134  const int h = l->height;
135  const int c = l->channels;
136  const int s = l->stride;
137  for (int k = 0; k < c; ++k) {
138  for (int j = 0; j < h * s; ++j) {
139  for (int i = 0; i < w * s; ++i) {
140  const int in_index = k * w * h + (j / s) * w + i / s;
141  const int out_index = k * w * h * s * s + j * w * s + i;
142  l->output[out_index] = input[in_index];
143  }
144  }
145  }
146 }
147 
155 void
156 neural_layer_upsample_backward(const struct Layer *l, const struct Net *net,
157  const double *input, double *delta)
158 {
159  (void) net;
160  (void) input;
161  if (!delta) {
162  return;
163  }
164  const int w = l->width;
165  const int h = l->height;
166  const int c = l->channels;
167  const int s = l->stride;
168  for (int k = 0; k < c; ++k) {
169  for (int j = 0; j < h * s; ++j) {
170  for (int i = 0; i < w * s; ++i) {
171  const int in_index = k * w * h + (j / s) * w + i / s;
172  const int out_index = k * w * h * s * s + j * w * s + i;
173  delta[in_index] += l->delta[out_index];
174  }
175  }
176  }
177 }
178 
183 void
185 {
186  (void) l;
187 }
188 
194 bool
196 {
197  (void) l;
198  return false;
199 }
200 
206 void
207 neural_layer_upsample_resize(struct Layer *l, const struct Layer *prev)
208 {
209  l->width = prev->out_w;
210  l->height = prev->out_h;
211  l->channels = prev->out_c;
212  l->out_c = prev->out_c;
213  l->out_w = l->width * l->stride;
214  l->out_h = l->height * l->stride;
215  l->n_inputs = l->height * l->width * l->channels;
216  l->n_outputs = l->out_h * l->out_w * l->out_c;
217  l->max_outputs = l->n_outputs;
220 }
221 
227 double *
229 {
230  return l->output;
231 }
232 
238 void
239 neural_layer_upsample_print(const struct Layer *l, const bool print_weights)
240 {
241  char *json_str = neural_layer_upsample_json_export(l, print_weights);
242  printf("%s\n", json_str);
243  free(json_str);
244 }
245 
253 char *
255  const bool return_weights)
256 {
257  (void) return_weights;
258  cJSON *json = cJSON_CreateObject();
259  cJSON_AddStringToObject(json, "type", "upsample");
260  cJSON_AddNumberToObject(json, "n_inputs", l->n_inputs);
261  cJSON_AddNumberToObject(json, "n_outputs", l->n_outputs);
262  cJSON_AddNumberToObject(json, "height", l->height);
263  cJSON_AddNumberToObject(json, "width", l->width);
264  cJSON_AddNumberToObject(json, "channels", l->channels);
265  cJSON_AddNumberToObject(json, "stride", l->stride);
266  char *string = cJSON_Print(json);
267  cJSON_Delete(json);
268  return string;
269 }
270 
277 size_t
278 neural_layer_upsample_save(const struct Layer *l, FILE *fp)
279 {
280  size_t s = 0;
281  s += fwrite(&l->height, sizeof(int), 1, fp);
282  s += fwrite(&l->width, sizeof(int), 1, fp);
283  s += fwrite(&l->channels, sizeof(int), 1, fp);
284  s += fwrite(&l->out_w, sizeof(int), 1, fp);
285  s += fwrite(&l->out_h, sizeof(int), 1, fp);
286  s += fwrite(&l->out_c, sizeof(int), 1, fp);
287  s += fwrite(&l->n_outputs, sizeof(int), 1, fp);
288  s += fwrite(&l->max_outputs, sizeof(int), 1, fp);
289  s += fwrite(&l->n_inputs, sizeof(int), 1, fp);
290  s += fwrite(&l->stride, sizeof(int), 1, fp);
291  return s;
292 }
293 
300 size_t
301 neural_layer_upsample_load(struct Layer *l, FILE *fp)
302 {
303  size_t s = 0;
304  s += fread(&l->height, sizeof(int), 1, fp);
305  s += fread(&l->width, sizeof(int), 1, fp);
306  s += fread(&l->channels, sizeof(int), 1, fp);
307  s += fread(&l->out_w, sizeof(int), 1, fp);
308  s += fread(&l->out_h, sizeof(int), 1, fp);
309  s += fread(&l->out_c, sizeof(int), 1, fp);
310  s += fread(&l->n_outputs, sizeof(int), 1, fp);
311  s += fread(&l->max_outputs, sizeof(int), 1, fp);
312  s += fread(&l->n_inputs, sizeof(int), 1, fp);
313  s += fread(&l->stride, sizeof(int), 1, fp);
315  return s;
316 }
Neural network activation functions.
void layer_defaults(struct Layer *l)
Initialises a layer to default values.
Definition: neural_layer.c:413
void layer_guard_outputs(const struct Layer *l)
Check number of outputs is within bounds.
Definition: neural_layer.c:595
#define UPSAMPLE
Layer type upsample.
Definition: neural_layer.h:38
void neural_layer_upsample_print(const struct Layer *l, const bool print_weights)
Prints an upsampling layer.
void neural_layer_upsample_resize(struct Layer *l, const struct Layer *prev)
Resizes an upsampling layer if the previous layer has changed size.
double * neural_layer_upsample_output(const struct Layer *l)
Returns the output from an upsampling layer.
size_t neural_layer_upsample_save(const struct Layer *l, FILE *fp)
Writes an upsampling layer to a file.
void neural_layer_upsample_backward(const struct Layer *l, const struct Net *net, const double *input, double *delta)
Backward propagates an upsampling layer.
void neural_layer_upsample_free(const struct Layer *l)
Free memory used by an upsampling layer.
void neural_layer_upsample_forward(const struct Layer *l, const struct Net *net, const double *input)
Forward propagates an upsampling layer.
static void free_layer_arrays(const struct Layer *l)
Free memory used by an upsampling layer.
static void malloc_layer_arrays(struct Layer *l)
Allocate memory used by an upsampling layer.
void neural_layer_upsample_rand(struct Layer *l)
Dummy function since upsampling layers have no weights.
bool neural_layer_upsample_mutate(struct Layer *l)
Dummy function since upsampling layers cannot be mutated.
void neural_layer_upsample_update(const struct Layer *l)
Dummy function since upsampling layers have no weights.
void neural_layer_upsample_init(struct Layer *l, const struct ArgsLayer *args)
Initialises a 2D upsampling layer.
size_t neural_layer_upsample_load(struct Layer *l, FILE *fp)
Reads an upsampling layer from a file.
char * neural_layer_upsample_json_export(const struct Layer *l, const bool return_weights)
Returns a json formatted string representation of an upsample layer.
struct Layer * neural_layer_upsample_copy(const struct Layer *src)
Initialises and copies one upsampling layer from another.
An implementation of a 2D upsampling layer.
Parameters for initialising a neural network layer.
int channels
Pool, Conv, and Upsample.
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
int stride
Pool, Conv, and Upsample.
Definition: neural_layer.h:134
int n_inputs
Number of layer inputs.
Definition: neural_layer.h:90
int channels
Pool, Conv, and Upsample.
Definition: neural_layer.h:128
double * c
LSTM.
Definition: neural_layer.h:120
int height
Pool, Conv, and Upsample.
Definition: neural_layer.h:126
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
double * h
LSTM.
Definition: neural_layer.h:121
int width
Pool, Conv, and Upsample.
Definition: neural_layer.h:127
double * i
LSTM.
Definition: neural_layer.h:117
int n_outputs
Number of layer outputs.
Definition: neural_layer.h:91
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
int out_h
Pool, Conv, and Upsample.
Definition: neural_layer.h:131
Neural network data structure.
Definition: neural.h:48
Utility functions for random number handling, etc.