diff --git a/doc/cnn.md b/doc/cnn.md index a8d990e..a1d7a7f 100644 --- a/doc/cnn.md +++ b/doc/cnn.md @@ -60,20 +60,20 @@ On constitue ensuite le corps du fichier à partir des données contenues dans c type | nom de la variable | commentaire :---:|:---:|:---: -uint32_t|bias[0][0][0]|biais -uint32_t|...| -uint32_t|bias[cnn->columns-1][cnn->k_size-1][cnn->k_size-1]| -uint32_t|w[0][0][0][0]|poids -uint32_t|...| -uint32_t|w[cnn->rows][cnn->columns-1][cnn->k_size-1][cnn->k_size-1]| +float|bias[0][0][0]|biais +float|...| +float|bias[cnn->columns-1][cnn->k_size-1][cnn->k_size-1]| +float|w[0][0][0][0]|poids +float|...| +float|w[cnn->rows][cnn->columns-1][cnn->k_size-1][cnn->k_size-1]| - Si la couche est de type nn, on ajoute les poids de manière croissante sur leurs indices: type | nom de la variable | commentaire :---:|:---:|:---: -uint32_t|bias[0]|biais -uint32_t|...| -uint32_t|bias[nn->output_units-1]|biais -uint32_t|weights[0][0]|poids -uint32_t|...| -uint32_t|weights[nn->input_units-1][nn->output_units-1]| +float|bias[0]|biais +float|...| +float|bias[nn->output_units-1]|biais +float|weights[0][0]|poids +float|...| +float|weights[nn->input_units-1][nn->output_units-1]| diff --git a/src/cnn/neuron_io.c b/src/cnn/neuron_io.c index b20f62c..33a5841 100644 --- a/src/cnn/neuron_io.c +++ b/src/cnn/neuron_io.c @@ -22,6 +22,7 @@ void write_network(char* filename, Network* network) { buffer[2] = network->initialisation; buffer[3] = network->dropout; + // Écriture du header for (int i=0; i < size; i++) { buffer[2*i+4] = network->width[i]; buffer[2*i+5] = network->depth[i]; @@ -40,7 +41,7 @@ void write_network(char* filename, Network* network) { fwrite(buffer, sizeof(buffer), 1, ptr); - + // Écriture du pré-corps et corps for (int i=0; i < size; i++) { write_couche(network->kernel[i], type_couche[i], ptr); } @@ -50,14 +51,19 @@ void write_network(char* filename, Network* network) { void write_couche(Kernel* kernel, int type_couche, FILE* ptr) { - uint32_t activation[1]; int indice; - - activation[0] = kernel->activation; - - fwrite(activation, sizeof(activation), 1, ptr); - if (type_couche == 0) { + if (type_couche == 0) { // Cas du CNN Kernel_cnn* cnn = kernel->cnn; + + // Écriture du pré-corps + uint32_t pre_buffer[4]; + pre_buffer[0] = kernel->activation; + pre_buffer[1] = cnn->k_size; + pre_buffer[2] = cnn->rows; + pre_buffer[3] = cnn->columns; + fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr); + + // Écriture du corps float buffer[2*cnn->k_size*cnn->k_size*cnn->columns*(cnn->rows+1)]; for (int i=0; i < cnn->columns; i++) { for (int j=0; j < cnn->k_size; j++) { @@ -79,8 +85,17 @@ void write_couche(Kernel* kernel, int type_couche, FILE* ptr) { } } fwrite(buffer, sizeof(buffer), 1, ptr); - } else if (type_couche == 1) { + } else if (type_couche == 1) { // Cas du NN Kernel_nn* nn = kernel->nn; + + // Écriture du pré-corps + uint32_t pre_buffer[3]; + pre_buffer[0] = kernel->activation; + pre_buffer[1] = nn->input_units; + pre_buffer[2] = nn->output_units; + fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr); + + // Écriture du corps float buffer[(1+nn->input_units)*nn->output_units]; for (int i=0; i < nn->output_units; i++) { buffer[i] = nn->bias[i]; @@ -92,6 +107,10 @@ void write_couche(Kernel* kernel, int type_couche, FILE* ptr) { } } fwrite(buffer, sizeof(buffer), 1, ptr); + } else if (type_couche == 2) { // Cas du Pooling Layer + uint32_t pre_buffer[1]; + pre_buffer[0] = kernel->activation; // Variable du pooling + fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr); } } @@ -100,6 +119,7 @@ Network* read_network(char* filename) { FILE *ptr; Network* network = (Network*)malloc(sizeof(Network)); // TODO: malloc pour network -> input + printf("\033[33;1m[WARNING]\033[0m Chargement depuis un fichier, network->input ne sera pas alloué\n"); ptr = fopen(filename, "rb"); @@ -155,11 +175,92 @@ Network* read_network(char* filename) { Kernel* read_kernel(int type_couche, FILE* ptr) { Kernel* kernel = (Kernel*)malloc(sizeof(Kernel)); - if (type_couche == 0) { - // TODO: lecture d'un CNN - } else if (type_couche == 1) { - // TODO: lecture d'un NN - } else if (type_couche == 2) { + if (type_couche == 0) { // Cas du CNN + // Lecture du "Pré-corps" + kernel->cnn = (Kernel_cnn*)malloc(sizeof(Kernel_cnn)); + kernel->nn = NULL; + uint32_t buffer[4]; + fread(&buffer, sizeof(buffer), 1, ptr); + + kernel->activation = buffer[0]; + kernel->cnn->k_size = buffer[1]; + kernel->cnn->rows = buffer[2]; + kernel->cnn->columns = buffer[3]; + + // Lecture du corps + Kernel_cnn* cnn = kernel->cnn; + float tmp; + + cnn->bias = (float***)malloc(sizeof(float**)*cnn->columns); + cnn->d_bias = (float***)malloc(sizeof(float**)*cnn->columns); + for (int i=0; i < cnn->columns; i++) { + cnn->bias[i] = (float**)malloc(sizeof(float*)*cnn->k_size); + cnn->d_bias[i] = (float**)malloc(sizeof(float*)*cnn->k_size); + for (int j=0; j < cnn->k_size; j++) { + cnn->bias[i][j] = (float*)malloc(sizeof(float)*cnn->k_size); + cnn->d_bias[i][j] = (float*)malloc(sizeof(float)*cnn->k_size); + for (int k=0; k < cnn->k_size; k++) { + fread(&tmp, sizeof(tmp), 1, ptr); + cnn->bias[i][j][k] = tmp; + cnn->d_bias[i][j][k] = 0.; + } + } + } + + cnn->w = (float****)malloc(sizeof(float***)*cnn->rows); + cnn->d_w = (float****)malloc(sizeof(float***)*cnn->rows); + for (int i=0; i < cnn->rows; i++) { + cnn->w[i] = (float***)malloc(sizeof(float**)*cnn->columns); + cnn->d_w[i] = (float***)malloc(sizeof(float**)*cnn->columns); + for (int j=0; j < cnn->columns; j++) { + cnn->w[i][j] = (float**)malloc(sizeof(float*)*cnn->k_size); + cnn->d_w[i][j] = (float**)malloc(sizeof(float*)*cnn->k_size); + for (int k=0; k < cnn->k_size; k++) { + cnn->w[i][j][k] = (float*)malloc(sizeof(float)*cnn->k_size); + cnn->d_w[i][j][k] = (float*)malloc(sizeof(float)*cnn->k_size); + for (int l=0; l < cnn->k_size; l++) { + fread(&tmp, sizeof(tmp), 1, ptr); + cnn->w[i][j][k][l] = tmp; + cnn->d_w[i][j][k][l] = 0.; + } + } + } + } + } else if (type_couche == 1) { // Cas du NN + // Lecture du "Pré-corps" + kernel->nn = (Kernel_nn*)malloc(sizeof(Kernel_nn)); + kernel->cnn = NULL; + uint32_t buffer[3]; + fread(&buffer, sizeof(buffer), 1, ptr); + + kernel->activation = buffer[0]; + kernel->nn->input_units = buffer[1]; + kernel->nn->output_units = buffer[2]; + + // Lecture du corps + Kernel_nn* nn = kernel->nn; + float tmp; + + nn->bias = (float*)malloc(sizeof(float)*nn->output_units); + nn->d_bias = (float*)malloc(sizeof(float)*nn->output_units); + for (int i=0; i < nn->output_units; i++) { + fread(&tmp, sizeof(tmp), 1, ptr); + nn->bias[i] = tmp; + nn->d_bias[i] = 0.; + } + + nn->weights = (float**)malloc(sizeof(float*)*nn->input_units); + nn->d_weights = (float**)malloc(sizeof(float*)*nn->input_units); + for (int i=0; i < nn->input_units; i++) { + nn->weights[i] = malloc(sizeof(float)*nn->output_units); + nn->d_weights[i] = malloc(sizeof(float)*nn->output_units); + for (int j=0; j < nn->output_units; j++) { + fread(&tmp, sizeof(tmp), 1, ptr); + nn->weights[i][j] = tmp; + nn->d_weights[i][j] = 0.; + } + } + } else if (type_couche == 2) { // Cas du Pooling Layer uint32_t pooling; fread(&pooling, sizeof(pooling), 1, ptr); diff --git a/test/cnn_neuron_io.c b/test/cnn_neuron_io.c index c2e74ae..8594568 100644 --- a/test/cnn_neuron_io.c +++ b/test/cnn_neuron_io.c @@ -17,12 +17,14 @@ int main() { write_network(".test-cache/cnn_neuron_io.bin", network); printf("OK\n"); - /* printf("Vérification de l'accès en lecture\n"); - Network* network2 = read_network(".test-cache/neuron_io.bin"); + Network* network2 = read_network(".test-cache/cnn_neuron_io.bin"); + printf("OK\n"); + + /* + printf("Réécriture du nouveau réseau\n"); + write_network(".test-cache/cnn_neuron_io_2.bin", network2); printf("OK\n"); - deletion_of_network(network); - deletion_of_network(network2); */ return 0; } \ No newline at end of file