source: src/ai/batchnorm.c @ 9b05ea9

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

[batchnorm] wrap long lines

  • Property mode set to 100644
File size: 4.6 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  AUBIO_DBG("batchnorm: %15s -> %s (%d params) (4 * (%d,))\n",
73      aubio_tensor_get_shape_string(input_tensor),
74      aubio_tensor_get_shape_string(input_tensor), // same output shape
75      c->n_outputs, 4 * c->n_outputs);
76}
77
78uint_t aubio_batchnorm_get_output_shape(aubio_batchnorm_t *c,
79    aubio_tensor_t *input, uint_t *shape)
80{
81  uint_t i;
82
83  AUBIO_ASSERT(c && input && shape);
84  AUBIO_ASSERT(c->n_outputs == input->shape[input->ndim - 1]);
85
86  for (i = 0; i < input->ndim; i++) {
87    shape[i] = input->shape[i];
88  }
89
90  aubio_batchnorm_debug(c, input);
91
92  return AUBIO_OK;
93}
94
95void aubio_batchnorm_do(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor,
96    aubio_tensor_t *activations)
97{
98  smpl_t s;
99  uint_t i, j;
100  uint_t ii = 0;
101  uint_t length = activations->shape[activations->ndim - 1];
102  uint_t height = activations->size / length;
103
104  AUBIO_ASSERT(c);
105  AUBIO_ASSERT_EQUAL_SHAPE(input_tensor, activations);
106  AUBIO_ASSERT(length == c->n_outputs);
107  AUBIO_ASSERT(height * length == activations->size);
108
109  for (i = 0; i < height; i++) {
110    for (j = 0; j < length; j++) {
111      s = input_tensor->buffer[ii + j];
112      s -= c->moving_mean->data[j];
113      s *= c->gamma->data[j];
114      s /= SQRT(c->moving_variance->data[j] + 1.e-4);
115      s += c->beta->data[j];
116      activations->buffer[ii + j] = s;
117    }
118    ii += length;
119  }
120}
121
122uint_t aubio_batchnorm_set_gamma(aubio_batchnorm_t *t, fvec_t *gamma)
123{
124  AUBIO_ASSERT(t && t->gamma);
125  AUBIO_ASSERT(gamma);
126  if (t->gamma->length != gamma->length) return AUBIO_FAIL;
127  fvec_copy(gamma, t->gamma);
128  return AUBIO_OK;
129}
130
131uint_t aubio_batchnorm_set_beta(aubio_batchnorm_t *t, fvec_t *beta)
132{
133  AUBIO_ASSERT(t && t->beta && beta);
134  if (t->beta->length != beta->length)
135    return AUBIO_FAIL;
136  fvec_copy(beta, t->beta);
137  return AUBIO_OK;
138}
139
140uint_t aubio_batchnorm_set_moving_mean(aubio_batchnorm_t *t,
141    fvec_t *moving_mean)
142{
143  AUBIO_ASSERT(t && t->moving_mean);
144  AUBIO_ASSERT(moving_mean);
145  if (t->moving_mean->length != moving_mean->length)
146    return AUBIO_FAIL;
147  fvec_copy(moving_mean, t->moving_mean);
148  return AUBIO_OK;
149}
150
151uint_t aubio_batchnorm_set_moving_variance(aubio_batchnorm_t *t,
152    fvec_t *moving_variance)
153{
154  AUBIO_ASSERT(t && t->moving_variance);
155  AUBIO_ASSERT(moving_variance);
156  if (t->moving_variance->length != moving_variance->length)
157    return AUBIO_FAIL;
158  fvec_copy(moving_variance, t->moving_variance);
159  return AUBIO_OK;
160}
161
162fvec_t *aubio_batchnorm_get_gamma(aubio_batchnorm_t *t)
163{
164  AUBIO_ASSERT(t && t->gamma);
165  return t->gamma;
166}
167
168fvec_t *aubio_batchnorm_get_beta(aubio_batchnorm_t *t)
169{
170  AUBIO_ASSERT(t && t->beta);
171  return t->beta;
172}
173
174fvec_t *aubio_batchnorm_get_moving_mean(aubio_batchnorm_t *t)
175{
176  AUBIO_ASSERT(t && t->moving_mean);
177  return t->moving_mean;
178}
179
180fvec_t *aubio_batchnorm_get_moving_variance(aubio_batchnorm_t *t)
181{
182  AUBIO_ASSERT(t && t->moving_variance);
183  return t->moving_variance;
184}
Note: See TracBrowser for help on using the repository browser.