From 5ec7bab48880f9a30b61afd312c4624c67ddcfc7 Mon Sep 17 00:00:00 2001 From: julienChemillier Date: Thu, 25 May 2023 16:32:37 +0200 Subject: [PATCH] Add finetuning option --- src/cnn/cnn.c | 8 +++++++- src/cnn/include/cnn.h | 6 +++++- src/cnn/include/train.h | 3 ++- src/cnn/main.c | 14 ++++++++++++-- src/cnn/train.c | 11 +++++++---- 5 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/cnn/cnn.c b/src/cnn/cnn.c index c481483..f8420c4 100644 --- a/src/cnn/cnn.c +++ b/src/cnn/cnn.c @@ -229,7 +229,7 @@ void forward_propagation(Network* network) { } } -void backward_propagation(Network* network, int wanted_number) { +void backward_propagation(Network* network, int wanted_number, int finetuning) { int n = network->size; // Nombre de couches du réseau // Backward sur la dernière couche qui utilise toujours SOFTMAX @@ -264,12 +264,18 @@ void backward_propagation(Network* network, int wanted_number) { if (k_i->cnn) { // Convolution + if (finetuning == NN_AND_LINEARISATION || finetuning == NN_ONLY) { + return; // On arrête la backpropagation + } int kernel_size = k_i->cnn->k_size; backward_convolution(k_i->cnn, input, input_z, output, input_depth, input_width, output_depth, output_width, -activation, is_last_layer, kernel_size, padding, stride); } else if (k_i->nn) { // Full connection if (k_i->linearisation == DOESNT_LINEARISE) { // Vecteur -> Vecteur backward_dense(k_i->nn, input[0][0], input_z[0][0], output[0][0], input_width, output_width, -activation, is_last_layer); } else { // Matrice -> vecteur + if (finetuning == NN_ONLY) { + return; // On arrête la backpropagation + } backward_linearisation(k_i->nn, input, input_z, output[0][0], input_depth, input_width, output_width, -activation); } } else { // Pooling diff --git a/src/cnn/include/cnn.h b/src/cnn/include/cnn.h index 86c69b1..5ed7e7c 100644 --- a/src/cnn/include/cnn.h +++ b/src/cnn/include/cnn.h @@ -5,6 +5,10 @@ #ifndef DEF_MAIN_H #define DEF_MAIN_H +#define EVERYTHING 0 +#define NN_ONLY 1 +#define NN_AND_LINEARISATION 2 + /* * Renvoie l'indice de l'élément de valeur maximale dans un tableau de flottants * Utilisé pour trouver le neurone le plus activé de la dernière couche (résultat de la classification) @@ -38,7 +42,7 @@ void forward_propagation(Network* network); /* * Propage en arrière le cnn */ -void backward_propagation(Network* network, int wanted_number); +void backward_propagation(Network* network, int wanted_number, int finetuning); /* * Implémente le dropout durant l'apprentissage en suivant le papier de recherche suivant: diff --git a/src/cnn/include/train.h b/src/cnn/include/train.h index 5e15e7e..a29c954 100644 --- a/src/cnn/include/train.h +++ b/src/cnn/include/train.h @@ -23,6 +23,7 @@ typedef struct TrainParameters { int nb_images; // Nombre d'images à traiter float accuracy; // Accuracy (à renvoyer) float loss; // Loss (à renvoyer) + int finetuning; // Distance de parcours de la backpropagation bool offset; // Décalage aléatoire de l'image } TrainParameters; @@ -54,6 +55,6 @@ void* train_thread(void* parameters); /* * Fonction principale d'entraînement du réseau neuronal convolutif */ -void train(int dataset_type, char* images_file, char* labels_file, char* data_dir, int epochs, char* out, char* recover, bool with_offset); +void train(int dataset_type, char* images_file, char* labels_file, char* data_dir, int epochs, char* out, char* recover, bool with_offset, int finetuning); #endif \ No newline at end of file diff --git a/src/cnn/main.c b/src/cnn/main.c index 4932560..218b17c 100644 --- a/src/cnn/main.c +++ b/src/cnn/main.c @@ -28,6 +28,7 @@ void help(char* call) { printf("\t (jpg) \t--datadir | -dd [FOLDER]\tDossier contenant les images.\n"); printf("\t\t--recover | -r [FILENAME]\tRécupérer depuis un modèle existant.\n"); printf("\t\t--epochs | -e [int]\t\tNombre d'époques.\n"); + printf("\t\t--finetuning | -f [int]\t\tDistance de backpropagation (0: tout; 1: dense et linéarisation; 2:dense).\n"); printf("\t\t--out | -o [FILENAME]\tFichier où écrire le réseau de neurones.\n"); printf("\trecognize:\n"); printf("\t\t--dataset | -d (mnist|jpg)\tFormat de l'image à reconnaître.\n"); @@ -58,6 +59,7 @@ int main(int argc, char* argv[]) { char* labels_file = NULL; char* data_dir = NULL; int epochs = EPOCHS; + int finetuning = 0; int dataset_type = 0; char* out = NULL; char* recover = NULL; @@ -84,7 +86,10 @@ int main(int argc, char* argv[]) { epochs = strtol(argv[i+1], NULL, 10); i += 2; } - else if ((! strcmp(argv[i], "--out"))||(! strcmp(argv[i], "-o"))) { + else if ((! strcmp(argv[i], "--finetuning"))||(! strcmp(argv[i], "-f"))) { + finetuning = strtol(argv[i+1], NULL, 10); + i += 2; + } else if ((! strcmp(argv[i], "--out"))||(! strcmp(argv[i], "-o"))) { out = argv[i+1]; i += 2; } else if ((! strcmp(argv[i], "--recover"))||(! strcmp(argv[i], "-r"))) { @@ -125,7 +130,12 @@ int main(int argc, char* argv[]) { printf("Pas de fichier de sortie spécifié, défaut: out.bin\n"); out = "out.bin"; } - train(dataset_type, images_file, labels_file, data_dir, epochs, out, recover, offset); + + if (finetuning < 0 || finetuning > 2) { + printf_error("Mauvais paramètre pour '--finetuning'\n"); + return 1; + } + train(dataset_type, images_file, labels_file, data_dir, epochs, out, recover, offset, finetuning); return 0; } if (! strcmp(argv[1], "test")) { diff --git a/src/cnn/train.c b/src/cnn/train.c index b04c599..0238a38 100644 --- a/src/cnn/train.c +++ b/src/cnn/train.c @@ -57,6 +57,7 @@ void* train_thread(void* parameters) { int dataset_type = param->dataset_type; int start = param->start; int nb_images = param->nb_images; + int finetuning = param->finetuning; float* wanted_output; float accuracy = 0.; @@ -103,7 +104,7 @@ void* train_thread(void* parameters) { loss += compute_mean_squared_error(network->input[network->size-1][0][0], wanted_output, 10); gree(wanted_output, false); - backward_propagation(network, labels[index[i]]); + backward_propagation(network, labels[index[i]], finetuning); #ifdef DETAILED_TRAIN_TIMINGS printf("Temps de backward: "); @@ -143,7 +144,7 @@ void* train_thread(void* parameters) { #endif maxi = indice_max(network->input[network->size-1][0][0], param->dataset->numCategories); - backward_propagation(network, param->dataset->labels[index[i]]); + backward_propagation(network, param->dataset->labels[index[i]], finetuning); #ifdef DETAILED_TRAIN_TIMINGS printf("Temps de backward: "); @@ -170,7 +171,7 @@ void* train_thread(void* parameters) { } -void train(int dataset_type, char* images_file, char* labels_file, char* data_dir, int epochs, char* out, char* recover, bool offset) { +void train(int dataset_type, char* images_file, char* labels_file, char* data_dir, int epochs, char* out, char* recover, bool offset, int finetuning) { #ifdef USE_CUDA bool compatibility = cuda_setup(true); if (!compatibility) { @@ -289,6 +290,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di param->index = shuffle_index; param->network = copy_network(network); param->offset = offset; + param->finetuning = finetuning; } #else // Création des paramètres donnés à l'unique @@ -315,6 +317,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di train_params->nb_images = BATCHES; train_params->index = shuffle_index; train_params->offset = offset; + train_params->finetuning = finetuning; #endif end_time = omp_get_wtime(); @@ -485,4 +488,4 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di printf("\nTemps total: "); printf_time(elapsed_time); printf("\n"); -} +} \ No newline at end of file