source: src/ai/batchnorm.c @ 83ef8f0

feature/cnnfeature/crepe
Last change on this file since 83ef8f0 was 7b2a58c, checked in by Paul Brossier <piem@piem.org>, 2 years ago

[batchnorm] add first plain version

  • Property mode set to 100644
File size: 4.9 KB
Line 
1/*
2  Copyright (C) 2018 Paul Brossier <piem@aubio.org>
3
4  This file is part of aubio.
5
6  aubio is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10
11  aubio is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  GNU General Public License for more details.
15
16  You should have received a copy of the GNU General Public License
17  along with aubio.  If not, see <http://www.gnu.org/licenses/>.
18
19*/
20
21#include "aubio_priv.h"
22#include "fmat.h"
23#include "tensor.h"
24#include "batchnorm.h"
25
26struct _aubio_batchnorm_t {
27  uint_t n_outputs;
28  fvec_t *gamma;
29  fvec_t *beta;
30  fvec_t *moving_mean;
31  fvec_t *moving_variance;
32};
33
34static void aubio_batchnorm_debug(aubio_batchnorm_t *c,
35    aubio_tensor_t *input_tensor);
36
37aubio_batchnorm_t *new_aubio_batchnorm(uint_t n_outputs)
38{
39  aubio_batchnorm_t *c = AUBIO_NEW(aubio_batchnorm_t);
40
41  AUBIO_GOTO_FAILURE((sint_t)n_outputs > 0);
42
43  c->n_outputs = n_outputs;
44
45  c->gamma = new_fvec(n_outputs);
46  c->beta = new_fvec(n_outputs);
47  c->moving_mean = new_fvec(n_outputs);
48  c->moving_variance = new_fvec(n_outputs);
49
50  return c;
51
52failure:
53  del_aubio_batchnorm(c);
54  return NULL;
55}
56
57void del_aubio_batchnorm(aubio_batchnorm_t* c) {
58  AUBIO_ASSERT(c);
59  if (c->gamma)
60    del_fvec(c->gamma);
61  if (c->beta)
62    del_fvec(c->beta);
63  if (c->moving_mean)
64    del_fvec(c->moving_mean);
65  if (c->moving_variance)
66    del_fvec(c->moving_variance);
67  AUBIO_FREE(c);
68}
69
70void aubio_batchnorm_debug(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor)
71{
72  const char_t *shape_str = aubio_tensor_get_shape_string(input_tensor);
73  AUBIO_DBG("batchnorm: %15s ¤ (%d x4) -> %s (4 x %d params)\n",
74      shape_str, c->n_outputs, shape_str, c->n_outputs);
75}
76
77uint_t aubio_batchnorm_get_output_shape(aubio_batchnorm_t *c,
78    aubio_tensor_t *input, uint_t *shape)
79{
80  AUBIO_ASSERT(c && input && shape);
81
82  shape[0] = input->shape[0];
83  shape[1] = input->shape[1];
84  shape[2] = input->shape[2];
85
86  aubio_batchnorm_debug(c, input);
87
88  return AUBIO_OK;
89}
90
91void aubio_batchnorm_do(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor,
92    aubio_tensor_t *activations)
93{
94  uint_t i, j, k;
95  uint_t jj;
96  smpl_t s;
97  AUBIO_ASSERT(c);
98  AUBIO_ASSERT_EQUAL_SHAPE(input_tensor, activations);
99  if (input_tensor->ndim == 3) {
100    for (i = 0; i < activations->shape[0]; i++) {
101      jj = 0;
102      for (j = 0; j < activations->shape[1]; j++) {
103        for (k = 0; k < activations->shape[2]; k++) {
104          s = input_tensor->data[i][jj + k];
105          s -= c->moving_mean->data[k];
106          s *= c->gamma->data[k];
107          s /= SQRT(c->moving_variance->data[k] + 1.e-4);
108          s += c->beta->data[k];
109          activations->data[i][jj + k] = s;
110        }
111        jj += activations->shape[2];
112      }
113    }
114  } else if (input_tensor->ndim == 2) {
115    for (i = 0; i < activations->shape[0]; i++) {
116      for (j = 0; j < activations->shape[1]; j++) {
117        s = input_tensor->data[i][j];
118        s -= c->moving_mean->data[j];
119        s *= c->gamma->data[j];
120        s /= SQRT(c->moving_variance->data[j] + 1.e-4);
121        s += c->beta->data[j];
122        activations->data[i][j] = s;
123      }
124    }
125  }
126}
127
128uint_t aubio_batchnorm_set_gamma(aubio_batchnorm_t *t, fvec_t *gamma)
129{
130  AUBIO_ASSERT(t && t->gamma);
131  AUBIO_ASSERT(gamma);
132  if (t->gamma->length != gamma->length) return AUBIO_FAIL;
133  fvec_copy(gamma, t->gamma);
134  return AUBIO_OK;
135}
136
137uint_t aubio_batchnorm_set_beta(aubio_batchnorm_t *t, fvec_t *beta)
138{
139  AUBIO_ASSERT(t && t->beta);
140  AUBIO_ASSERT(beta);
141  if (t->beta->length != beta->length) return AUBIO_FAIL;
142  fvec_copy(beta, t->beta);
143  return AUBIO_OK;
144}
145
146uint_t aubio_batchnorm_set_moving_mean(aubio_batchnorm_t *t, fvec_t *moving_mean)
147{
148  AUBIO_ASSERT(t && t->moving_mean);
149  AUBIO_ASSERT(moving_mean);
150  if (t->moving_mean->length != moving_mean->length) return AUBIO_FAIL;
151  fvec_copy(moving_mean, t->moving_mean);
152  return AUBIO_OK;
153}
154
155uint_t aubio_batchnorm_set_moving_variance(aubio_batchnorm_t *t, fvec_t *moving_variance)
156{
157  AUBIO_ASSERT(t && t->moving_variance);
158  AUBIO_ASSERT(moving_variance);
159  if (t->moving_variance->length != moving_variance->length) return AUBIO_FAIL;
160  fvec_copy(moving_variance, t->moving_variance);
161  return AUBIO_OK;
162}
163
164fvec_t *aubio_batchnorm_get_gamma(aubio_batchnorm_t *t)
165{
166  AUBIO_ASSERT(t && t->gamma);
167  return t->gamma;
168}
169
170fvec_t *aubio_batchnorm_get_beta(aubio_batchnorm_t *t)
171{
172  AUBIO_ASSERT(t && t->beta);
173  return t->beta;
174}
175
176fvec_t *aubio_batchnorm_get_moving_mean(aubio_batchnorm_t *t)
177{
178  AUBIO_ASSERT(t && t->moving_mean);
179  return t->moving_mean;
180}
181
182fvec_t *aubio_batchnorm_get_moving_variance(aubio_batchnorm_t *t)
183{
184  AUBIO_ASSERT(t && t->moving_variance);
185  return t->moving_variance;
186}
Note: See TracBrowser for help on using the repository browser.