mirror of
https://github.com/augustin64/projet-tipe
synced 2025-02-02 19:39:39 +01:00
Merge branch 'main' of https://github.com/julienChemillier/TIPE
This commit is contained in:
commit
c74d3f574b
6
Makefile
6
Makefile
@ -65,10 +65,10 @@ $(BUILDDIR)/mnist_%.o: $(MNIST_SRCDIR)/%.c $(MNIST_SRCDIR)/include/%.h
|
|||||||
#
|
#
|
||||||
cnn: $(BUILDDIR)/cnn-main $(BUILDDIR)/cnn-main-cuda $(BUILDDIR)/cnn-preview;
|
cnn: $(BUILDDIR)/cnn-main $(BUILDDIR)/cnn-main-cuda $(BUILDDIR)/cnn-preview;
|
||||||
|
|
||||||
$(BUILDDIR)/cnn-main: $(CNN_SRCDIR)/main.c $(BUILDDIR)/cnn_train.o $(BUILDDIR)/cnn_cnn.o $(BUILDDIR)/cnn_creation.o $(BUILDDIR)/cnn_initialisation.o $(BUILDDIR)/cnn_make.o $(BUILDDIR)/cnn_neuron_io.o $(BUILDDIR)/cnn_function.o $(BUILDDIR)/cnn_utils.o $(BUILDDIR)/cnn_update.o $(BUILDDIR)/cnn_free.o $(BUILDDIR)/cnn_jpeg.o $(BUILDDIR)/cnn_convolution.o $(BUILDDIR)/cnn_backpropagation.o $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o
|
$(BUILDDIR)/cnn-main: $(CNN_SRCDIR)/main.c $(BUILDDIR)/cnn_train.o $(BUILDDIR)/cnn_test_network.o $(BUILDDIR)/cnn_cnn.o $(BUILDDIR)/cnn_creation.o $(BUILDDIR)/cnn_initialisation.o $(BUILDDIR)/cnn_make.o $(BUILDDIR)/cnn_neuron_io.o $(BUILDDIR)/cnn_function.o $(BUILDDIR)/cnn_utils.o $(BUILDDIR)/cnn_update.o $(BUILDDIR)/cnn_free.o $(BUILDDIR)/cnn_jpeg.o $(BUILDDIR)/cnn_convolution.o $(BUILDDIR)/cnn_backpropagation.o $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o
|
||||||
$(CC) $^ -o $@ $(CFLAGS)
|
$(CC) $^ -o $@ $(CFLAGS)
|
||||||
|
|
||||||
$(BUILDDIR)/cnn-main-cuda: $(BUILDDIR)/cnn_main.o $(BUILDDIR)/cnn_train.o $(BUILDDIR)/cnn_cnn.o $(BUILDDIR)/cnn_creation.o $(BUILDDIR)/cnn_initialisation.o $(BUILDDIR)/cnn_make.o $(BUILDDIR)/cnn_neuron_io.o $(BUILDDIR)/cnn_function.o $(BUILDDIR)/cnn_utils.o $(BUILDDIR)/cnn_update.o $(BUILDDIR)/cnn_free.o $(BUILDDIR)/cnn_jpeg.o $(BUILDDIR)/cnn_cuda_convolution.o $(BUILDDIR)/cnn_backpropagation.o $(BUILDDIR)/cuda_utils.o $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o
|
$(BUILDDIR)/cnn-main-cuda: $(BUILDDIR)/cnn_main.o $(BUILDDIR)/cnn_train.o $(BUILDDIR)/cnn_test_network.o $(BUILDDIR)/cnn_cnn.o $(BUILDDIR)/cnn_creation.o $(BUILDDIR)/cnn_initialisation.o $(BUILDDIR)/cnn_make.o $(BUILDDIR)/cnn_neuron_io.o $(BUILDDIR)/cnn_function.o $(BUILDDIR)/cnn_utils.o $(BUILDDIR)/cnn_update.o $(BUILDDIR)/cnn_free.o $(BUILDDIR)/cnn_jpeg.o $(BUILDDIR)/cnn_cuda_convolution.o $(BUILDDIR)/cnn_backpropagation.o $(BUILDDIR)/cuda_utils.o $(BUILDDIR)/colors.o $(BUILDDIR)/mnist.o
|
||||||
ifndef NVCC_INSTALLED
|
ifndef NVCC_INSTALLED
|
||||||
@echo "$(NVCC) not found, skipping"
|
@echo "$(NVCC) not found, skipping"
|
||||||
else
|
else
|
||||||
@ -105,7 +105,7 @@ endif
|
|||||||
#
|
#
|
||||||
run-tests: build-tests
|
run-tests: build-tests
|
||||||
$(foreach file, $(wildcard $(TEST_SRCDIR)/*.sh), $(file);)
|
$(foreach file, $(wildcard $(TEST_SRCDIR)/*.sh), $(file);)
|
||||||
@echo "$$(for file in build/test-*; do echo -e \\033[33m#####\\033[0m $$file \\033[33m#####\\033[0m; $$file; done)"
|
@echo "$$(for file in build/test-*; do echo -e \\033[33m#####\\033[0m $$file \\033[33m#####\\033[0m; $$file || echo "Erreur sur $$file"; done)"
|
||||||
|
|
||||||
build-tests: prepare-tests $(TESTS_OBJ) $(BUILDDIR)/test-cnn_matrix_multiplication $(BUILDDIR)/test-cnn_convolution
|
build-tests: prepare-tests $(TESTS_OBJ) $(BUILDDIR)/test-cnn_matrix_multiplication $(BUILDDIR)/test-cnn_convolution
|
||||||
|
|
||||||
|
@ -16,6 +16,19 @@
|
|||||||
// Augmente les dimensions de l'image d'entrée
|
// Augmente les dimensions de l'image d'entrée
|
||||||
#define PADDING_INPUT 2
|
#define PADDING_INPUT 2
|
||||||
|
|
||||||
|
int indice_max(float* tab, int n) {
|
||||||
|
int indice = -1;
|
||||||
|
float maxi = FLT_MIN;
|
||||||
|
|
||||||
|
for (int i=0; i < n; i++) {
|
||||||
|
if (tab[i] > maxi) {
|
||||||
|
maxi = tab[i];
|
||||||
|
indice = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indice;
|
||||||
|
}
|
||||||
|
|
||||||
int will_be_drop(int dropout_prob) {
|
int will_be_drop(int dropout_prob) {
|
||||||
return (rand() % 100) < dropout_prob;
|
return (rand() % 100) < dropout_prob;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,11 @@
|
|||||||
#ifndef DEF_MAIN_H
|
#ifndef DEF_MAIN_H
|
||||||
#define DEF_MAIN_H
|
#define DEF_MAIN_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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)
|
||||||
|
*/
|
||||||
|
int indice_max(float* tab, int n);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Renvoie si oui ou non (1 ou 0) le neurone va être abandonné
|
* Renvoie si oui ou non (1 ou 0) le neurone va être abandonné
|
||||||
|
25
src/cnn/include/test_network.h
Normal file
25
src/cnn/include/test_network.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#include "struct.h"
|
||||||
|
|
||||||
|
#ifndef DEF_TEST_NETWORK_H
|
||||||
|
#define DEF_TEST_NETWORK_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Renvoie le taux de réussite d'un réseau sur des données de test
|
||||||
|
*/
|
||||||
|
void test_network(int dataset_type, char* modele, char* images_file, char* labels_file, char* data_dir, bool preview_fails);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Classifie un fichier d'images sous le format MNIST à partir d'un réseau préalablement entraîné
|
||||||
|
*/
|
||||||
|
void recognize_mnist(Network* network, char* input_file);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Classifie une image jpg à partir d'un réseau préalablement entraîné
|
||||||
|
*/
|
||||||
|
void recognize_jpg(Network* network, char* input_file);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Classifie une image à partir d'un réseau préalablement entraîné
|
||||||
|
*/
|
||||||
|
void recognize(int dataset_type, char* modele, char* input_file);
|
||||||
|
#endif
|
@ -27,11 +27,6 @@ typedef struct TrainParameters {
|
|||||||
} TrainParameters;
|
} TrainParameters;
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Renvoie l'indice maximal d'un tableau tab de taille n
|
|
||||||
*/
|
|
||||||
int indice_max(float* tab, int n);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Fonction auxiliaire d'entraînement destinée à être exécutée sur plusieurs threads à la fois
|
* Fonction auxiliaire d'entraînement destinée à être exécutée sur plusieurs threads à la fois
|
||||||
*/
|
*/
|
||||||
|
156
src/cnn/main.c
156
src/cnn/main.c
@ -2,9 +2,11 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
|
||||||
#include "include/initialisation.h"
|
#include "include/initialisation.h"
|
||||||
|
#include "include/test_network.h"
|
||||||
#include "../include/colors.h"
|
#include "../include/colors.h"
|
||||||
#include "include/function.h"
|
#include "include/function.h"
|
||||||
#include "include/creation.h"
|
#include "include/creation.h"
|
||||||
@ -15,10 +17,8 @@
|
|||||||
|
|
||||||
|
|
||||||
void help(char* call) {
|
void help(char* call) {
|
||||||
printf("Usage: %s ( train | dev ) [OPTIONS]\n\n", call);
|
printf("Usage: %s ( train | recognize | test ) [OPTIONS]\n\n", call);
|
||||||
printf("OPTIONS:\n");
|
printf("OPTIONS:\n");
|
||||||
printf("\tdev:\n");
|
|
||||||
printf("\t\t--conv | -c\tTester la fonction dev_conv().\n");
|
|
||||||
printf("\ttrain:\n");
|
printf("\ttrain:\n");
|
||||||
printf("\t\t--dataset | -d (mnist|jpg)\tFormat du set de données.\n");
|
printf("\t\t--dataset | -d (mnist|jpg)\tFormat du set de données.\n");
|
||||||
printf("\t(mnist)\t--images | -i [FILENAME]\tFichier contenant les images.\n");
|
printf("\t(mnist)\t--images | -i [FILENAME]\tFichier contenant les images.\n");
|
||||||
@ -26,12 +26,17 @@ void help(char* call) {
|
|||||||
printf("\t (jpg) \t--datadir | -dd [FOLDER]\tDossier contenant les images.\n");
|
printf("\t (jpg) \t--datadir | -dd [FOLDER]\tDossier contenant les images.\n");
|
||||||
printf("\t\t--epochs | -e [int]\t\tNombre d'époques.\n");
|
printf("\t\t--epochs | -e [int]\t\tNombre d'époques.\n");
|
||||||
printf("\t\t--out | -o [FILENAME]\tFichier où écrire le réseau de neurones.\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");
|
||||||
|
printf("\t\t--modele | -m [FILENAME]\tFichier contenant le réseau entraîné.\n");
|
||||||
void dev_conv() {
|
printf("\t\t--input | -i [FILENAME]\tImage jpeg ou fichier binaire à reconnaître.\n");
|
||||||
Network* network = create_network_lenet5(0, 0, TANH, GLOROT, 32, 1);
|
printf("\ttest:\n");
|
||||||
forward_propagation(network);
|
printf("\t\t--modele | -m [FILENAME]\tFichier contenant le réseau entraîné.\n");
|
||||||
|
printf("\t\t--dataset | -d (mnist|jpg)\tFormat du set de données.\n");
|
||||||
|
printf("\t(mnist)\t--images | -i [FILENAME]\tFichier contenant les images.\n");
|
||||||
|
printf("\t(mnist)\t--labels | -l [FILENAME]\tFichier contenant les labels.\n");
|
||||||
|
printf("\t (jpg) \t--datadir | -dd [FOLDER]\tDossier contenant les images.\n");
|
||||||
|
printf("\t\t--preview-fails | -p\t\tAfficher les images ayant échoué.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -42,27 +47,6 @@ int main(int argc, char* argv[]) {
|
|||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (! strcmp(argv[1], "dev")) {
|
|
||||||
int option = 0;
|
|
||||||
// 0 pour la fonction dev_conv()
|
|
||||||
int i = 2;
|
|
||||||
while (i < argc) {
|
|
||||||
// Utiliser un switch serait sans doute plus élégant
|
|
||||||
if ((! strcmp(argv[i], "--conv"))||(! strcmp(argv[i], "-c"))) {
|
|
||||||
option = 0;
|
|
||||||
i++;
|
|
||||||
} else {
|
|
||||||
printf("Option choisie inconnue: %s\n", argv[i]);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (option == 0) {
|
|
||||||
dev_conv();
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
printf("Option choisie inconnue: dev %d\n", option);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (! strcmp(argv[1], "train")) {
|
if (! strcmp(argv[1], "train")) {
|
||||||
char* dataset = NULL;
|
char* dataset = NULL;
|
||||||
char* images_file = NULL;
|
char* images_file = NULL;
|
||||||
@ -130,6 +114,118 @@ int main(int argc, char* argv[]) {
|
|||||||
train(dataset_type, images_file, labels_file, data_dir, epochs, out);
|
train(dataset_type, images_file, labels_file, data_dir, epochs, out);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (! strcmp(argv[1], "test")) {
|
||||||
|
char* dataset = NULL; // mnist ou jpg
|
||||||
|
char* modele = NULL; // Fichier contenant le modèle
|
||||||
|
char* images_file = NULL; // Fichier d'images (mnist)
|
||||||
|
char* labels_file = NULL; // Fichier de labels (mnist)
|
||||||
|
char* data_dir = NULL; // Dossier d'images (jpg)
|
||||||
|
int dataset_type; // Type de dataset (0 pour mnist, 1 pour jpg)
|
||||||
|
bool preview_fails = false;
|
||||||
|
int i = 2;
|
||||||
|
while (i < argc) {
|
||||||
|
if ((! strcmp(argv[i], "--dataset"))||(! strcmp(argv[i], "-d"))) {
|
||||||
|
dataset = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--modele"))||(! strcmp(argv[i], "-m"))) {
|
||||||
|
modele = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--images"))||(! strcmp(argv[i], "-i"))) {
|
||||||
|
images_file = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--labels"))||(! strcmp(argv[i], "-l"))) {
|
||||||
|
labels_file = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--datadir"))||(! strcmp(argv[i], "-dd"))) {
|
||||||
|
data_dir = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--preview-fails"))||(! strcmp(argv[i], "-p"))) {
|
||||||
|
preview_fails = true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Option choisie inconnue: %s\n", argv[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((dataset!=NULL) && !strcmp(dataset, "mnist")) {
|
||||||
|
dataset_type = 0;
|
||||||
|
if (!images_file) {
|
||||||
|
printf("Pas de fichier d'images spécifié\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!labels_file) {
|
||||||
|
printf("Pas de fichier de labels spécifié\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((dataset!=NULL) && !strcmp(dataset, "jpg")) {
|
||||||
|
dataset_type = 1;
|
||||||
|
if (!data_dir) {
|
||||||
|
printf("Pas de dossier de données spécifié.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Pas de type de dataset spécifié.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!modele) {
|
||||||
|
printf("Pas de modèle à utiliser spécifié.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
test_network(dataset_type, modele, images_file, labels_file, data_dir, preview_fails);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
if (! strcmp(argv[1], "recognize")) {
|
||||||
|
char* dataset = NULL; // mnist ou jpg
|
||||||
|
char* modele = NULL; // Fichier contenant le modèle
|
||||||
|
char* input_file = NULL; // Image à reconnaître
|
||||||
|
int dataset_type;
|
||||||
|
int i = 2;
|
||||||
|
while (i < argc) {
|
||||||
|
if ((! strcmp(argv[i], "--dataset"))||(! strcmp(argv[i], "-d"))) {
|
||||||
|
dataset = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--modele"))||(! strcmp(argv[i], "-m"))) {
|
||||||
|
modele = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
}
|
||||||
|
else if ((! strcmp(argv[i], "--input"))||(! strcmp(argv[i], "-i"))) {
|
||||||
|
input_file = argv[i+1];
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
printf("Option choisie inconnue: %s\n", argv[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((dataset!=NULL) && !strcmp(dataset, "mnist")) {
|
||||||
|
dataset_type = 0;
|
||||||
|
} else if ((dataset!=NULL) && !strcmp(dataset, "jpg")) {
|
||||||
|
dataset_type = 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printf("Pas de type de dataset spécifié.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!input_file) {
|
||||||
|
printf("Pas de fichier d'entrée spécifié, rien à faire.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!modele) {
|
||||||
|
printf("Pas de modèle à utiliser spécifié.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
recognize(dataset_type, modele, input_file);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
printf("Option choisie non reconnue: %s\n", argv[1]);
|
printf("Option choisie non reconnue: %s\n", argv[1]);
|
||||||
help(argv[0]);
|
help(argv[0]);
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -185,6 +185,20 @@ Network* read_network(char* filename) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
network->input_z = (float****)malloc(sizeof(float***)*size);
|
||||||
|
for (int i=0; i < (int)size; i++) { // input[size][couche->depth][couche->dim][couche->dim]
|
||||||
|
network->input_z[i] = (float***)malloc(sizeof(float**)*network->depth[i]);
|
||||||
|
for (int j=0; j < network->depth[i]; j++) {
|
||||||
|
network->input_z[i][j] = (float**)malloc(sizeof(float*)*network->width[i]);
|
||||||
|
for (int k=0; k < network->width[i]; k++) {
|
||||||
|
network->input_z[i][j][k] = (float*)malloc(sizeof(float)*network->width[i]);
|
||||||
|
for (int l=0; l < network->width[i]; l++) {
|
||||||
|
network->input_z[i][j][k][l] = 0.;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fclose(ptr);
|
fclose(ptr);
|
||||||
return network;
|
return network;
|
||||||
}
|
}
|
||||||
|
158
src/cnn/test_network.c
Normal file
158
src/cnn/test_network.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "../mnist/include/mnist.h"
|
||||||
|
#include "include/neuron_io.h"
|
||||||
|
#include "include/struct.h"
|
||||||
|
#include "include/jpeg.h"
|
||||||
|
#include "include/free.h"
|
||||||
|
#include "include/cnn.h"
|
||||||
|
|
||||||
|
|
||||||
|
void test_network_mnist(Network* network, char* images_file, char* labels_file, bool preview_fails) {
|
||||||
|
(void)preview_fails; // Inutilisé pour le moment
|
||||||
|
int width, height; // Dimensions des images
|
||||||
|
int nb_elem; // Nombre d'éléments
|
||||||
|
int maxi; // Catégorie reconnue
|
||||||
|
|
||||||
|
int accuracy = 0; // Nombre d'images reconnues
|
||||||
|
|
||||||
|
// Load image
|
||||||
|
int* mnist_parameters = read_mnist_images_parameters(images_file);
|
||||||
|
|
||||||
|
int*** images = read_mnist_images(images_file);
|
||||||
|
unsigned int* labels = read_mnist_labels(labels_file);
|
||||||
|
|
||||||
|
nb_elem = mnist_parameters[0];
|
||||||
|
|
||||||
|
width = mnist_parameters[1];
|
||||||
|
height = mnist_parameters[2];
|
||||||
|
free(mnist_parameters);
|
||||||
|
|
||||||
|
// Load image in the first layer of the Network
|
||||||
|
for (int i=0; i < nb_elem; i++) {
|
||||||
|
if(i %(nb_elem/100) == 0) {
|
||||||
|
printf("Avancement: %.0f%%\r", 100*i/(float)nb_elem);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
write_image_in_network_32(images[i], height, width, network->input[0][0]);
|
||||||
|
forward_propagation(network);
|
||||||
|
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
||||||
|
|
||||||
|
if (maxi == (int)labels[i]) {
|
||||||
|
accuracy++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int j=0; j < height; j++) {
|
||||||
|
free(images[i][j]);
|
||||||
|
}
|
||||||
|
free(images[i]);
|
||||||
|
}
|
||||||
|
free(images);
|
||||||
|
printf("%d Images. Taux de réussite: %.2f%%\n", nb_elem, 100*accuracy/(float)nb_elem);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_network_jpg(Network* network, char* data_dir, bool preview_fails) {
|
||||||
|
(void)preview_fails; // Inutilisé pour le moment
|
||||||
|
jpegDataset* dataset = loadJpegDataset(data_dir);
|
||||||
|
|
||||||
|
int accuracy = 0;
|
||||||
|
int maxi;
|
||||||
|
|
||||||
|
for (int i=0; i < (int)dataset->numImages; i++) {
|
||||||
|
if(i %(dataset->numImages/100) == 0) {
|
||||||
|
printf("Avancement: %.1f%%\r", 1000*i/(float)dataset->numImages);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
write_image_in_network_260(dataset->images[i], dataset->height, dataset->height, network->input[0]);
|
||||||
|
forward_propagation(network);
|
||||||
|
maxi = indice_max(network->input[network->size-1][0][0], 50);
|
||||||
|
|
||||||
|
if (maxi == (int)dataset->labels[i]) {
|
||||||
|
accuracy++;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(dataset->images[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%d Images. Taux de réussite: %.2f%%\n", dataset->numImages, 100*accuracy/(float)dataset->numImages);
|
||||||
|
free(dataset->images);
|
||||||
|
free(dataset->labels);
|
||||||
|
free(dataset);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void test_network(int dataset_type, char* modele, char* images_file, char* labels_file, char* data_dir, bool preview_fails) {
|
||||||
|
Network* network = read_network(modele);
|
||||||
|
|
||||||
|
if (dataset_type == 0) {
|
||||||
|
test_network_mnist(network, images_file, labels_file, preview_fails);
|
||||||
|
} else {
|
||||||
|
test_network_jpg(network, data_dir, preview_fails);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_network(network);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void recognize_mnist(Network* network, char* input_file) {
|
||||||
|
int width, height; // Dimensions de l'image
|
||||||
|
int nb_elem; // Nombre d'éléments
|
||||||
|
int maxi; // Catégorie reconnue
|
||||||
|
|
||||||
|
// Load image
|
||||||
|
int* mnist_parameters = read_mnist_images_parameters(input_file);
|
||||||
|
int*** images = read_mnist_images(input_file);
|
||||||
|
nb_elem = mnist_parameters[0];
|
||||||
|
|
||||||
|
width = mnist_parameters[1];
|
||||||
|
height = mnist_parameters[2];
|
||||||
|
free(mnist_parameters);
|
||||||
|
|
||||||
|
printf("Image\tCatégorie détectée\n");
|
||||||
|
// Load image in the first layer of the Network
|
||||||
|
for (int i=0; i < nb_elem; i++) {
|
||||||
|
write_image_in_network_32(images[i], height, width, network->input[0][0]);
|
||||||
|
forward_propagation(network);
|
||||||
|
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
||||||
|
|
||||||
|
printf("%d\t%d\n", i, maxi);
|
||||||
|
|
||||||
|
for (int j=0; j < height; j++) {
|
||||||
|
free(images[i][j]);
|
||||||
|
}
|
||||||
|
free(images[i]);
|
||||||
|
}
|
||||||
|
free(images);
|
||||||
|
}
|
||||||
|
|
||||||
|
void recognize_jpg(Network* network, char* input_file) {
|
||||||
|
int width, height; // Dimensions de l'image
|
||||||
|
int maxi;
|
||||||
|
|
||||||
|
imgRawImage* image = loadJpegImageFile(input_file);
|
||||||
|
width = image->width;
|
||||||
|
height = image->height;
|
||||||
|
|
||||||
|
write_image_in_network_260(image->lpData, height, width, network->input[0]);
|
||||||
|
forward_propagation(network);
|
||||||
|
maxi = indice_max(network->input[network->size-1][0][0], 50);
|
||||||
|
|
||||||
|
printf("Catégorie reconnue: %d\n", maxi);
|
||||||
|
free(image->lpData);
|
||||||
|
free(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void recognize(int dataset_type, char* modele, char* input_file) {
|
||||||
|
Network* network = read_network(modele);
|
||||||
|
|
||||||
|
if (dataset_type == 0) {
|
||||||
|
recognize_mnist(network, input_file);
|
||||||
|
} else {
|
||||||
|
recognize_jpg(network, input_file);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_network(network);
|
||||||
|
}
|
@ -19,18 +19,8 @@
|
|||||||
|
|
||||||
#include "include/train.h"
|
#include "include/train.h"
|
||||||
|
|
||||||
|
int div_up(int a, int b) { // Partie entière supérieure de a/b
|
||||||
int indice_max(float* tab, int n) {
|
return ((a % b) != 0) ? (a / b + 1) : (a / b);
|
||||||
int indice = -1;
|
|
||||||
float maxi = FLT_MIN;
|
|
||||||
|
|
||||||
for (int i=0; i < n; i++) {
|
|
||||||
if (tab[i] > maxi) {
|
|
||||||
maxi = tab[i];
|
|
||||||
indice = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return indice;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -91,7 +81,9 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
float accuracy;
|
float accuracy;
|
||||||
float current_accuracy;
|
float current_accuracy;
|
||||||
|
|
||||||
int nb_images_total;
|
int nb_images_total; // Images au total
|
||||||
|
int nb_images_total_remaining; // Images restantes dans un batch
|
||||||
|
int batches_epoques; // Batches par époque
|
||||||
|
|
||||||
int*** images;
|
int*** images;
|
||||||
unsigned int* labels;
|
unsigned int* labels;
|
||||||
@ -180,9 +172,17 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
// du multi-threading car chaque copie du réseau initiale sera légèrement différente
|
// du multi-threading car chaque copie du réseau initiale sera légèrement différente
|
||||||
// et donnera donc des résultats différents sur les mêmes images.
|
// et donnera donc des résultats différents sur les mêmes images.
|
||||||
accuracy = 0.;
|
accuracy = 0.;
|
||||||
for (int j=0; j < nb_images_total / BATCHES; j++) {
|
batches_epoques = div_up(nb_images_total, BATCHES);
|
||||||
|
nb_images_total_remaining = nb_images_total;
|
||||||
|
for (int j=0; j < batches_epoques; j++) {
|
||||||
#ifdef USE_MULTITHREADING
|
#ifdef USE_MULTITHREADING
|
||||||
|
if (j == batches_epoques-1) {
|
||||||
|
nb_remaining_images = nb_images_total_remaining;
|
||||||
|
nb_images_total_remaining = 0;
|
||||||
|
} else {
|
||||||
|
nb_images_total_remaining -= BATCHES;
|
||||||
nb_remaining_images = BATCHES;
|
nb_remaining_images = BATCHES;
|
||||||
|
}
|
||||||
|
|
||||||
for (int k=0; k < nb_threads; k++) {
|
for (int k=0; k < nb_threads; k++) {
|
||||||
if (k == nb_threads-1) {
|
if (k == nb_threads-1) {
|
||||||
@ -191,8 +191,9 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
} else {
|
} else {
|
||||||
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]->network = copy_network(network);
|
train_parameters[k]->network = copy_network(network);
|
||||||
train_parameters[k]->start = BATCHES*j + (nb_images_total/BATCHES)*k;
|
|
||||||
pthread_create( &tid[k], NULL, train_thread, (void*) train_parameters[k]);
|
pthread_create( &tid[k], NULL, train_thread, (void*) train_parameters[k]);
|
||||||
}
|
}
|
||||||
for (int k=0; k < nb_threads; k++) {
|
for (int k=0; k < nb_threads; k++) {
|
||||||
@ -206,6 +207,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
}
|
}
|
||||||
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.1f%%"RESET" ", nb_threads, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100);
|
||||||
|
fflush(stdout);
|
||||||
#else
|
#else
|
||||||
train_params->start = j*BATCHES;
|
train_params->start = j*BATCHES;
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
#include "neural_network.h"
|
||||||
|
|
||||||
#ifndef DEF_MAIN_H
|
#ifndef DEF_MAIN_H
|
||||||
#define DEF_MAIN_H
|
#define DEF_MAIN_H
|
||||||
|
|
||||||
@ -49,6 +51,16 @@ void* train_thread(void* parameters);
|
|||||||
*/
|
*/
|
||||||
void train(int epochs, int layers, int neurons, char* recovery, char* image_file, char* label_file, char* out, char* delta, int nb_images_to_process, int start);
|
void train(int epochs, int layers, int neurons, char* recovery, char* image_file, char* label_file, char* out, char* delta, int nb_images_to_process, int start);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Échange deux éléments d'un tableau
|
||||||
|
*/
|
||||||
|
void swap(int* tab, int i, int j);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Mélange un tableau avec le mélange de Knuth
|
||||||
|
*/
|
||||||
|
void knuth_shuffle(int* tab, int n);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Reconnaissance d'un set d'images, renvoie un tableau de float contentant les prédictions
|
* Reconnaissance d'un set d'images, renvoie un tableau de float contentant les prédictions
|
||||||
* modele: nom du fichier contenant le réseau neuronal
|
* modele: nom du fichier contenant le réseau neuronal
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#include <sys/sysinfo.h>
|
#include <sys/sysinfo.h>
|
||||||
|
|
||||||
|
#include "include/main.h"
|
||||||
#include "include/mnist.h"
|
#include "include/mnist.h"
|
||||||
#include "include/neuron_io.h"
|
#include "include/neuron_io.h"
|
||||||
#include "include/neural_network.h"
|
#include "include/neural_network.h"
|
||||||
@ -20,6 +21,7 @@ typedef struct TrainParameters {
|
|||||||
Network* network;
|
Network* network;
|
||||||
int*** images;
|
int*** images;
|
||||||
int* labels;
|
int* labels;
|
||||||
|
int* shuffle_indices;
|
||||||
int start;
|
int start;
|
||||||
int nb_images;
|
int nb_images;
|
||||||
int height;
|
int height;
|
||||||
@ -97,6 +99,7 @@ void* train_thread(void* parameters) {
|
|||||||
|
|
||||||
int*** images = param->images;
|
int*** images = param->images;
|
||||||
int* labels = param->labels;
|
int* labels = param->labels;
|
||||||
|
int* shuffle = param->shuffle_indices;
|
||||||
|
|
||||||
int start = param->start;
|
int start = param->start;
|
||||||
int nb_images = param->nb_images;
|
int nb_images = param->nb_images;
|
||||||
@ -107,15 +110,15 @@ void* train_thread(void* parameters) {
|
|||||||
int* desired_output;
|
int* desired_output;
|
||||||
|
|
||||||
for (int i=start; i < start+nb_images; i++) {
|
for (int i=start; i < start+nb_images; i++) {
|
||||||
write_image_in_network(images[i], network, height, width);
|
write_image_in_network(images[shuffle[i]], network, height, width);
|
||||||
desired_output = desired_output_creation(network, labels[i]);
|
desired_output = desired_output_creation(network, labels[shuffle[i]]);
|
||||||
forward_propagation(network);
|
forward_propagation(network);
|
||||||
backward_propagation(network, desired_output);
|
backward_propagation(network, desired_output);
|
||||||
|
|
||||||
for (int k=0; k < nb_neurons_last_layer; k++) {
|
for (int k=0; k < nb_neurons_last_layer; k++) {
|
||||||
sortie[k] = last_layer->neurons[k]->z;
|
sortie[k] = last_layer->neurons[k]->z;
|
||||||
}
|
}
|
||||||
if (indice_max(sortie, nb_neurons_last_layer) == labels[i]) {
|
if (indice_max(sortie, nb_neurons_last_layer) == labels[shuffle[i]]) {
|
||||||
accuracy += 1.;
|
accuracy += 1.;
|
||||||
}
|
}
|
||||||
free(desired_output);
|
free(desired_output);
|
||||||
@ -134,7 +137,7 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
|
|
||||||
//int* repartition = malloc(sizeof(int)*layers);
|
//int* repartition = malloc(sizeof(int)*layers);
|
||||||
int nb_neurons_last_layer = 10;
|
int nb_neurons_last_layer = 10;
|
||||||
int repartition[2] = {neurons, nb_neurons_last_layer};
|
int repartition[3] = {neurons, 42, nb_neurons_last_layer};
|
||||||
|
|
||||||
float accuracy;
|
float accuracy;
|
||||||
|
|
||||||
@ -179,6 +182,11 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
int*** images = read_mnist_images(image_file);
|
int*** images = read_mnist_images(image_file);
|
||||||
unsigned int* labels = read_mnist_labels(label_file);
|
unsigned int* labels = read_mnist_labels(label_file);
|
||||||
|
|
||||||
|
int* shuffle_indices = (int*)malloc(sizeof(int)*nb_images_total);
|
||||||
|
for (int i=0; i < nb_images_total; i++) {
|
||||||
|
shuffle_indices[i] = i;
|
||||||
|
}
|
||||||
|
|
||||||
if (nb_images_to_process != -1) {
|
if (nb_images_to_process != -1) {
|
||||||
nb_images_total = nb_images_to_process;
|
nb_images_total = nb_images_to_process;
|
||||||
}
|
}
|
||||||
@ -191,9 +199,11 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
train_parameters[j]->height = height;
|
train_parameters[j]->height = height;
|
||||||
train_parameters[j]->width = width;
|
train_parameters[j]->width = width;
|
||||||
train_parameters[j]->nb_images = BATCHES / nb_threads;
|
train_parameters[j]->nb_images = BATCHES / nb_threads;
|
||||||
|
train_parameters[j]->shuffle_indices = shuffle_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i=0; i < epochs; i++) {
|
for (int i=0; i < epochs; i++) {
|
||||||
|
knuth_shuffle(shuffle_indices, nb_images_total); // Shuffle images between each epoch
|
||||||
accuracy = 0.;
|
accuracy = 0.;
|
||||||
for (int k=0; k < nb_images_total / BATCHES; k++) {
|
for (int k=0; k < nb_images_total / BATCHES; k++) {
|
||||||
nb_remaining_images = BATCHES;
|
nb_remaining_images = BATCHES;
|
||||||
@ -220,6 +230,7 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
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);
|
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);
|
||||||
|
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: %0.1f%%\n", nb_threads, i, epochs, nb_images_total, nb_images_total, accuracy*100);
|
||||||
write_network(out, network);
|
write_network(out, network);
|
||||||
@ -239,6 +250,18 @@ void train(int epochs, int layers, int neurons, char* recovery, char* image_file
|
|||||||
free(tid);
|
free(tid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void swap(int* tab, int i, int j) {
|
||||||
|
int tmp = tab[i];
|
||||||
|
tab[i] = tab[j];
|
||||||
|
tab[j] = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void knuth_shuffle(int* tab, int n) {
|
||||||
|
for(int i=1; i < n; i++) {
|
||||||
|
swap(tab, i, rand() %i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
float** recognize(char* modele, char* entree) {
|
float** recognize(char* modele, char* entree) {
|
||||||
Network* network = read_network(modele);
|
Network* network = read_network(modele);
|
||||||
Layer* last_layer = network->layers[network->nb_layers-1];
|
Layer* last_layer = network->layers[network->nb_layers-1];
|
||||||
@ -351,7 +374,7 @@ int main(int argc, char* argv[]) {
|
|||||||
}
|
}
|
||||||
if (! strcmp(argv[1], "train")) {
|
if (! strcmp(argv[1], "train")) {
|
||||||
int epochs = EPOCHS;
|
int epochs = EPOCHS;
|
||||||
int layers = 2;
|
int layers = 3;
|
||||||
int neurons = 784;
|
int neurons = 784;
|
||||||
int nb_images = -1;
|
int nb_images = -1;
|
||||||
int start = 0;
|
int start = 0;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
// Définit le taux d'apprentissage du réseau neuronal, donc la rapidité d'adaptation du modèle (compris entre 0 et 1)
|
// Définit le taux d'apprentissage du réseau neuronal, donc la rapidité d'adaptation du modèle (compris entre 0 et 1)
|
||||||
// Cette valeur peut évoluer au fur et à mesure des époques (linéaire c'est mieux)
|
// Cette valeur peut évoluer au fur et à mesure des époques (linéaire c'est mieux)
|
||||||
#define LEARNING_RATE 0.5
|
#define LEARNING_RATE 0.1
|
||||||
// Retourne un nombre aléatoire entre 0 et 1
|
// Retourne un nombre aléatoire entre 0 et 1
|
||||||
#define RAND_DOUBLE() ((double)rand())/((double)RAND_MAX)
|
#define RAND_DOUBLE() ((double)rand())/((double)RAND_MAX)
|
||||||
//Coefficient leaking ReLU
|
//Coefficient leaking ReLU
|
||||||
|
Loading…
Reference in New Issue
Block a user