-
Notifications
You must be signed in to change notification settings - Fork 0
/
batchnorm.c
101 lines (94 loc) · 3.2 KB
/
batchnorm.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#include "matrix.h"
#include "batchnorm.h"
struct BN *BN_Init(int channel)
{
struct BN *input = (struct BN *)malloc(sizeof(struct BN));
input->channelSize = channel;
input->beta = (float *)malloc(channel * sizeof(float));
input->gamma = (float *)malloc(channel * sizeof(float));
input->mean = (float *)malloc(channel * sizeof(float));
input->variance = (float *)malloc(channel * sizeof(float));
input->runningMean = (float *)malloc(channel * sizeof(float));
input->runningVar = (float *)malloc(channel * sizeof(float));
for(int i = 0 ; i < channel ; i++)
{
input->mean[i] = 0;
input->variance[i] = 0;
input->beta[i] = 0;
input->gamma[i] = 1.0;
input->runningMean[i] = 0;
input->runningVar[i] = 1.0;
}
return input;
}
void *BN_GetCoeff(struct Matrix **input , struct BN *coeff)
{
int channel = input[0]->channelSize;
int size = input[0]->rowSize;
int amount = BATCH * size * size ;
for(int i = 0 ; i < channel ; i++)
{
coeff->mean[i] =0 ;
coeff->variance[i] = 0;
float temp = 0;
for(int num = 0 ; num < BATCH ; num ++)
{
for (int j = 0 ; j < size ; j++)
{
for(int k = 0 ; k < size ; k++)
{
temp = temp + input[num]->feature[i][j][k];
//printf("batch = %d i = %d j = %d k = %d temp = %.0f\n",batch,i,j,k,temp);
}
}
}
coeff->mean[i] = temp/amount ;
coeff->runningMean[i] = (1-MOMENTUM)*coeff->runningMean[i] + MOMENTUM*coeff->mean[i];
//mean_new = (1-momentum)mean_old+momentum*mean this batch
}
for(int i = 0 ; i < channel ; i++)
{
float temp = 0;
float avg = coeff->mean[i];
for(int batch = 0 ; batch < BATCH ; batch ++)
{
for (int j = 0 ; j < size ; j++)
{
for(int k = 0 ; k < size ; k++)
{
temp = temp + pow(input[batch]->feature[i][j][k] - avg ,2);
}
}
}
coeff->variance[i] = temp/(amount);
coeff->runningVar[i] = (1-MOMENTUM)*coeff->runningVar[i] + MOMENTUM*temp/(amount-1);
}
}
void BN_BatchNorm(struct Matrix *input , struct Matrix *output , struct BN *coeff )
{
int channel = input->channelSize;
int size = input->rowSize;
for(int i = 0 ; i < channel ; i++)
{
float avg = coeff->mean[i];
float std = coeff->variance[i];
float gamma = coeff->gamma[i];
float beta = coeff->beta[i];
for (int j = 0 ; j < size ; j++)
{
for(int k = 0 ; k < size ; k++)
{
float temp = input->feature[i][j][k] ;
temp = gamma*(temp -avg)/pow(std+EPSILON,0.5) + beta;
output->feature[i][j][k] = temp;
}
}
}
}
void **BNBatch_BatchNorm(struct Matrix **input ,struct Matrix **output, struct BN *coeff )
{
for(int num = 0 ; num < BATCH ; num++)
{
BN_BatchNorm(input[num],output[num],coeff);
}
}