2022-07-05 08:13:25 +02:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "creation.h"
|
|
|
|
#include "function.h"
|
|
|
|
#include "initialisation.h"
|
|
|
|
|
|
|
|
Network* create_network(int max_size, int dropout, int initialisation, int input_dim, int input_depth) {
|
2022-09-09 17:39:07 +02:00
|
|
|
if (dropout < 0 || dropout > 100) {
|
2022-07-05 08:13:25 +02:00
|
|
|
printf("Erreur, la probabilité de dropout n'est pas respecté, elle doit être comprise entre 0 et 100\n");
|
|
|
|
}
|
2022-09-09 17:39:07 +02:00
|
|
|
Network* network = (Network*)malloc(sizeof(Network));
|
2022-07-05 08:13:25 +02:00
|
|
|
network->max_size = max_size;
|
|
|
|
network->dropout = dropout;
|
|
|
|
network->initialisation = initialisation;
|
|
|
|
network->size = 1;
|
2022-09-09 17:39:07 +02:00
|
|
|
network->input = (float****)malloc(sizeof(float***)*max_size);
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel = (Kernel**)malloc(sizeof(Kernel*)*(max_size-1));
|
2022-09-12 17:56:44 +02:00
|
|
|
network->width = (int*)malloc(sizeof(int*)*max_size);
|
|
|
|
network->depth = (int*)malloc(sizeof(int*)*max_size);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int i=0; i < max_size; i++) {
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel[i] = (Kernel*)malloc(sizeof(Kernel));
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
2022-09-12 17:56:44 +02:00
|
|
|
network->width[0] = input_dim;
|
|
|
|
network->depth[0] = input_depth;
|
|
|
|
network->kernel[0]->nn = NULL;
|
|
|
|
network->kernel[0]->cnn = NULL;
|
2022-09-09 17:39:07 +02:00
|
|
|
create_a_cube_input_layer(network, 0, input_depth, input_dim);
|
2022-07-05 08:13:25 +02:00
|
|
|
return network;
|
|
|
|
}
|
|
|
|
|
|
|
|
Network* create_network_lenet5(int dropout, int activation, int initialisation) {
|
2022-09-10 17:17:49 +02:00
|
|
|
Network* network = create_network(8, dropout, initialisation, 32, 1);
|
2022-09-12 17:56:44 +02:00
|
|
|
network->kernel[0]->activation = activation;
|
2022-07-05 08:13:25 +02:00
|
|
|
add_convolution(network, 6, 5, activation);
|
|
|
|
add_average_pooling(network, 2, activation);
|
|
|
|
add_convolution(network, 16, 5, activation);
|
|
|
|
add_average_pooling_flatten(network, 2, activation);
|
|
|
|
add_dense(network, 120, 84, activation);
|
|
|
|
add_dense(network, 84, 10, activation);
|
|
|
|
add_dense(network, 10, 10, SOFTMAX);
|
|
|
|
return network;
|
|
|
|
}
|
|
|
|
|
|
|
|
void create_a_cube_input_layer(Network* network, int pos, int depth, int dim) {
|
2022-09-09 17:39:07 +02:00
|
|
|
network->input[pos] = (float***)malloc(sizeof(float**)*depth);
|
|
|
|
for (int i=0; i < depth; i++) {
|
|
|
|
network->input[pos][i] = (float**)malloc(sizeof(float*)*dim);
|
|
|
|
for (int j=0; j < dim; j++) {
|
|
|
|
network->input[pos][i][j] = (float*)malloc(sizeof(float)*dim);
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-12 17:56:44 +02:00
|
|
|
network->width[pos] = dim;
|
|
|
|
network->depth[pos] = depth;
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void create_a_line_input_layer(Network* network, int pos, int dim) {
|
2022-09-09 17:39:07 +02:00
|
|
|
network->input[pos] = (float***)malloc(sizeof(float**));
|
|
|
|
network->input[pos][0] = (float**)malloc(sizeof(float*));
|
|
|
|
network->input[pos][0][0] = (float*)malloc(sizeof(float)*dim);
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void add_average_pooling(Network* network, int kernel_size, int activation) {
|
|
|
|
int n = network->size;
|
|
|
|
if (network->max_size == n) {
|
|
|
|
printf("Impossible de rajouter une couche d'average pooling, le réseau est déjà plein\n");
|
|
|
|
return;
|
|
|
|
}
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel[n]->cnn = NULL;
|
|
|
|
network->kernel[n]->nn = NULL;
|
|
|
|
network->kernel[n]->activation = activation + 100*kernel_size;
|
2022-09-12 17:56:44 +02:00
|
|
|
create_a_cube_input_layer(network, n, network->depth[n-1], network->width[n-1]/2);
|
2022-07-05 08:13:25 +02:00
|
|
|
network->size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void add_average_pooling_flatten(Network* network, int kernel_size, int activation) {
|
|
|
|
int n = network->size;
|
|
|
|
if (network->max_size == n) {
|
|
|
|
printf("Impossible de rajouter une couche d'average pooling, le réseau est déjà plein\n");
|
|
|
|
return;
|
|
|
|
}
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel[n]->cnn = NULL;
|
|
|
|
network->kernel[n]->nn = NULL;
|
|
|
|
network->kernel[n]->activation = activation + 100*kernel_size;
|
2022-09-12 17:56:44 +02:00
|
|
|
int dim = (network->width[n-1]*network->width[n-1]*network->depth[n-1])/(kernel_size*kernel_size);
|
2022-07-05 08:13:25 +02:00
|
|
|
create_a_line_input_layer(network, n, dim);
|
|
|
|
network->size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void add_convolution(Network* network, int nb_filter, int kernel_size, int activation) {
|
2022-09-09 17:39:07 +02:00
|
|
|
int n = network->size;
|
2022-07-05 08:13:25 +02:00
|
|
|
if (network->max_size == n) {
|
|
|
|
printf("Impossible de rajouter une couche de convolution, le réseau est déjà plein\n");
|
|
|
|
return;
|
|
|
|
}
|
2022-09-12 17:56:44 +02:00
|
|
|
int r = network->depth[n-1];
|
2022-07-05 08:13:25 +02:00
|
|
|
int c = nb_filter;
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel[n]->nn = NULL;
|
|
|
|
network->kernel[n]->activation = activation;
|
2022-09-10 18:23:16 +02:00
|
|
|
network->kernel[n]->cnn = (Kernel_cnn*)malloc(sizeof(Kernel_cnn));
|
|
|
|
Kernel_cnn* cnn = network->kernel[n]->cnn;
|
|
|
|
|
|
|
|
cnn->k_size = kernel_size;
|
|
|
|
cnn->rows = r;
|
|
|
|
cnn->columns = c;
|
|
|
|
cnn->w = (float****)malloc(sizeof(float***)*r);
|
|
|
|
cnn->d_w = (float****)malloc(sizeof(float***)*r);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int i=0; i < r; i++) {
|
2022-09-10 18:23:16 +02:00
|
|
|
cnn->w[i] = (float***)malloc(sizeof(float**)*c);
|
|
|
|
cnn->d_w[i] = (float***)malloc(sizeof(float**)*c);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int j=0; j < c; j++) {
|
2022-09-10 18:23:16 +02:00
|
|
|
cnn->w[i][j] = (float**)malloc(sizeof(float*)*kernel_size);
|
|
|
|
cnn->d_w[i][j] = (float**)malloc(sizeof(float*)*kernel_size);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int k=0; k < kernel_size; k++) {
|
2022-09-10 18:23:16 +02:00
|
|
|
cnn->w[i][j][k] = (float*)malloc(sizeof(float)*kernel_size);
|
|
|
|
cnn->d_w[i][j][k] = (float*)malloc(sizeof(float)*kernel_size);
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-09-10 18:23:16 +02:00
|
|
|
cnn->bias = (float***)malloc(sizeof(float**)*c);
|
|
|
|
cnn->d_bias = (float***)malloc(sizeof(float**)*c);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int i=0; i < c; i++) {
|
2022-09-10 18:23:16 +02:00
|
|
|
cnn->bias[i] = (float**)malloc(sizeof(float*)*kernel_size);
|
|
|
|
cnn->d_bias[i] = (float**)malloc(sizeof(float*)*kernel_size);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int j=0; j < kernel_size; j++) {
|
2022-09-10 18:23:16 +02:00
|
|
|
cnn->bias[i][j] = (float*)malloc(sizeof(float)*kernel_size);
|
|
|
|
cnn->d_bias[i][j] = (float*)malloc(sizeof(float)*kernel_size);
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
|
|
|
}
|
2022-09-12 17:56:44 +02:00
|
|
|
create_a_cube_input_layer(network, n, c, network->width[n-1] - 2*(kernel_size/2));
|
|
|
|
int n_int = network->width[n-1]*network->width[n-1]*network->depth[n-1];
|
|
|
|
int n_out = network->width[n]*network->width[n]*network->depth[n];
|
2022-09-10 18:23:16 +02:00
|
|
|
initialisation_3d_matrix(network->initialisation, cnn->bias, c, kernel_size, kernel_size, n_int+n_out);
|
|
|
|
initialisation_3d_matrix(ZERO, cnn->d_bias, c, kernel_size, kernel_size, n_int+n_out);
|
|
|
|
initialisation_4d_matrix(network->initialisation, cnn->w, r, c, kernel_size, kernel_size, n_int+n_out);
|
|
|
|
initialisation_4d_matrix(ZERO, cnn->d_w, r, c, kernel_size, kernel_size, n_int+n_out);
|
2022-07-05 08:13:25 +02:00
|
|
|
network->size++;
|
|
|
|
}
|
|
|
|
|
|
|
|
void add_dense(Network* network, int input_units, int output_units, int activation) {
|
|
|
|
int n = network->size;
|
|
|
|
if (network->max_size == n) {
|
|
|
|
printf("Impossible de rajouter une couche dense, le réseau est déjà plein\n");
|
|
|
|
return;
|
|
|
|
}
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel[n]->cnn = NULL;
|
|
|
|
network->kernel[n]->nn = (Kernel_nn*)malloc(sizeof(Kernel_nn));
|
2022-09-10 18:23:16 +02:00
|
|
|
Kernel_nn* nn = network->kernel[n]->nn;
|
2022-09-10 17:17:49 +02:00
|
|
|
network->kernel[n]->activation = activation;
|
2022-09-10 18:23:16 +02:00
|
|
|
nn->input_units = input_units;
|
|
|
|
nn->output_units = output_units;
|
|
|
|
nn->bias = (float*)malloc(sizeof(float)*output_units);
|
|
|
|
nn->d_bias = (float*)malloc(sizeof(float)*output_units);
|
|
|
|
nn->weights = (float**)malloc(sizeof(float*)*input_units);
|
|
|
|
nn->d_weights = (float**)malloc(sizeof(float*)*input_units);
|
2022-09-09 17:39:07 +02:00
|
|
|
for (int i=0; i < input_units; i++) {
|
2022-09-10 18:23:16 +02:00
|
|
|
nn->weights[i] = (float*)malloc(sizeof(float)*output_units);
|
|
|
|
nn->d_weights[i] = (float*)malloc(sizeof(float)*output_units);
|
2022-07-05 08:13:25 +02:00
|
|
|
}
|
2022-09-10 18:23:16 +02:00
|
|
|
initialisation_1d_matrix(network->initialisation, nn->bias, output_units, output_units+input_units);
|
|
|
|
initialisation_1d_matrix(ZERO, nn->d_bias, output_units, output_units+input_units);
|
|
|
|
initialisation_2d_matrix(network->initialisation, nn->weights, input_units, output_units, output_units+input_units);
|
|
|
|
initialisation_2d_matrix(ZERO, nn->d_weights, input_units, output_units, output_units+input_units);
|
2022-07-05 08:13:25 +02:00
|
|
|
create_a_line_input_layer(network, n, output_units);
|
|
|
|
network->size++;
|
|
|
|
}
|