mirror of
https://github.com/augustin64/projet-tipe
synced 2025-01-23 23:26:25 +01:00
Changes in the structure of the cnn
This commit is contained in:
parent
d236055a6d
commit
cbd7b5427d
@ -14,7 +14,7 @@ Network* create_network(int max_size, int dropout, int initialisation, int input
|
||||
network->initialisation = initialisation;
|
||||
network->size = 1;
|
||||
network->input = (float****)malloc(sizeof(float***)*max_size);
|
||||
network->kernel = (Kernel**)malloc(sizeof(Kernel*)*(max_size-1));
|
||||
network->kernel = (Kernel**)malloc(sizeof(Kernel*)*max_size);
|
||||
network->width = (int*)malloc(sizeof(int*)*max_size);
|
||||
network->depth = (int*)malloc(sizeof(int*)*max_size);
|
||||
for (int i=0; i < max_size; i++) {
|
||||
@ -32,12 +32,12 @@ Network* create_network_lenet5(int dropout, int activation, int initialisation)
|
||||
Network* network = create_network(8, dropout, initialisation, 32, 1);
|
||||
network->kernel[0]->activation = activation;
|
||||
add_convolution(network, 6, 5, activation);
|
||||
add_average_pooling(network, 2, activation);
|
||||
add_2d_average_pooling(network, 2);
|
||||
add_convolution(network, 16, 5, activation);
|
||||
add_average_pooling_flatten(network, 2, activation);
|
||||
add_2d_average_pooling(network, 2);
|
||||
add_dense_linearisation(network, 160, 120, activation);
|
||||
add_dense(network, 120, 84, activation);
|
||||
add_dense(network, 84, 10, activation);
|
||||
add_dense(network, 10, 10, SOFTMAX);
|
||||
add_dense(network, 84, 10, SOFTMAX);
|
||||
return network;
|
||||
}
|
||||
|
||||
@ -57,9 +57,11 @@ void create_a_line_input_layer(Network* network, int pos, int dim) {
|
||||
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);
|
||||
network->width[pos] = dim;
|
||||
network->depth[pos] = 1;
|
||||
}
|
||||
|
||||
void add_average_pooling(Network* network, int kernel_size, int activation) {
|
||||
void add_2d_average_pooling(Network* network, int kernel_size) {
|
||||
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");
|
||||
@ -67,12 +69,12 @@ void add_average_pooling(Network* network, int kernel_size, int activation) {
|
||||
}
|
||||
network->kernel[n]->cnn = NULL;
|
||||
network->kernel[n]->nn = NULL;
|
||||
network->kernel[n]->activation = activation + 100*kernel_size;
|
||||
network->kernel[n]->activation = 100*kernel_size; // Ne contient pas de fonction d'activation
|
||||
create_a_cube_input_layer(network, n, network->depth[n-1], network->width[n-1]/2);
|
||||
network->size++;
|
||||
}
|
||||
|
||||
void add_average_pooling_flatten(Network* network, int kernel_size, int activation) {
|
||||
void add_average_pooling_flatten(Network* network, int kernel_size) { // NEED TO BE VERIFIED
|
||||
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");
|
||||
@ -80,7 +82,7 @@ void add_average_pooling_flatten(Network* network, int kernel_size, int activati
|
||||
}
|
||||
network->kernel[n]->cnn = NULL;
|
||||
network->kernel[n]->nn = NULL;
|
||||
network->kernel[n]->activation = activation + 100*kernel_size;
|
||||
network->kernel[n]->activation = 100*kernel_size; // Ne contient pas de fonction d'activation
|
||||
int dim = (network->width[n-1]*network->width[n-1]*network->depth[n-1])/(kernel_size*kernel_size);
|
||||
create_a_line_input_layer(network, n, dim);
|
||||
network->size++;
|
||||
@ -92,6 +94,7 @@ void add_convolution(Network* network, int depth_output, int kernel_size, int ac
|
||||
printf("Impossible de rajouter une couche de convolution, le réseau est déjà plein \n");
|
||||
return;
|
||||
}
|
||||
int bias_size = network->width[n-1] - 2*(kernel_size/2);
|
||||
int depth_input = network->depth[n-1];
|
||||
network->kernel[n]->nn = NULL;
|
||||
network->kernel[n]->activation = activation;
|
||||
@ -118,14 +121,14 @@ void add_convolution(Network* network, int depth_output, int kernel_size, int ac
|
||||
cnn->bias = (float***)malloc(sizeof(float**)*depth_output);
|
||||
cnn->d_bias = (float***)malloc(sizeof(float**)*depth_output);
|
||||
for (int i=0; i < depth_output; i++) {
|
||||
cnn->bias[i] = (float**)malloc(sizeof(float*)*kernel_size);
|
||||
cnn->d_bias[i] = (float**)malloc(sizeof(float*)*kernel_size);
|
||||
for (int j=0; j < kernel_size; j++) {
|
||||
cnn->bias[i][j] = (float*)malloc(sizeof(float)*kernel_size);
|
||||
cnn->d_bias[i][j] = (float*)malloc(sizeof(float)*kernel_size);
|
||||
cnn->bias[i] = (float**)malloc(sizeof(float*)*bias_size);
|
||||
cnn->d_bias[i] = (float**)malloc(sizeof(float*)*bias_size);
|
||||
for (int j=0; j < bias_size; j++) {
|
||||
cnn->bias[i][j] = (float*)malloc(sizeof(float)*bias_size);
|
||||
cnn->d_bias[i][j] = (float*)malloc(sizeof(float)*bias_size);
|
||||
}
|
||||
}
|
||||
create_a_cube_input_layer(network, n, depth_output, network->width[n-1] - 2*(kernel_size/2));
|
||||
create_a_cube_input_layer(network, n, depth_output, bias_size);
|
||||
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];
|
||||
initialisation_3d_matrix(network->initialisation, cnn->bias, depth_output, kernel_size, kernel_size, n_int+n_out);
|
||||
@ -160,5 +163,37 @@ void add_dense(Network* network, int input_units, int output_units, int activati
|
||||
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);
|
||||
create_a_line_input_layer(network, n, output_units);
|
||||
network->size++;
|
||||
}
|
||||
|
||||
void add_dense_linearisation(Network* network, int input_units, int output_units, int activation) {
|
||||
// Can replace input_units by a research of this dim
|
||||
|
||||
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;
|
||||
}
|
||||
network->kernel[n]->cnn = NULL;
|
||||
network->kernel[n]->nn = (Kernel_nn*)malloc(sizeof(Kernel_nn));
|
||||
Kernel_nn* nn = network->kernel[n]->nn;
|
||||
network->kernel[n]->activation = activation;
|
||||
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);
|
||||
for (int i=0; i < input_units; i++) {
|
||||
nn->weights[i] = (float*)malloc(sizeof(float)*output_units);
|
||||
nn->d_weights[i] = (float*)malloc(sizeof(float)*output_units);
|
||||
}
|
||||
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);
|
||||
create_a_line_input_layer(network, n, output_units);
|
||||
|
||||
network->size++;
|
||||
}
|
@ -26,21 +26,26 @@ void create_a_line_input_layer(Network* network, int pos, int dim);
|
||||
/*
|
||||
* Ajoute au réseau une couche d'average pooling valide de dimension dim*dim
|
||||
*/
|
||||
void add_average_pooling(Network* network, int kernel_size, int activation);
|
||||
void add_2d_average_pooling(Network* network, int kernel_size);
|
||||
|
||||
/*
|
||||
* Ajoute au réseau une couche d'average pooling valide de dimension dim*dim qui aplatit
|
||||
*/
|
||||
void add_average_pooling_flatten(Network* network, int kernel_size, int activation);
|
||||
void add_average_pooling_flatten(Network* network, int kernel_size);
|
||||
|
||||
/*
|
||||
* Ajoute une couche de convolution dim*dim au réseau et initialise les kernels
|
||||
* Ajoute au réseau une couche de convolution dim*dim et initialise les kernels
|
||||
*/
|
||||
void add_convolution(Network* network, int nb_filter, int kernel_size, int activation);
|
||||
|
||||
/*
|
||||
* Ajoute une couche dense au réseau et initialise les poids et les biais
|
||||
* Ajoute au réseau une couche dense et initialise les poids et les biais
|
||||
*/
|
||||
void add_dense(Network* network, int input_units, int output_units, int activation);
|
||||
|
||||
/*
|
||||
* Ajoute au réseau une couche dense qui aplatit
|
||||
*/
|
||||
void add_dense_linearisation(Network* network, int input_units, int output_units, int activation);
|
||||
|
||||
#endif
|
@ -23,7 +23,8 @@ typedef struct Kernel_nn {
|
||||
typedef struct Kernel {
|
||||
Kernel_cnn* cnn; // NULL si ce n'est pas un cnn
|
||||
Kernel_nn* nn; // NULL si ce n'est pas un nn
|
||||
int activation; // Vaut l'activation sauf pour un pooling où il: vaut kernel_size*100 + activation
|
||||
int activation; // Vaut l'activation sauf pour un pooling où il: vaut pooling_size*100 + activation
|
||||
int linearisation; // Vaut 1 si c'est la linéarisation d'une couche, 0 sinon ?? Ajouter dans les autres
|
||||
} Kernel;
|
||||
|
||||
|
||||
|
@ -30,35 +30,48 @@ void write_image_in_network_32(int** image, int height, int width, float** input
|
||||
}
|
||||
|
||||
void forward_propagation(Network* network) {
|
||||
int output_dim, output_depth;
|
||||
int activation, input_width, input_depth, output_width, output_depth;
|
||||
int n = network->size;
|
||||
float*** input;
|
||||
float*** output;
|
||||
for (int i=0; i < network->size-1; i++) {
|
||||
if (network->kernel[i]->nn==NULL && network->kernel[i]->cnn!=NULL) { //CNN
|
||||
output = network->input[i+1];
|
||||
output_dim = network->width[i+1];
|
||||
output_depth = network->depth[i+1];
|
||||
make_convolution(network->input[i], network->kernel[i]->cnn, output, output_dim);
|
||||
choose_apply_function_input(network->kernel[i]->activation, output, output_depth, output_dim, output_dim);
|
||||
Kernel* k_i_1;
|
||||
Kernel* k_i;
|
||||
for (int i=0; i < n-1; i++) {
|
||||
k_i_1 = network->kernel[i+1];
|
||||
k_i = network->kernel[i];
|
||||
input_width = network->width[i];
|
||||
input_depth = network->depth[i];
|
||||
output_width = network->width[i+1];
|
||||
output_depth = network->depth[i+1];
|
||||
activation = network->kernel[i]->activation;
|
||||
input = network->input[i];
|
||||
output = network->input[i+1];
|
||||
|
||||
if (k_i_1->nn==NULL && k_i_1->cnn!=NULL) { //CNN
|
||||
printf("Convolution of cnn: %dx%d -> %dx%d\n", input_depth, input_width, output_depth, output_width);
|
||||
make_convolution(input, k_i_1->cnn, output, output_width);
|
||||
choose_apply_function_input(activation, output, output_depth, output_width, output_width);
|
||||
}
|
||||
else if (network->kernel[i]->nn!=NULL && network->kernel[i]->cnn==NULL) { //NN
|
||||
make_fully_connected(network->input[i][0][0], network->kernel[i]->nn, network->input[i+1][0][0], network->width[i], network->width[i+1]);
|
||||
choose_apply_function_input(network->kernel[i]->activation, network->input[i+1], 1, 1, network->width[i+1]);
|
||||
else if (k_i_1->nn!=NULL && k_i_1->cnn==NULL) { //NN
|
||||
printf("Densification of nn\n");
|
||||
// Checked if it is a nn which linearise
|
||||
make_fully_connected(network->input[i][0][0], network->kernel[i]->nn, network->input[i+1][0][0], input_width, output_width);
|
||||
choose_apply_function_input(activation, output, 1, 1, output_width);
|
||||
}
|
||||
else { //Pooling
|
||||
if (network->size-2==i) {
|
||||
else { //Pooling (Vérifier dedans) ??
|
||||
if (n-2==i) {
|
||||
printf("Le réseau ne peut pas finir par une pooling layer");
|
||||
return;
|
||||
}
|
||||
if (network->kernel[i+1]->nn!=NULL && network->kernel[i+1]->cnn==NULL) {
|
||||
make_average_pooling_flattened(network->input[i], network->input[i+1][0][0], network->kernel[i]->activation/100, network->depth[i], network->width[i]);
|
||||
choose_apply_function_input(network->kernel[i]->activation%100, network->input[i+1], 1, 1, network->width[i+1]);
|
||||
if (1==1) { // Pooling sur une matrice
|
||||
printf("Average pooling\n");
|
||||
make_average_pooling(input, output, activation/100, output_depth, output_width);
|
||||
}
|
||||
else if (network->kernel[i+1]->nn==NULL && network->kernel[i+1]->cnn!=NULL) {
|
||||
make_average_pooling(network->input[i], network->input[i+1], network->kernel[i]->activation/100, network->depth[i+1], network->width[i+1]);
|
||||
choose_apply_function_input(network->kernel[i]->activation%100, network->input[i+1], network->depth[i+1], network->width[i+1], network->width[i+1]);
|
||||
else if (1==0) { // Pooling sur un vecteur
|
||||
printf("Error: Not implemented: forward: %d\n", i);
|
||||
}
|
||||
else {
|
||||
printf("Le réseau ne peut pas contenir deux pooling layers collées");
|
||||
printf("Erreur: forward_propagation: %d -> %d %d\n", i, k_i_1->nn==NULL, k_i_1->cnn);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -128,6 +141,15 @@ float* generate_wanted_output(float wanted_number) {
|
||||
|
||||
int main() {
|
||||
Network* network = create_network_lenet5(0, TANH, GLOROT_NORMAL);
|
||||
for (int i=0; i<8; i++) {
|
||||
printf("%d %d \n", network->depth[i], network->width[i]);
|
||||
}
|
||||
printf("Kernel:\n");
|
||||
for (int i=0; i<7; i++) {
|
||||
if (network->kernel[i]->cnn!=NULL) {
|
||||
printf("%d -> %d %d\n", i, network->kernel[i]->cnn->rows, network->kernel[i]->cnn->k_size);
|
||||
}
|
||||
}
|
||||
forward_propagation(network);
|
||||
return 0;
|
||||
}
|
@ -5,6 +5,8 @@ void make_convolution(float*** input, Kernel_cnn* kernel, float*** output, int o
|
||||
//NOT FINISHED, MISS CONDITIONS ON THE CONVOLUTION
|
||||
float f;
|
||||
int n = kernel->k_size;
|
||||
printf("Convolution output: %dx%dx%d, %dx%dx%d\n", kernel->columns, output_dim, output_dim, kernel->rows, n, n);
|
||||
printf("BIS %d %d \n", kernel->columns, kernel->k_size);
|
||||
for (int i=0; i < kernel->columns; i++) {
|
||||
for (int j=0; j < output_dim; j++) {
|
||||
for (int k=0; k < output_dim; k++) {
|
||||
@ -35,7 +37,7 @@ void make_average_pooling(float*** input, float*** output, int size, int output_
|
||||
average += input[i][2*j +a][2*k +b];
|
||||
}
|
||||
}
|
||||
output[i][j][k] = average;
|
||||
output[i][j][k] = average/n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user