mirror of
https://github.com/augustin64/projet-tipe
synced 2025-01-24 07:36:24 +01:00
Merge branch 'main' of https://github.com/julienChemillier/TIPE
This commit is contained in:
commit
0e878a421e
6
Makefile
6
Makefile
@ -25,8 +25,8 @@ TESTS_SRC_CU += $(wildcard test/*.cu)
|
|||||||
TESTS_OBJ = $(TESTS_SRC:test/%.c=$(BUILDDIR)/test-%) $(TESTS_SRC_CU:test/%.cu=$(BUILDDIR)/test-%)
|
TESTS_OBJ = $(TESTS_SRC:test/%.c=$(BUILDDIR)/test-%) $(TESTS_SRC_CU:test/%.cu=$(BUILDDIR)/test-%)
|
||||||
|
|
||||||
# Compile flags
|
# Compile flags
|
||||||
CFLAGS = -std=gnu99 -lm -lpthread -ljpeg
|
CFLAGS = -std=gnu99 -lm -lpthread -ljpeg -fopenmp
|
||||||
NVCCFLAGS = -ljpeg
|
NVCCFLAGS = -ljpeg -Xcompiler -fopenmp
|
||||||
|
|
||||||
# Additional warning rules
|
# Additional warning rules
|
||||||
CFLAGS += -Wall -Wextra
|
CFLAGS += -Wall -Wextra
|
||||||
@ -35,6 +35,8 @@ NVCCFLAGS +=
|
|||||||
# -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable
|
# -Wno-unused-parameter -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable
|
||||||
# Compile with debug
|
# Compile with debug
|
||||||
# -g
|
# -g
|
||||||
|
# See memory leaks and Incorrect Read/Write
|
||||||
|
# -fsanitize=address -lasan
|
||||||
|
|
||||||
all: mnist cnn;
|
all: mnist cnn;
|
||||||
#
|
#
|
||||||
|
@ -34,6 +34,7 @@ On stocke pour chaque couche des informations supplémentaires en fonction de so
|
|||||||
type | nom de la variable | commentaire
|
type | nom de la variable | commentaire
|
||||||
:---:|:---:|:---:
|
:---:|:---:|:---:
|
||||||
uint32_t|activation|
|
uint32_t|activation|
|
||||||
|
uint32_t|linearisation|
|
||||||
uint32_t|k_size|
|
uint32_t|k_size|
|
||||||
uint32_t|rows|
|
uint32_t|rows|
|
||||||
uint32_t|columns|
|
uint32_t|columns|
|
||||||
@ -42,17 +43,19 @@ uint32_t|columns|
|
|||||||
type | nom de la variable | commentaire
|
type | nom de la variable | commentaire
|
||||||
:---:|:---:|:---:
|
:---:|:---:|:---:
|
||||||
uint32_t|activation|
|
uint32_t|activation|
|
||||||
|
uint32_t|linearisation|
|
||||||
uint32_t|input_units|
|
uint32_t|input_units|
|
||||||
uint32_t|output_units|
|
uint32_t|output_units|
|
||||||
|
|
||||||
#### Si la couche est de type pooling:
|
#### Si la couche est de type pooling:
|
||||||
type | nom de la variable | commentaire
|
type | nom de la variable | commentaire
|
||||||
:---:|:---:|:---:
|
:---:|:---:|:---:
|
||||||
|
uint32_t|linearisation|
|
||||||
uint32_t|pooling|
|
uint32_t|pooling|
|
||||||
|
|
||||||
|
|
||||||
### Corps
|
### Corps
|
||||||
On constitue ensuite le corps du fichier à partir des données contenues dans chauqe couche de la manière suivante:
|
On constitue ensuite le corps du fichier à partir des données contenues dans chaque couche de la manière suivante:
|
||||||
|
|
||||||
- Si la couche est de type pooling, on ne rajoute rien.
|
- Si la couche est de type pooling, on ne rajoute rien.
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#ifndef DEF_INITIALISATION_H
|
#ifndef DEF_INITIALISATION_H
|
||||||
#define DEF_INITIALISATION_H
|
#define DEF_INITIALISATION_H
|
||||||
|
|
||||||
// Génère un flotant entre 0 et 1
|
// Génère un flottant entre 0 et 1
|
||||||
#define RAND_FLT() ((float)rand())/((float)RAND_MAX)
|
#define RAND_FLT() ((float)rand())/((float)RAND_MAX)
|
||||||
|
|
||||||
#define ZERO 0
|
#define ZERO 0
|
||||||
|
@ -203,9 +203,7 @@ void free_dataset(jpegDataset* dataset) {
|
|||||||
}
|
}
|
||||||
free(dataset->fileNames);
|
free(dataset->fileNames);
|
||||||
free(dataset->labels);
|
free(dataset->labels);
|
||||||
#ifdef STORE_IMAGES_TO_RAM
|
|
||||||
free(dataset->images);
|
free(dataset->images);
|
||||||
#endif
|
|
||||||
free(dataset);
|
free(dataset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,18 +8,18 @@
|
|||||||
void make_average_pooling(float*** input, float*** output, int size, int output_depth, int output_dim) {
|
void make_average_pooling(float*** input, float*** output, int size, int output_depth, int output_dim) {
|
||||||
// input[output_depth][output_dim+size-1][output_dim+size-1]
|
// input[output_depth][output_dim+size-1][output_dim+size-1]
|
||||||
// output[output_depth][output_dim][output_dim]
|
// output[output_depth][output_dim][output_dim]
|
||||||
float average;
|
float sum;
|
||||||
int n = size*size;
|
int n = size*size;
|
||||||
for (int i=0; i < output_depth; i++) {
|
for (int i=0; i < output_depth; i++) {
|
||||||
for (int j=0; j < output_dim; j++) {
|
for (int j=0; j < output_dim; j++) {
|
||||||
for (int k=0; k < output_dim; k++) {
|
for (int k=0; k < output_dim; k++) {
|
||||||
average = 0.;
|
sum = 0.;
|
||||||
for (int a=0; a < size; a++) {
|
for (int a=0; a < size; a++) {
|
||||||
for (int b=0; b < size; b++) {
|
for (int b=0; b < size; b++) {
|
||||||
average += input[i][size*j +a][size*k +b];
|
sum += input[i][size*j +a][size*k +b];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output[i][j][k] = average/(float)n;
|
output[i][j][k] = sum/(float)n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,11 +62,12 @@ void write_couche(Network* network, int indice_couche, int type_couche, FILE* pt
|
|||||||
int output_dim = network->width[indice_couche+1];
|
int output_dim = network->width[indice_couche+1];
|
||||||
|
|
||||||
// Écriture du pré-corps
|
// Écriture du pré-corps
|
||||||
uint32_t pre_buffer[4];
|
uint32_t pre_buffer[5];
|
||||||
pre_buffer[0] = kernel->activation;
|
pre_buffer[0] = kernel->activation;
|
||||||
pre_buffer[1] = cnn->k_size;
|
pre_buffer[1] = kernel->linearisation;
|
||||||
pre_buffer[2] = cnn->rows;
|
pre_buffer[2] = cnn->k_size;
|
||||||
pre_buffer[3] = cnn->columns;
|
pre_buffer[3] = cnn->rows;
|
||||||
|
pre_buffer[4] = cnn->columns;
|
||||||
fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr);
|
fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr);
|
||||||
|
|
||||||
// Écriture du corps
|
// Écriture du corps
|
||||||
@ -93,10 +94,11 @@ void write_couche(Network* network, int indice_couche, int type_couche, FILE* pt
|
|||||||
Kernel_nn* nn = kernel->nn;
|
Kernel_nn* nn = kernel->nn;
|
||||||
|
|
||||||
// Écriture du pré-corps
|
// Écriture du pré-corps
|
||||||
uint32_t pre_buffer[3];
|
uint32_t pre_buffer[4];
|
||||||
pre_buffer[0] = kernel->activation;
|
pre_buffer[0] = kernel->activation;
|
||||||
pre_buffer[1] = nn->input_units;
|
pre_buffer[1] = kernel->linearisation;
|
||||||
pre_buffer[2] = nn->output_units;
|
pre_buffer[2] = nn->input_units;
|
||||||
|
pre_buffer[3] = nn->output_units;
|
||||||
fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr);
|
fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr);
|
||||||
|
|
||||||
// Écriture du corps
|
// Écriture du corps
|
||||||
@ -111,8 +113,9 @@ void write_couche(Network* network, int indice_couche, int type_couche, FILE* pt
|
|||||||
}
|
}
|
||||||
fwrite(buffer, sizeof(buffer), 1, ptr);
|
fwrite(buffer, sizeof(buffer), 1, ptr);
|
||||||
} else if (type_couche == 2) { // Cas du Pooling Layer
|
} else if (type_couche == 2) { // Cas du Pooling Layer
|
||||||
uint32_t pre_buffer[1];
|
uint32_t pre_buffer[2];
|
||||||
pre_buffer[0] = kernel->activation; // Variable du pooling
|
pre_buffer[0] = kernel->activation; // Variable du pooling
|
||||||
|
pre_buffer[1] = kernel->linearisation;
|
||||||
fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr);
|
fwrite(pre_buffer, sizeof(pre_buffer), 1, ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -167,9 +170,10 @@ Network* read_network(char* filename) {
|
|||||||
// Lecture de chaque couche
|
// Lecture de chaque couche
|
||||||
network->kernel = (Kernel**)malloc(sizeof(Kernel*)*size);
|
network->kernel = (Kernel**)malloc(sizeof(Kernel*)*size);
|
||||||
|
|
||||||
for (int i=0; i < (int)size; i++) {
|
for (int i=0; i < (int)size-1; i++) {
|
||||||
network->kernel[i] = read_kernel(type_couche[i], network->width[i+1], ptr);
|
network->kernel[i] = read_kernel(type_couche[i], network->width[i+1], ptr);
|
||||||
}
|
}
|
||||||
|
network->kernel[(int)size-1] = read_kernel(type_couche[(int)size-1], -1, ptr);
|
||||||
|
|
||||||
network->input = (float****)malloc(sizeof(float***)*size);
|
network->input = (float****)malloc(sizeof(float***)*size);
|
||||||
for (int i=0; i < (int)size; i++) { // input[size][couche->depth][couche->dim][couche->dim]
|
for (int i=0; i < (int)size; i++) { // input[size][couche->depth][couche->dim][couche->dim]
|
||||||
@ -209,14 +213,14 @@ Kernel* read_kernel(int type_couche, int output_dim, FILE* ptr) {
|
|||||||
// Lecture du "Pré-corps"
|
// Lecture du "Pré-corps"
|
||||||
kernel->cnn = (Kernel_cnn*)malloc(sizeof(Kernel_cnn));
|
kernel->cnn = (Kernel_cnn*)malloc(sizeof(Kernel_cnn));
|
||||||
kernel->nn = NULL;
|
kernel->nn = NULL;
|
||||||
uint32_t buffer[4];
|
uint32_t buffer[5];
|
||||||
fread(&buffer, sizeof(buffer), 1, ptr);
|
fread(&buffer, sizeof(buffer), 1, ptr);
|
||||||
|
|
||||||
kernel->activation = buffer[0];
|
kernel->activation = buffer[0];
|
||||||
kernel->linearisation = 0;
|
kernel->linearisation = buffer[1];
|
||||||
kernel->cnn->k_size = buffer[1];
|
kernel->cnn->k_size = buffer[2];
|
||||||
kernel->cnn->rows = buffer[2];
|
kernel->cnn->rows = buffer[3];
|
||||||
kernel->cnn->columns = buffer[3];
|
kernel->cnn->columns = buffer[4];
|
||||||
|
|
||||||
// Lecture du corps
|
// Lecture du corps
|
||||||
Kernel_cnn* cnn = kernel->cnn;
|
Kernel_cnn* cnn = kernel->cnn;
|
||||||
@ -261,12 +265,13 @@ Kernel* read_kernel(int type_couche, int output_dim, FILE* ptr) {
|
|||||||
// Lecture du "Pré-corps"
|
// Lecture du "Pré-corps"
|
||||||
kernel->nn = (Kernel_nn*)malloc(sizeof(Kernel_nn));
|
kernel->nn = (Kernel_nn*)malloc(sizeof(Kernel_nn));
|
||||||
kernel->cnn = NULL;
|
kernel->cnn = NULL;
|
||||||
uint32_t buffer[3];
|
uint32_t buffer[4];
|
||||||
fread(&buffer, sizeof(buffer), 1, ptr);
|
fread(&buffer, sizeof(buffer), 1, ptr);
|
||||||
|
|
||||||
kernel->activation = buffer[0];
|
kernel->activation = buffer[0];
|
||||||
kernel->nn->input_units = buffer[1];
|
kernel->linearisation = buffer[1];
|
||||||
kernel->nn->output_units = buffer[2];
|
kernel->nn->input_units = buffer[2];
|
||||||
|
kernel->nn->output_units = buffer[3];
|
||||||
|
|
||||||
// Lecture du corps
|
// Lecture du corps
|
||||||
Kernel_nn* nn = kernel->nn;
|
Kernel_nn* nn = kernel->nn;
|
||||||
@ -292,13 +297,14 @@ Kernel* read_kernel(int type_couche, int output_dim, FILE* ptr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (type_couche == 2) { // Cas du Pooling Layer
|
} else if (type_couche == 2) { // Cas du Pooling Layer
|
||||||
uint32_t pooling;
|
uint32_t pooling, linearisation;
|
||||||
fread(&pooling, sizeof(pooling), 1, ptr);
|
fread(&pooling, sizeof(pooling), 1, ptr);
|
||||||
|
fread(&linearisation, sizeof(linearisation), 1, ptr);
|
||||||
|
|
||||||
kernel->cnn = NULL;
|
kernel->cnn = NULL;
|
||||||
kernel->nn = NULL;
|
kernel->nn = NULL;
|
||||||
kernel->activation = pooling;
|
kernel->activation = pooling;
|
||||||
kernel->linearisation = pooling; // TODO: mettre à 0 la variable inutile
|
kernel->linearisation = linearisation;
|
||||||
}
|
}
|
||||||
return kernel;
|
return kernel;
|
||||||
}
|
}
|
@ -4,6 +4,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
#include "../mnist/include/mnist.h"
|
#include "../mnist/include/mnist.h"
|
||||||
#include "include/initialisation.h"
|
#include "include/initialisation.h"
|
||||||
@ -92,6 +93,13 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
jpegDataset* dataset; // Structure de données décrivant un dataset d'images jpeg
|
jpegDataset* dataset; // Structure de données décrivant un dataset d'images jpeg
|
||||||
int* shuffle_index; // shuffle_index[i] contient le nouvel index de l'élément à l'emplacement i avant mélange
|
int* shuffle_index; // shuffle_index[i] contient le nouvel index de l'élément à l'emplacement i avant mélange
|
||||||
|
|
||||||
|
double start_time, end_time;
|
||||||
|
double elapsed_time;
|
||||||
|
|
||||||
|
double algo_start = omp_get_wtime();
|
||||||
|
|
||||||
|
start_time = omp_get_wtime();
|
||||||
|
|
||||||
if (dataset_type == 0) { // Type MNIST
|
if (dataset_type == 0) { // Type MNIST
|
||||||
// Chargement des images du set de données MNIST
|
// Chargement des images du set de données MNIST
|
||||||
int* parameters = read_mnist_images_parameters(images_file);
|
int* parameters = read_mnist_images_parameters(images_file);
|
||||||
@ -113,7 +121,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
|
|
||||||
// Initialisation du réseau
|
// Initialisation du réseau
|
||||||
if (!recover) {
|
if (!recover) {
|
||||||
network = create_network_lenet5(1, 0, TANH, GLOROT, input_dim, input_depth);
|
network = create_network_lenet5(0.1, 0, TANH, GLOROT, input_dim, input_depth);
|
||||||
} else {
|
} else {
|
||||||
network = read_network(recover);
|
network = read_network(recover);
|
||||||
}
|
}
|
||||||
@ -179,8 +187,14 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
train_params->nb_images = BATCHES;
|
train_params->nb_images = BATCHES;
|
||||||
train_params->index = shuffle_index;
|
train_params->index = shuffle_index;
|
||||||
#endif
|
#endif
|
||||||
|
end_time = omp_get_wtime();
|
||||||
|
|
||||||
|
elapsed_time = end_time - start_time;
|
||||||
|
printf("Initialisation: %0.2lf s\n\n", elapsed_time);
|
||||||
|
|
||||||
for (int i=0; i < epochs; i++) {
|
for (int i=0; i < epochs; i++) {
|
||||||
|
|
||||||
|
start_time = omp_get_wtime();
|
||||||
// La variable accuracy permet d'avoir une ESTIMATION
|
// La variable accuracy permet d'avoir une ESTIMATION
|
||||||
// du taux de réussite et de l'entraînement du réseau,
|
// du taux de réussite et de l'entraînement du réseau,
|
||||||
// mais n'est en aucun cas une valeur réelle dans le cas
|
// mais n'est en aucun cas une valeur réelle dans le cas
|
||||||
@ -211,24 +225,35 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
nb_remaining_images -= BATCHES / nb_threads;
|
nb_remaining_images -= BATCHES / nb_threads;
|
||||||
}
|
}
|
||||||
train_parameters[k]->start = BATCHES*j + (BATCHES/nb_threads)*k;
|
train_parameters[k]->start = BATCHES*j + (BATCHES/nb_threads)*k;
|
||||||
train_parameters[k]->network = copy_network(network);
|
|
||||||
|
|
||||||
|
if (train_parameters[k]->start+train_parameters[k]->nb_images >= nb_images_total) {
|
||||||
|
train_parameters[k]->nb_images = nb_images_total - train_parameters[k]->start -1;
|
||||||
|
}
|
||||||
|
if (train_parameters[k]->nb_images > 0) {
|
||||||
|
train_parameters[k]->network = copy_network(network);
|
||||||
pthread_create( &tid[k], NULL, train_thread, (void*) train_parameters[k]);
|
pthread_create( &tid[k], NULL, train_thread, (void*) train_parameters[k]);
|
||||||
|
} else {
|
||||||
|
train_parameters[k]->network = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (int k=0; k < nb_threads; k++) {
|
for (int k=0; k < nb_threads; k++) {
|
||||||
// On attend la terminaison de chaque thread un à un
|
// On attend la terminaison de chaque thread un à un
|
||||||
|
if (train_parameters[k]->network) {
|
||||||
pthread_join( tid[k], NULL );
|
pthread_join( tid[k], NULL );
|
||||||
accuracy += train_parameters[k]->accuracy / (float) nb_images_total;
|
accuracy += train_parameters[k]->accuracy / (float) nb_images_total;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// On attend que tous les fils aient fini avant d'appliquer des modifications au réseau principal
|
// On attend que tous les fils aient fini avant d'appliquer des modifications au réseau principal
|
||||||
for (int k=0; k < nb_threads; k++) {
|
for (int k=0; k < nb_threads; k++) {
|
||||||
|
if (train_parameters[k]->network) { // Si le fil a été utilisé
|
||||||
update_weights(network, train_parameters[k]->network, train_parameters[k]->nb_images);
|
update_weights(network, train_parameters[k]->network, train_parameters[k]->nb_images);
|
||||||
update_bias(network, train_parameters[k]->network, train_parameters[k]->nb_images);
|
update_bias(network, train_parameters[k]->network, train_parameters[k]->nb_images);
|
||||||
free_network(train_parameters[k]->network);
|
free_network(train_parameters[k]->network);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
current_accuracy = accuracy * nb_images_total/((j+1)*BATCHES);
|
current_accuracy = accuracy * nb_images_total/((j+1)*BATCHES);
|
||||||
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "YELLOW"%0.1f%%"RESET" ", nb_threads, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100);
|
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "YELLOW"%0.2f%%"RESET" ", nb_threads, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#else
|
#else
|
||||||
(void)nb_images_total_remaining; // Juste pour enlever un warning
|
(void)nb_images_total_remaining; // Juste pour enlever un warning
|
||||||
@ -248,22 +273,42 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
update_weights(network, network, train_params->nb_images);
|
update_weights(network, network, train_params->nb_images);
|
||||||
update_bias(network, network, train_params->nb_images);
|
update_bias(network, network, train_params->nb_images);
|
||||||
|
|
||||||
printf("\rÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "YELLOW"%0.1f%%"RESET" ", i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100);
|
printf("\rÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "YELLOW"%0.4f%%"RESET" ", i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
end_time = omp_get_wtime();
|
||||||
|
elapsed_time = end_time - start_time;
|
||||||
#ifdef USE_MULTITHREADING
|
#ifdef USE_MULTITHREADING
|
||||||
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "GREEN"%0.1f%%"RESET" \n", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100);
|
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "GREEN"%0.4f%%"RESET"\tTemps: %0.2f s\n", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100, elapsed_time);
|
||||||
#else
|
#else
|
||||||
printf("\rÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "GREEN"%0.1f%%"RESET" \n", i, epochs, nb_images_total, nb_images_total, accuracy*100);
|
printf("\rÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "GREEN"%0.4f%%"RESET"\tTemps: %0.2f s\n", i, epochs, nb_images_total, nb_images_total, accuracy*100, elapsed_time);
|
||||||
#endif
|
#endif
|
||||||
write_network(out, network);
|
write_network(out, network);
|
||||||
}
|
}
|
||||||
free(shuffle_index);
|
free(shuffle_index);
|
||||||
free_network(network);
|
free_network(network);
|
||||||
|
|
||||||
#ifdef USE_MULTITHREADING
|
#ifdef USE_MULTITHREADING
|
||||||
free(tid);
|
free(tid);
|
||||||
#else
|
#else
|
||||||
free(train_params);
|
free(train_params);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (dataset_type == 0) {
|
||||||
|
for (int i=0; i < nb_images_total; i++) {
|
||||||
|
for (int j=0; j < 28; j++) {
|
||||||
|
free(images[i][j]);
|
||||||
|
}
|
||||||
|
free(images[i]);
|
||||||
|
}
|
||||||
|
free(images);
|
||||||
|
free(labels);
|
||||||
|
} else {
|
||||||
|
free_dataset(dataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
end_time = omp_get_wtime();
|
||||||
|
elapsed_time = end_time - algo_start;
|
||||||
|
printf("\nTemps total: %0.1f s\n", elapsed_time);
|
||||||
}
|
}
|
||||||
|
@ -46,9 +46,10 @@ bool equals_networks(Network* network1, Network* network2) {
|
|||||||
printf(BOLDRED "[ ERROR ]" RESET "network1->kernel[%d] et network1->kernel[%d] diffèrent de type\n", i, i);
|
printf(BOLDRED "[ ERROR ]" RESET "network1->kernel[%d] et network1->kernel[%d] diffèrent de type\n", i, i);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
checkEquals(kernel[i]->linearisation, "kernel[i]->linearisation", i);
|
||||||
if (!network1->kernel[i]->cnn && !network1->kernel[i]->nn) {
|
if (!network1->kernel[i]->cnn && !network1->kernel[i]->nn) {
|
||||||
// Type Pooling
|
// Type Pooling
|
||||||
// checkEquals(kernel[i]->linearisation, "kernel[i]->linearisation", i);
|
checkEquals(kernel[i]->activation, "kernel[i]->activation pour un pooling", i);
|
||||||
} else if (!network1->kernel[i]->cnn) {
|
} else if (!network1->kernel[i]->cnn) {
|
||||||
// Type NN
|
// Type NN
|
||||||
checkEquals(kernel[i]->nn->input_units, "kernel[i]->nn->input_units", i);
|
checkEquals(kernel[i]->nn->input_units, "kernel[i]->nn->input_units", i);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
#include "include/main.h"
|
#include "include/main.h"
|
||||||
#include "include/mnist.h"
|
#include "include/mnist.h"
|
||||||
|
#include "../include/colors.h"
|
||||||
#include "include/neuron_io.h"
|
#include "include/neuron_io.h"
|
||||||
#include "include/neural_network.h"
|
#include "include/neural_network.h"
|
||||||
|
|
||||||
@ -140,6 +141,7 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
int repartition[3] = {neurons, 42, nb_neurons_last_layer};
|
int repartition[3] = {neurons, 42, nb_neurons_last_layer};
|
||||||
|
|
||||||
float accuracy;
|
float accuracy;
|
||||||
|
float current_accuracy;
|
||||||
|
|
||||||
int nb_threads = get_nprocs();
|
int nb_threads = get_nprocs();
|
||||||
pthread_t *tid = (pthread_t *)malloc(nb_threads * sizeof(pthread_t));
|
pthread_t *tid = (pthread_t *)malloc(nb_threads * sizeof(pthread_t));
|
||||||
@ -229,10 +231,11 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
patch_network(network, train_parameters[j]->network, train_parameters[j]->nb_images);
|
patch_network(network, train_parameters[j]->network, train_parameters[j]->nb_images);
|
||||||
deletion_of_network(train_parameters[j]->network);
|
deletion_of_network(train_parameters[j]->network);
|
||||||
}
|
}
|
||||||
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: %0.1f%%", nb_threads, i, epochs, BATCHES*(k+1), nb_images_total, accuracy*100);
|
current_accuracy = accuracy*(nb_images_total/(BATCHES*(k+1)));
|
||||||
|
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "YELLOW"%0.1f%%"RESET, nb_threads, i, epochs, BATCHES*(k+1), nb_images_total, current_accuracy*100);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: %0.1f%%\n", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100);
|
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: "GREEN"%0.1f%%"RESET"\n", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100);
|
||||||
write_network(out, network);
|
write_network(out, network);
|
||||||
if (delta != NULL)
|
if (delta != NULL)
|
||||||
write_delta_network(delta, delta_network);
|
write_delta_network(delta, delta_network);
|
||||||
@ -245,6 +248,16 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
for (int j=0; j < nb_threads; j++) {
|
for (int j=0; j < nb_threads; j++) {
|
||||||
free(train_parameters[j]);
|
free(train_parameters[j]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (int i=0; i < nb_images_total; i++) {
|
||||||
|
for (int j=0; j < height; j++) {
|
||||||
|
free(images[i][j]);
|
||||||
|
}
|
||||||
|
free(images[i]);
|
||||||
|
}
|
||||||
|
free(images);
|
||||||
|
free(labels);
|
||||||
|
|
||||||
free(shuffle_indices);
|
free(shuffle_indices);
|
||||||
free(train_parameters);
|
free(train_parameters);
|
||||||
// On libère les espaces mémoire utilisés spécialement sur le CPU
|
// On libère les espaces mémoire utilisés spécialement sur le CPU
|
||||||
|
@ -84,14 +84,15 @@ void deletion_of_network(Network* network) {
|
|||||||
|
|
||||||
for (int i=0; i < network->nb_layers; i++) {
|
for (int i=0; i < network->nb_layers; i++) {
|
||||||
layer = network->layers[i];
|
layer = network->layers[i];
|
||||||
if (i != network->nb_layers-1) { // On exclut la dernière couche dont les neurones ne contiennent pas de poids sortants
|
|
||||||
for (int j=0; j < network->layers[i]->nb_neurons; j++) {
|
for (int j=0; j < network->layers[i]->nb_neurons; j++) {
|
||||||
neuron = layer->neurons[j];
|
neuron = layer->neurons[j];
|
||||||
|
if (i != network->nb_layers-1) { // On exclut la dernière couche dont les neurones ne contiennent pas de poids sortants
|
||||||
free(neuron->weights);
|
free(neuron->weights);
|
||||||
free(neuron->back_weights);
|
free(neuron->back_weights);
|
||||||
free(neuron->last_back_weights);
|
free(neuron->last_back_weights);
|
||||||
free(neuron);
|
|
||||||
}
|
}
|
||||||
|
free(neuron);
|
||||||
}
|
}
|
||||||
free(layer->neurons);
|
free(layer->neurons);
|
||||||
free(network->layers[i]);
|
free(network->layers[i]);
|
||||||
|
@ -24,6 +24,7 @@ Neuron* read_neuron(uint32_t nb_weights, FILE *ptr) {
|
|||||||
neuron->last_back_bias = 0.0;
|
neuron->last_back_bias = 0.0;
|
||||||
neuron->back_bias = 0.0;
|
neuron->back_bias = 0.0;
|
||||||
|
|
||||||
|
if (nb_weights != 0) {
|
||||||
neuron->last_back_weights = (float*)malloc(sizeof(float)*nb_weights);
|
neuron->last_back_weights = (float*)malloc(sizeof(float)*nb_weights);
|
||||||
neuron->back_weights = (float*)malloc(sizeof(float)*nb_weights);
|
neuron->back_weights = (float*)malloc(sizeof(float)*nb_weights);
|
||||||
neuron->weights = (float*)malloc(sizeof(float)*nb_weights);
|
neuron->weights = (float*)malloc(sizeof(float)*nb_weights);
|
||||||
@ -34,6 +35,7 @@ Neuron* read_neuron(uint32_t nb_weights, FILE *ptr) {
|
|||||||
neuron->back_weights[i] = 0.0;
|
neuron->back_weights[i] = 0.0;
|
||||||
neuron->last_back_weights[i] = 0.0;
|
neuron->last_back_weights[i] = 0.0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return neuron;
|
return neuron;
|
||||||
}
|
}
|
||||||
|
@ -63,9 +63,7 @@ void print_weights(char* filename) {
|
|||||||
|
|
||||||
void count_labels(char* filename) {
|
void count_labels(char* filename) {
|
||||||
uint32_t number_of_images = read_mnist_labels_nb_images(filename);
|
uint32_t number_of_images = read_mnist_labels_nb_images(filename);
|
||||||
|
unsigned int* labels = read_mnist_labels(filename);
|
||||||
unsigned int* labels = (unsigned int*)malloc(sizeof(unsigned int)*number_of_images);
|
|
||||||
labels = read_mnist_labels(filename);
|
|
||||||
|
|
||||||
unsigned int tab[10];
|
unsigned int tab[10];
|
||||||
|
|
||||||
@ -103,6 +101,7 @@ void create_network(char* filename, int sortie) {
|
|||||||
|
|
||||||
neuron->back_bias = 0.;
|
neuron->back_bias = 0.;
|
||||||
neuron->last_back_bias = 0.;
|
neuron->last_back_bias = 0.;
|
||||||
|
if (i != network->nb_layers-1) {
|
||||||
neuron->weights = (float*)malloc(sizeof(float)*neurons_per_layer[i+1]);
|
neuron->weights = (float*)malloc(sizeof(float)*neurons_per_layer[i+1]);
|
||||||
neuron->back_weights = (float*)malloc(sizeof(float)*neurons_per_layer[i+1]);
|
neuron->back_weights = (float*)malloc(sizeof(float)*neurons_per_layer[i+1]);
|
||||||
neuron->last_back_weights = (float*)malloc(sizeof(float)*neurons_per_layer[i+1]);
|
neuron->last_back_weights = (float*)malloc(sizeof(float)*neurons_per_layer[i+1]);
|
||||||
@ -111,6 +110,7 @@ void create_network(char* filename, int sortie) {
|
|||||||
neuron->back_weights[k] = 0.;
|
neuron->back_weights[k] = 0.;
|
||||||
neuron->last_back_weights[k] = 0.;
|
neuron->last_back_weights[k] = 0.;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
layer->neurons[j] = neuron;
|
layer->neurons[j] = neuron;
|
||||||
}
|
}
|
||||||
network->layers[i] = layer;
|
network->layers[i] = layer;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
#include "../src/cnn/include/convolution.h"
|
#include "../src/cnn/include/convolution.h"
|
||||||
#include "../src/cnn/include/struct.h"
|
#include "../src/cnn/include/struct.h"
|
||||||
@ -122,22 +123,23 @@ void run_convolution_test(int input_dim, int output_dim, int rows, int columns)
|
|||||||
|
|
||||||
|
|
||||||
// Lancement des calculs
|
// Lancement des calculs
|
||||||
clock_t start, end;
|
double start_time, end_time;
|
||||||
double cpu_time_used, gpu_time_used;
|
double cpu_time_used, gpu_time_used;
|
||||||
|
|
||||||
start = clock();
|
start_time = omp_get_wtime();
|
||||||
make_convolution_device(kernel, input, output_gpu, output_dim);
|
make_convolution_device(kernel, input, output_gpu, output_dim);
|
||||||
end = clock();
|
end_time = omp_get_wtime();
|
||||||
|
|
||||||
gpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
|
|
||||||
|
gpu_time_used = end_time - start_time;
|
||||||
printf("(%d, %d, %d, %d) Time used for GPU: %lf seconds\n", rows, columns, input_dim, output_dim, gpu_time_used);
|
printf("(%d, %d, %d, %d) Time used for GPU: %lf seconds\n", rows, columns, input_dim, output_dim, gpu_time_used);
|
||||||
|
|
||||||
|
|
||||||
start = clock();
|
start_time = omp_get_wtime();
|
||||||
make_convolution_cpu(kernel, input, output_cpu, output_dim);
|
make_convolution_cpu(kernel, input, output_cpu, output_dim);
|
||||||
end = clock();
|
end_time = omp_get_wtime();
|
||||||
|
|
||||||
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
|
cpu_time_used = end_time - start_time;
|
||||||
printf("(%d, %d, %d, %d) Time used for CPU: %lf seconds\n", rows, columns, input_dim, output_dim, cpu_time_used);
|
printf("(%d, %d, %d, %d) Time used for CPU: %lf seconds\n", rows, columns, input_dim, output_dim, cpu_time_used);
|
||||||
|
|
||||||
// Vérification de l'égalité des matrices
|
// Vérification de l'égalité des matrices
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <omp.h>
|
||||||
|
|
||||||
#include "../src/cnn/include/matrix_multiplication.h"
|
#include "../src/cnn/include/matrix_multiplication.h"
|
||||||
#include "../src/include/colors.h"
|
#include "../src/include/colors.h"
|
||||||
@ -70,7 +71,7 @@ bool check_matrices_equality(float** m1, float** m2, int n, int p, int acceptati
|
|||||||
}
|
}
|
||||||
|
|
||||||
void run_matrices_test(int n, int p, int q) {
|
void run_matrices_test(int n, int p, int q) {
|
||||||
clock_t start, end;
|
double start_time, end_time;
|
||||||
double cpu_time_used, gpu_time_used;
|
double cpu_time_used, gpu_time_used;
|
||||||
|
|
||||||
float** matrix1 = create_matrix(n, p);
|
float** matrix1 = create_matrix(n, p);
|
||||||
@ -79,18 +80,18 @@ void run_matrices_test(int n, int p, int q) {
|
|||||||
float** result_cpu = create_empty_matrix(n, q);
|
float** result_cpu = create_empty_matrix(n, q);
|
||||||
|
|
||||||
printf("(%d,%d)x(%d,%d) Data generation complete.\n", n, p, p, q);
|
printf("(%d,%d)x(%d,%d) Data generation complete.\n", n, p, p, q);
|
||||||
start = clock();
|
start_time = omp_get_wtime();
|
||||||
matrix_multiplication_device(matrix1, matrix2, result_gpu, n, p, q);
|
matrix_multiplication_device(matrix1, matrix2, result_gpu, n, p, q);
|
||||||
end = clock();
|
end_time = omp_get_wtime();
|
||||||
|
|
||||||
cpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
|
cpu_time_used = end_time - start_time;
|
||||||
printf("(%d,%d)x(%d,%d) Time used for GPU: %lf seconds\n", n, p, p, q, cpu_time_used);
|
printf("(%d,%d)x(%d,%d) Time used for GPU: %lf seconds\n", n, p, p, q, cpu_time_used);
|
||||||
|
|
||||||
start = clock();
|
start_time = omp_get_wtime();
|
||||||
matrix_multiplication_host(matrix1, matrix2, result_cpu, n, p, q);
|
matrix_multiplication_host(matrix1, matrix2, result_cpu, n, p, q);
|
||||||
end = clock();
|
end_time = omp_get_wtime();
|
||||||
|
|
||||||
gpu_time_used = ((double) (end - start)) / CLOCKS_PER_SEC;
|
gpu_time_used = end_time - start_time;
|
||||||
printf("(%d,%d)x(%d,%d) Time used for CPU: %lf seconds\n", n, p, p, q, gpu_time_used);
|
printf("(%d,%d)x(%d,%d) Time used for CPU: %lf seconds\n", n, p, p, q, gpu_time_used);
|
||||||
|
|
||||||
// Vérification de l'égalité des matrices
|
// Vérification de l'égalité des matrices
|
||||||
|
@ -22,11 +22,16 @@ int main() {
|
|||||||
|
|
||||||
printf("Vérification de l'accès en lecture\n");
|
printf("Vérification de l'accès en lecture\n");
|
||||||
Network* network2 = read_network((char*)".test-cache/cnn_neuron_io.bin");
|
Network* network2 = read_network((char*)".test-cache/cnn_neuron_io.bin");
|
||||||
|
Network* network3 = read_network((char*)".test-cache/cnn_neuron_io.bin");
|
||||||
printf(GREEN "OK\n" RESET);
|
printf(GREEN "OK\n" RESET);
|
||||||
|
|
||||||
printf("Vérification de l'égalité des réseaux\n");
|
printf("Vérification de l'égalité des réseaux\n");
|
||||||
if (! equals_networks(network, network2)) {
|
if (! equals_networks(network, network2)) {
|
||||||
printf_error(RED "Les deux réseaux obtenus ne sont pas égaux.\n" RESET);
|
printf_error(RED "Le réseau lu ne contient pas les mêmes données.\n" RESET);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (! equals_networks(network2, network3)) {
|
||||||
|
printf_error(RED "La lecture du réseau donne des résultats différents.\n" RESET);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf(GREEN "OK\n" RESET);
|
printf(GREEN "OK\n" RESET);
|
||||||
@ -34,6 +39,7 @@ int main() {
|
|||||||
printf("Libération de la mémoire\n");
|
printf("Libération de la mémoire\n");
|
||||||
free_network(network);
|
free_network(network);
|
||||||
free_network(network2);
|
free_network(network2);
|
||||||
|
free_network(network3);
|
||||||
printf(GREEN "OK\n" RESET);
|
printf(GREEN "OK\n" RESET);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -21,7 +21,6 @@ int main() {
|
|||||||
kernel = network->kernel[i];
|
kernel = network->kernel[i];
|
||||||
if ((!kernel->cnn)&&(!kernel->nn)) {
|
if ((!kernel->cnn)&&(!kernel->nn)) {
|
||||||
printf("\n==== Couche %d de type "YELLOW"Pooling"RESET" ====\n", i);
|
printf("\n==== Couche %d de type "YELLOW"Pooling"RESET" ====\n", i);
|
||||||
printf("Linéarisation: %d\n", kernel->linearisation);
|
|
||||||
} else if (!kernel->cnn) {
|
} else if (!kernel->cnn) {
|
||||||
printf("\n==== Couche %d de type "GREEN"NN"RESET" ====\n", i);
|
printf("\n==== Couche %d de type "GREEN"NN"RESET" ====\n", i);
|
||||||
printf("input: %d\n", kernel->nn->input_units);
|
printf("input: %d\n", kernel->nn->input_units);
|
||||||
@ -32,8 +31,12 @@ int main() {
|
|||||||
printf("rows: %d\n", kernel->cnn->rows);
|
printf("rows: %d\n", kernel->cnn->rows);
|
||||||
printf("columns: %d\n", kernel->cnn->columns);
|
printf("columns: %d\n", kernel->cnn->columns);
|
||||||
}
|
}
|
||||||
|
if (kernel->linearisation) {
|
||||||
|
printf(YELLOW"Linéarisation: %d\n"RESET, kernel->linearisation);
|
||||||
|
}
|
||||||
printf("width: %d\n", network->width[i]);
|
printf("width: %d\n", network->width[i]);
|
||||||
printf("depth: %d\n", network->depth[i]);
|
printf("depth: %d\n", network->depth[i]);
|
||||||
|
printf("activation: %d\n", kernel->activation);
|
||||||
}
|
}
|
||||||
printf(GREEN "\nOK\n" RESET);
|
printf(GREEN "\nOK\n" RESET);
|
||||||
|
|
||||||
|
@ -49,5 +49,14 @@ int main() {
|
|||||||
read_test(nb_images, width, height, images, labels);
|
read_test(nb_images, width, height, images, labels);
|
||||||
|
|
||||||
printf(GREEN "OK\n" RESET);
|
printf(GREEN "OK\n" RESET);
|
||||||
|
for (int i=0; i < nb_images; i++) {
|
||||||
|
for (int j=0; j < height; j++) {
|
||||||
|
free(images[i][j]);
|
||||||
|
}
|
||||||
|
free(images[i]);
|
||||||
|
}
|
||||||
|
free(images);
|
||||||
|
free(labels);
|
||||||
|
free(parameters);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
Neuron* creer_neuron(int nb_sortants) {
|
Neuron* creer_neuron(int nb_sortants) {
|
||||||
Neuron* neuron = (Neuron*)malloc(sizeof(Neuron));
|
Neuron* neuron = (Neuron*)malloc(sizeof(Neuron));
|
||||||
|
if (nb_sortants != 0) {
|
||||||
neuron->weights = (float*)malloc(sizeof(float)*nb_sortants);
|
neuron->weights = (float*)malloc(sizeof(float)*nb_sortants);
|
||||||
neuron->back_weights = (float*)malloc(sizeof(float)*nb_sortants);
|
neuron->back_weights = (float*)malloc(sizeof(float)*nb_sortants);
|
||||||
neuron->last_back_weights = (float*)malloc(sizeof(float)*nb_sortants);
|
neuron->last_back_weights = (float*)malloc(sizeof(float)*nb_sortants);
|
||||||
@ -24,6 +25,7 @@ Neuron* creer_neuron(int nb_sortants) {
|
|||||||
neuron->bias = 0.0;
|
neuron->bias = 0.0;
|
||||||
neuron->back_bias = 0.0;
|
neuron->back_bias = 0.0;
|
||||||
neuron->last_back_bias = 0.0;
|
neuron->last_back_bias = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
return neuron;
|
return neuron;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user