source: src/ai/batchnorm.c @ 17189b2

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

[batchnorm] remove comments, add a note about no input parameter

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