diff --git a/src/cnn/creation.c b/src/cnn/creation.c index 6b0402f..12f32f4 100644 --- a/src/cnn/creation.c +++ b/src/cnn/creation.c @@ -235,7 +235,7 @@ void add_dense(Network* network, int size_output, int activation) { } } - initialisation_1d_matrix(network->initialisation, nn->bias, size_output, size_input); + initialisation_1d_matrix(network->initialisation, nn->bias, size_output, size_input, size_output); initialisation_2d_matrix(network->initialisation, nn->weights, size_input, size_output, size_input, size_output); create_a_line_input_layer(network, n, size_output); create_a_line_input_z_layer(network, n, size_output); @@ -275,7 +275,7 @@ void add_dense_linearisation(Network* network, int size_output, int activation) nn->d_weights[i][j] = 0.; } } - initialisation_1d_matrix(network->initialisation, nn->bias, size_output, size_input); + initialisation_1d_matrix(network->initialisation, nn->bias, size_output, size_input, size_output); initialisation_2d_matrix(network->initialisation, nn->weights, size_input, size_output, size_input, size_output); create_a_line_input_layer(network, n, size_output); create_a_line_input_z_layer(network, n, size_output); diff --git a/src/cnn/include/initialisation.h b/src/cnn/include/initialisation.h index 64dab61..ceef35d 100644 --- a/src/cnn/include/initialisation.h +++ b/src/cnn/include/initialisation.h @@ -3,16 +3,24 @@ // Génère un flottant entre 0 et 1 #define RAND_FLT() ((float)rand())/((float)RAND_MAX) +#define TWOPI 6.2831853071795864769252867665 #define ZERO 0 #define GLOROT 1 -#define XAVIER 1 // Xavier and Glorot initialisations are the same -#define HE 2 +#define XAVIER 1 // Xavier et Glorot initialisations sont indentiques +#define NORMALIZED_XAVIER 2 +#define HE 3 + +/* +* Renvoie un flottant à partir de la loi normale [x;y]. +* La fonction repose sur la méthode de Box-Muller +*/ +float randn(); /* * Initialise une matrice 1d dim de float en fonction du type d'initialisation */ -void initialisation_1d_matrix(int initialisation, float* matrix, int dim, int n_in); +void initialisation_1d_matrix(int initialisation, float* matrix, int dim, int n_in, int n_out); /* * Initialise une matrice 2d dim1*dim2 de float en fonction du type d'initialisation diff --git a/src/cnn/initialisation.c b/src/cnn/initialisation.c index c2635b9..e30c237 100644 --- a/src/cnn/initialisation.c +++ b/src/cnn/initialisation.c @@ -8,87 +8,208 @@ // he initialisation : RELU (2/fan_in) // LeCun initialisation: SELU (1/fan_in) -// Only uniform for the moment -void initialisation_1d_matrix(int initialisation, float* matrix, int dim, int n_in) { - int n; - if (initialisation == GLOROT) { - n = (n_in + dim)/2; +// Explained in https://machinelearningmastery.com/weight-initialization-for-deep-learning-neural-networks/ - } else if (initialisation == HE) { - n = n_in/2; - } else { - printf_warning("Initialisation non reconnue dans 'initialisation_1d_matrix' \n"); - return ; +float randn() { + float f1=0.; + while (f1 == 0) { + f1 = RAND_FLT(); } - float lower_bound = -1/sqrt((double)n); - float distance_bounds = -2*lower_bound; - for (int i=0; i < dim; i++) { - matrix[i] = lower_bound + RAND_FLT()*distance_bounds; + return sqrt(-2.0*log(f1))*cos(TWOPI*RAND_FLT()); +} + +void initialisation_1d_matrix(int initialisation, float* matrix, int dim, int n_in, int n_out) { + float lower_bound, distance_bounds; + + if (initialisation == ZERO) { + for (int i=0; i