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
RevLine 
[7b2a58c]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
[72f450a]37aubio_batchnorm_t *new_aubio_batchnorm(void)
[7b2a58c]38{
39  aubio_batchnorm_t *c = AUBIO_NEW(aubio_batchnorm_t);
[e75bd80]40  // note; no input parameter, so no other possible failure
[7b2a58c]41  return c;
42}
43
[72f450a]44static void aubio_batchnorm_reset(aubio_batchnorm_t *c) {
[7b2a58c]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);
[72f450a]54}
55
56void del_aubio_batchnorm(aubio_batchnorm_t* c) {
57  aubio_batchnorm_reset(c);
[7b2a58c]58  AUBIO_FREE(c);
59}
60
61void aubio_batchnorm_debug(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor)
62{
[bee3d52]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);
[7b2a58c]67}
68
69uint_t aubio_batchnorm_get_output_shape(aubio_batchnorm_t *c,
70    aubio_tensor_t *input, uint_t *shape)
71{
[05808d5]72  uint_t i;
73
[7b2a58c]74  AUBIO_ASSERT(c && input && shape);
75
[05808d5]76  for (i = 0; i < input->ndim; i++) {
77    shape[i] = input->shape[i];
78  }
[7b2a58c]79
[72f450a]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
[7b2a58c]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;
[05808d5]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
[7b2a58c]109  AUBIO_ASSERT(c);
110  AUBIO_ASSERT_EQUAL_SHAPE(input_tensor, activations);
[05808d5]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;
[7b2a58c]122    }
[05808d5]123    ii += length;
[7b2a58c]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{
[9b05ea9]138  AUBIO_ASSERT(t && t->beta && beta);
139  if (t->beta->length != beta->length)
140    return AUBIO_FAIL;
[7b2a58c]141  fvec_copy(beta, t->beta);
142  return AUBIO_OK;
143}
144
[9b05ea9]145uint_t aubio_batchnorm_set_moving_mean(aubio_batchnorm_t *t,
146    fvec_t *moving_mean)
[7b2a58c]147{
148  AUBIO_ASSERT(t && t->moving_mean);
149  AUBIO_ASSERT(moving_mean);
[9b05ea9]150  if (t->moving_mean->length != moving_mean->length)
151    return AUBIO_FAIL;
[7b2a58c]152  fvec_copy(moving_mean, t->moving_mean);
153  return AUBIO_OK;
154}
155
[9b05ea9]156uint_t aubio_batchnorm_set_moving_variance(aubio_batchnorm_t *t,
157    fvec_t *moving_variance)
[7b2a58c]158{
159  AUBIO_ASSERT(t && t->moving_variance);
160  AUBIO_ASSERT(moving_variance);
[9b05ea9]161  if (t->moving_variance->length != moving_variance->length)
162    return AUBIO_FAIL;
[7b2a58c]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.