source: src/ai/batchnorm.c @ be3164d

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

[ai] only compile _debug function in debug mode

  • Property mode set to 100644
File size: 4.8 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
34#if defined(DEBUG)
35static void aubio_batchnorm_debug(aubio_batchnorm_t *c,
36    aubio_tensor_t *input_tensor);
37#endif
38
39aubio_batchnorm_t *new_aubio_batchnorm(void)
40{
41  aubio_batchnorm_t *c = AUBIO_NEW(aubio_batchnorm_t);
42  // note; no input parameter, so no other possible failure
43  return c;
44}
45
46static void aubio_batchnorm_reset(aubio_batchnorm_t *c) {
47  AUBIO_ASSERT(c);
48  if (c->gamma)
49    del_fvec(c->gamma);
50  if (c->beta)
51    del_fvec(c->beta);
52  if (c->moving_mean)
53    del_fvec(c->moving_mean);
54  if (c->moving_variance)
55    del_fvec(c->moving_variance);
56}
57
58void del_aubio_batchnorm(aubio_batchnorm_t* c) {
59  aubio_batchnorm_reset(c);
60  AUBIO_FREE(c);
61}
62
63#if defined(DEBUG)
64void aubio_batchnorm_debug(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor)
65{
66  AUBIO_DBG("batchnorm: %15s -> %s (%d params) (4 * (%d,))\n",
67      aubio_tensor_get_shape_string(input_tensor),
68      aubio_tensor_get_shape_string(input_tensor), // same output shape
69      c->n_outputs, 4 * c->n_outputs);
70}
71#endif
72
73uint_t aubio_batchnorm_get_output_shape(aubio_batchnorm_t *c,
74    aubio_tensor_t *input, uint_t *shape)
75{
76  uint_t i;
77
78  AUBIO_ASSERT(c && input && shape);
79
80  for (i = 0; i < input->ndim; i++) {
81    shape[i] = input->shape[i];
82  }
83
84  aubio_batchnorm_reset(c);
85
86  c->n_outputs = input->shape[input->ndim - 1];
87
88  c->gamma = new_fvec(c->n_outputs);
89  c->beta = new_fvec(c->n_outputs);
90  c->moving_mean = new_fvec(c->n_outputs);
91  c->moving_variance = new_fvec(c->n_outputs);
92
93  if (!c->gamma || !c->beta || !c->moving_mean || !c->moving_variance)
94  {
95    aubio_batchnorm_reset(c);
96    return AUBIO_FAIL;
97  }
98
99#if defined(DEBUG)
100  aubio_batchnorm_debug(c, input);
101#endif
102
103  return AUBIO_OK;
104}
105
106void aubio_batchnorm_do(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor,
107    aubio_tensor_t *activations)
108{
109  smpl_t s;
110  uint_t i, j;
111  uint_t ii = 0;
112  uint_t length = activations->shape[activations->ndim - 1];
113  uint_t height = activations->size / length;
114
115  AUBIO_ASSERT(c);
116  AUBIO_ASSERT_EQUAL_SHAPE(input_tensor, activations);
117  AUBIO_ASSERT(length == c->n_outputs);
118  AUBIO_ASSERT(height * length == activations->size);
119
120  for (i = 0; i < height; i++) {
121    for (j = 0; j < length; j++) {
122      s = input_tensor->buffer[ii + j];
123      s -= c->moving_mean->data[j];
124      s *= c->gamma->data[j];
125      s /= SQRT(c->moving_variance->data[j] + 1.e-4);
126      s += c->beta->data[j];
127      activations->buffer[ii + j] = s;
128    }
129    ii += length;
130  }
131}
132
133uint_t aubio_batchnorm_set_gamma(aubio_batchnorm_t *t, fvec_t *gamma)
134{
135  AUBIO_ASSERT(t && t->gamma);
136  AUBIO_ASSERT(gamma);
137  if (t->gamma->length != gamma->length) return AUBIO_FAIL;
138  fvec_copy(gamma, t->gamma);
139  return AUBIO_OK;
140}
141
142uint_t aubio_batchnorm_set_beta(aubio_batchnorm_t *t, fvec_t *beta)
143{
144  AUBIO_ASSERT(t && t->beta && beta);
145  if (t->beta->length != beta->length)
146    return AUBIO_FAIL;
147  fvec_copy(beta, t->beta);
148  return AUBIO_OK;
149}
150
151uint_t aubio_batchnorm_set_moving_mean(aubio_batchnorm_t *t,
152    fvec_t *moving_mean)
153{
154  AUBIO_ASSERT(t && t->moving_mean);
155  AUBIO_ASSERT(moving_mean);
156  if (t->moving_mean->length != moving_mean->length)
157    return AUBIO_FAIL;
158  fvec_copy(moving_mean, t->moving_mean);
159  return AUBIO_OK;
160}
161
162uint_t aubio_batchnorm_set_moving_variance(aubio_batchnorm_t *t,
163    fvec_t *moving_variance)
164{
165  AUBIO_ASSERT(t && t->moving_variance);
166  AUBIO_ASSERT(moving_variance);
167  if (t->moving_variance->length != moving_variance->length)
168    return AUBIO_FAIL;
169  fvec_copy(moving_variance, t->moving_variance);
170  return AUBIO_OK;
171}
172
173fvec_t *aubio_batchnorm_get_gamma(aubio_batchnorm_t *t)
174{
175  AUBIO_ASSERT(t && t->gamma);
176  return t->gamma;
177}
178
179fvec_t *aubio_batchnorm_get_beta(aubio_batchnorm_t *t)
180{
181  AUBIO_ASSERT(t && t->beta);
182  return t->beta;
183}
184
185fvec_t *aubio_batchnorm_get_moving_mean(aubio_batchnorm_t *t)
186{
187  AUBIO_ASSERT(t && t->moving_mean);
188  return t->moving_mean;
189}
190
191fvec_t *aubio_batchnorm_get_moving_variance(aubio_batchnorm_t *t)
192{
193  AUBIO_ASSERT(t && t->moving_variance);
194  return t->moving_variance;
195}
Note: See TracBrowser for help on using the repository browser.