darknet  v3
normalization_layer.c
Go to the documentation of this file.
1 #include "normalization_layer.h"
2 #include "blas.h"
3 
4 #include <stdio.h>
5 
6 layer make_normalization_layer(int batch, int w, int h, int c, int size, float alpha, float beta, float kappa)
7 {
8  fprintf(stderr, "Local Response Normalization Layer: %d x %d x %d image, %d size\n", w,h,c,size);
9  layer layer = {0};
10  layer.type = NORMALIZATION;
11  layer.batch = batch;
12  layer.h = layer.out_h = h;
13  layer.w = layer.out_w = w;
14  layer.c = layer.out_c = c;
15  layer.kappa = kappa;
16  layer.size = size;
17  layer.alpha = alpha;
18  layer.beta = beta;
19  layer.output = calloc(h * w * c * batch, sizeof(float));
20  layer.delta = calloc(h * w * c * batch, sizeof(float));
21  layer.squared = calloc(h * w * c * batch, sizeof(float));
22  layer.norms = calloc(h * w * c * batch, sizeof(float));
23  layer.inputs = w*h*c;
24  layer.outputs = layer.inputs;
25 
28  #ifdef GPU
29  layer.forward_gpu = forward_normalization_layer_gpu;
30  layer.backward_gpu = backward_normalization_layer_gpu;
31 
32  layer.output_gpu = cuda_make_array(layer.output, h * w * c * batch);
33  layer.delta_gpu = cuda_make_array(layer.delta, h * w * c * batch);
34  layer.squared_gpu = cuda_make_array(layer.squared, h * w * c * batch);
35  layer.norms_gpu = cuda_make_array(layer.norms, h * w * c * batch);
36  #endif
37  return layer;
38 }
39 
41 {
42  int c = layer->c;
43  int batch = layer->batch;
44  layer->h = h;
45  layer->w = w;
46  layer->out_h = h;
47  layer->out_w = w;
48  layer->inputs = w*h*c;
49  layer->outputs = layer->inputs;
50  layer->output = realloc(layer->output, h * w * c * batch * sizeof(float));
51  layer->delta = realloc(layer->delta, h * w * c * batch * sizeof(float));
52  layer->squared = realloc(layer->squared, h * w * c * batch * sizeof(float));
53  layer->norms = realloc(layer->norms, h * w * c * batch * sizeof(float));
54 #ifdef GPU
55  cuda_free(layer->output_gpu);
56  cuda_free(layer->delta_gpu);
57  cuda_free(layer->squared_gpu);
58  cuda_free(layer->norms_gpu);
59  layer->output_gpu = cuda_make_array(layer->output, h * w * c * batch);
60  layer->delta_gpu = cuda_make_array(layer->delta, h * w * c * batch);
61  layer->squared_gpu = cuda_make_array(layer->squared, h * w * c * batch);
62  layer->norms_gpu = cuda_make_array(layer->norms, h * w * c * batch);
63 #endif
64 }
65 
67 {
68  int k,b;
69  int w = layer.w;
70  int h = layer.h;
71  int c = layer.c;
72  scal_cpu(w*h*c*layer.batch, 0, layer.squared, 1);
73 
74  for(b = 0; b < layer.batch; ++b){
75  float *squared = layer.squared + w*h*c*b;
76  float *norms = layer.norms + w*h*c*b;
77  float *input = net.input + w*h*c*b;
78  pow_cpu(w*h*c, 2, input, 1, squared, 1);
79 
80  const_cpu(w*h, layer.kappa, norms, 1);
81  for(k = 0; k < layer.size/2; ++k){
82  axpy_cpu(w*h, layer.alpha, squared + w*h*k, 1, norms, 1);
83  }
84 
85  for(k = 1; k < layer.c; ++k){
86  copy_cpu(w*h, norms + w*h*(k-1), 1, norms + w*h*k, 1);
87  int prev = k - ((layer.size-1)/2) - 1;
88  int next = k + (layer.size/2);
89  if(prev >= 0) axpy_cpu(w*h, -layer.alpha, squared + w*h*prev, 1, norms + w*h*k, 1);
90  if(next < layer.c) axpy_cpu(w*h, layer.alpha, squared + w*h*next, 1, norms + w*h*k, 1);
91  }
92  }
93  pow_cpu(w*h*c*layer.batch, -layer.beta, layer.norms, 1, layer.output, 1);
94  mul_cpu(w*h*c*layer.batch, net.input, 1, layer.output, 1);
95 }
96 
98 {
99  // TODO This is approximate ;-)
100  // Also this should add in to delta instead of overwritting.
101 
102  int w = layer.w;
103  int h = layer.h;
104  int c = layer.c;
105  pow_cpu(w*h*c*layer.batch, -layer.beta, layer.norms, 1, net.delta, 1);
106  mul_cpu(w*h*c*layer.batch, layer.delta, 1, net.delta, 1);
107 }
108 
109 #ifdef GPU
110 void forward_normalization_layer_gpu(const layer layer, network net)
111 {
112  int k,b;
113  int w = layer.w;
114  int h = layer.h;
115  int c = layer.c;
116  scal_gpu(w*h*c*layer.batch, 0, layer.squared_gpu, 1);
117 
118  for(b = 0; b < layer.batch; ++b){
119  float *squared = layer.squared_gpu + w*h*c*b;
120  float *norms = layer.norms_gpu + w*h*c*b;
121  float *input = net.input_gpu + w*h*c*b;
122  pow_gpu(w*h*c, 2, input, 1, squared, 1);
123 
124  const_gpu(w*h, layer.kappa, norms, 1);
125  for(k = 0; k < layer.size/2; ++k){
126  axpy_gpu(w*h, layer.alpha, squared + w*h*k, 1, norms, 1);
127  }
128 
129  for(k = 1; k < layer.c; ++k){
130  copy_gpu(w*h, norms + w*h*(k-1), 1, norms + w*h*k, 1);
131  int prev = k - ((layer.size-1)/2) - 1;
132  int next = k + (layer.size/2);
133  if(prev >= 0) axpy_gpu(w*h, -layer.alpha, squared + w*h*prev, 1, norms + w*h*k, 1);
134  if(next < layer.c) axpy_gpu(w*h, layer.alpha, squared + w*h*next, 1, norms + w*h*k, 1);
135  }
136  }
137  pow_gpu(w*h*c*layer.batch, -layer.beta, layer.norms_gpu, 1, layer.output_gpu, 1);
138  mul_gpu(w*h*c*layer.batch, net.input_gpu, 1, layer.output_gpu, 1);
139 }
140 
141 void backward_normalization_layer_gpu(const layer layer, network net)
142 {
143  // TODO This is approximate ;-)
144 
145  int w = layer.w;
146  int h = layer.h;
147  int c = layer.c;
148  pow_gpu(w*h*c*layer.batch, -layer.beta, layer.norms_gpu, 1, net.delta_gpu, 1);
149  mul_gpu(w*h*c*layer.batch, layer.delta_gpu, 1, net.delta_gpu, 1);
150 }
151 #endif
float * norms
Definition: darknet.h:249
void pow_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY)
Definition: blas.c:172
void resize_normalization_layer(layer *layer, int w, int h)
int w
Definition: darknet.h:140
void(* forward_gpu)(struct layer, struct network)
Definition: darknet.h:126
void(* backward_gpu)(struct layer, struct network)
Definition: darknet.h:127
void axpy_gpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY)
void mul_cpu(int N, float *X, int INCX, float *Y, int INCY)
Definition: blas.c:166
void(* forward)(struct layer, struct network)
Definition: darknet.h:123
int out_w
Definition: darknet.h:141
float * delta
Definition: darknet.h:486
float kappa
Definition: darknet.h:187
int out_c
Definition: darknet.h:141
void mul_gpu(int N, float *X, int INCX, float *Y, int INCY)
int size
Definition: darknet.h:145
void forward_normalization_layer(const layer layer, network net)
void scal_gpu(int N, float ALPHA, float *X, int INCX)
int h
Definition: darknet.h:140
float * delta
Definition: darknet.h:245
int out_h
Definition: darknet.h:141
float beta
Definition: darknet.h:186
int inputs
Definition: darknet.h:134
void backward_normalization_layer(const layer layer, network net)
void axpy_cpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY)
Definition: blas.c:178
void(* backward)(struct layer, struct network)
Definition: darknet.h:124
int batch
Definition: darknet.h:131
float * output
Definition: darknet.h:246
void scal_cpu(int N, float ALPHA, float *X, int INCX)
Definition: blas.c:184
void const_cpu(int N, float ALPHA, float *X, int INCX)
Definition: blas.c:160
layer make_normalization_layer(int batch, int w, int h, int c, int size, float alpha, float beta, float kappa)
void copy_gpu(int N, float *X, int INCX, float *Y, int INCY)
float alpha
Definition: darknet.h:185
int c
Definition: darknet.h:140
void copy_cpu(int N, float *X, int INCX, float *Y, int INCY)
Definition: blas.c:226
LAYER_TYPE type
Definition: darknet.h:120
float * input
Definition: darknet.h:484
struct layer layer
Definition: darknet.h:117
float * squared
Definition: darknet.h:248
int outputs
Definition: darknet.h:135
void const_gpu(int N, float ALPHA, float *X, int INCX)
void pow_gpu(int N, float ALPHA, float *X, int INCX, float *Y, int INCY)
Definition: darknet.h:119