source: src/ai/batchnorm.c @ c97f7ed

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

[batchnorm] improve debug string

  • 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  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  AUBIO_ASSERT(c && input && shape);
82
83  shape[0] = input->shape[0];
84  shape[1] = input->shape[1];
85  shape[2] = input->shape[2];
86
87  aubio_batchnorm_debug(c, input);
88
89  return AUBIO_OK;
90}
91
92void aubio_batchnorm_do(aubio_batchnorm_t *c, aubio_tensor_t *input_tensor,
93    aubio_tensor_t *activations)
94{
95  uint_t i, j, k;
96  uint_t jj;
97  smpl_t s;
98  AUBIO_ASSERT(c);
99  AUBIO_ASSERT_EQUAL_SHAPE(input_tensor, activations);
100  if (input_tensor->ndim == 3) {
101    for (i = 0; i < activations->shape[0]; i++) {
102      jj = 0;
103      for (j = 0; j < activations->shape[1]; j++) {
104        for (k = 0; k < activations->shape[2]; k++) {
105          s = input_tensor->data[i][jj + k];
106          s -= c->moving_mean->data[k];
107          s *= c->gamma->data[k];
108          s /= SQRT(c->moving_variance->data[k] + 1.e-4);
109          s += c->beta->data[k];
110          activations->data[i][jj + k] = s;
111        }
112        jj += activations->shape[2];
113      }
114    }
115  } else if (input_tensor->ndim == 2) {
116    for (i = 0; i < activations->shape[0]; i++) {
117      for (j = 0; j < activations->shape[1]; j++) {
118        s = input_tensor->data[i][j];
119        s -= c->moving_mean->data[j];
120        s *= c->gamma->data[j];
121        s /= SQRT(c->moving_variance->data[j] + 1.e-4);
122        s += c->beta->data[j];
123        activations->data[i][j] = s;
124      }
125    }
126  }
127}
128
129uint_t aubio_batchnorm_set_gamma(aubio_batchnorm_t *t, fvec_t *gamma)
130{
131  AUBIO_ASSERT(t && t->gamma);
132  AUBIO_ASSERT(gamma);
133  if (t->gamma->length != gamma->length) return AUBIO_FAIL;
134  fvec_copy(gamma, t->gamma);
135  return AUBIO_OK;
136}
137
138uint_t aubio_batchnorm_set_beta(aubio_batchnorm_t *t, fvec_t *beta)
139{
140  AUBIO_ASSERT(t && t->beta);
141  AUBIO_ASSERT(beta);
142  if (t->beta->length != beta->length) return AUBIO_FAIL;
143  fvec_copy(beta, t->beta);
144  return AUBIO_OK;
145}
146
147uint_t aubio_batchnorm_set_moving_mean(aubio_batchnorm_t *t, fvec_t *moving_mean)
148{
149  AUBIO_ASSERT(t && t->moving_mean);
150  AUBIO_ASSERT(moving_mean);
151  if (t->moving_mean->length != moving_mean->length) 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, fvec_t *moving_variance)
157{
158  AUBIO_ASSERT(t && t->moving_variance);
159  AUBIO_ASSERT(moving_variance);
160  if (t->moving_variance->length != moving_variance->length) return AUBIO_FAIL;
161  fvec_copy(moving_variance, t->moving_variance);
162  return AUBIO_OK;
163}
164
165fvec_t *aubio_batchnorm_get_gamma(aubio_batchnorm_t *t)
166{
167  AUBIO_ASSERT(t && t->gamma);
168  return t->gamma;
169}
170
171fvec_t *aubio_batchnorm_get_beta(aubio_batchnorm_t *t)
172{
173  AUBIO_ASSERT(t && t->beta);
174  return t->beta;
175}
176
177fvec_t *aubio_batchnorm_get_moving_mean(aubio_batchnorm_t *t)
178{
179  AUBIO_ASSERT(t && t->moving_mean);
180  return t->moving_mean;
181}
182
183fvec_t *aubio_batchnorm_get_moving_variance(aubio_batchnorm_t *t)
184{
185  AUBIO_ASSERT(t && t->moving_variance);
186  return t->moving_variance;
187}
Note: See TracBrowser for help on using the repository browser.