Add restore backup option

This commit is contained in:
augustin64 2022-04-08 15:53:29 +02:00
parent 261f4d9df0
commit c3d07ad638
3 changed files with 83 additions and 15 deletions

View File

@ -2,22 +2,82 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include "neural_network.c"
#include "neuron_io.c"
#include "mnist.c"
void help(char* call) { void help(char* call) {
printf("Usage: %s ( train | recognize ) [OPTIONS]\n\n", call); printf("Usage: %s ( train | recognize ) [OPTIONS]\n\n", call);
printf("OPTIONS:\n"); printf("OPTIONS:\n");
printf("\ttrain:\n"); printf("\ttrain:\n");
printf("\t\t--batches | -b [int]\tNombre de batches\n"); printf("\t\t--batches | -b [int]\tNombre de batches.\n");
printf("\t\t--couches | -c [int]\tNombres de couches\n"); printf("\t\t--couches | -c [int]\tNombres de couches.\n");
printf("\t\t--neurons | -n [int]\tNombre de neurones sur la première couche\n"); printf("\t\t--neurons | -n [int]\tNombre de neurones sur la première couche.\n");
printf("\t\t--images | -i [FILENAME]\tFichier contenant les images\n"); printf("\t\t--recover | -r [FILENAME]\tRécupérer depuis un modèle existant.\n");
printf("\t\t--labels | -l [FILENAME]\tFichier contenant les labels\n"); printf("\t\t--images | -i [FILENAME]\tFichier contenant les images.\n");
printf("\t\t--out | -o [FILENAME]\tFichier où écrire le réseau de neurones\n"); printf("\t\t--labels | -l [FILENAME]\tFichier contenant les labels.\n");
printf("\t\t--out | -o [FILENAME]\tFichier où écrire le réseau de neurones.\n");
printf("\trecognize:\n"); printf("\trecognize:\n");
printf("\t\t--modele | -m [FILENAME]\tFichier contenant le réseau de neurones\n"); printf("\t\t--modele | -m [FILENAME]\tFichier contenant le réseau de neurones.\n");
printf("\t\t--in | -i [FILENAME]\tFichier contenant les images à reconnaître\n"); printf("\t\t--in | -i [FILENAME]\tFichier contenant les images à reconnaître.\n");
printf("\t\t--out | -o (text|json)\tFormat de sortie\n"); printf("\t\t--out | -o (text|json)\tFormat de sortie.\n");
} }
void ecrire_image_dans_reseau(int** image, Reseau* reseau, int height, int width) {
for (int i=0; i < height; i++) {
for (int j=0; j < width; j++) {
reseau->couches[0]->neurones[i*height+j]->activation = (float)image[i][j] / 255.0;
}
}
}
void train(int batches, int couches, int neurons, char* recovery, char* image_file, char* label_file, char* out) {
Reseau* reseau;
//int* repartition = malloc(sizeof(int)*couches);
int* sortie_voulue;
int repartition[5] = {784, 100, 75, 40, 10};
//generer_repartition(couches, repartition);
/*
* On repart d'un réseau déjà créée stocké dans un fichier
* ou on repart de zéro si aucune backup n'est fournie
* */
if (! recovery) {
reseau = malloc(sizeof(Reseau));
creation_du_reseau_neuronal(reseau, repartition, couches);
} else {
reseau = lire_reseau(recovery);
printf("Backup restorée.\n");
}
// Chargement des images du set de données MNIST
int* parameters = read_mnist_images_parameters(image_file);
int nb_images = parameters[0];
int height = parameters[1];
int width = parameters[2];
int*** images = read_mnist_images(image_file);
unsigned int* labels = read_mnist_labels(label_file);
for (int i=0; i < batches; i++) {
printf("Batch [%d/%d]\n", i, batches);
for (int j=0; j < nb_images; j++) {
printf("\rImage [%d/%d]", j, nb_images);
ecrire_image_dans_reseau(images[j], reseau, height, width);
sortie_voulue = creation_de_la_sortie_voulue(reseau, labels[j]);
forward_propagation(reseau);
backward_propagation(reseau, sortie_voulue);
}
printf("\n");
ecrire_reseau(out, reseau);
}
}
int main(int argc, char* argv[]) { int main(int argc, char* argv[]) {
if (argc < 2) { if (argc < 2) {
printf("Pas d'action spécifiée\n"); printf("Pas d'action spécifiée\n");
@ -30,6 +90,7 @@ int main(int argc, char* argv[]) {
int neurons = 784; int neurons = 784;
char* images = NULL; char* images = NULL;
char* labels = NULL; char* labels = NULL;
char* recovery = NULL;
char* out = NULL; char* out = NULL;
int i=2; int i=2;
while (i < argc) { while (i < argc) {
@ -50,6 +111,9 @@ int main(int argc, char* argv[]) {
} else if ((! strcmp(argv[i], "--labels"))||(! strcmp(argv[i], "-l"))) { } else if ((! strcmp(argv[i], "--labels"))||(! strcmp(argv[i], "-l"))) {
labels = argv[i+1]; labels = argv[i+1];
i += 2; i += 2;
} else if ((! strcmp(argv[i], "--recover"))||(! strcmp(argv[i], "-r"))) {
recovery = argv[i+1];
i += 2;
} else if ((! strcmp(argv[i], "--out"))||(! strcmp(argv[i], "-o"))) { } else if ((! strcmp(argv[i], "--out"))||(! strcmp(argv[i], "-o"))) {
out = argv[i+1]; out = argv[i+1];
i += 2; i += 2;
@ -71,6 +135,7 @@ int main(int argc, char* argv[]) {
out = "out.bin"; out = "out.bin";
} }
// Entraînement en sourçant neural_network.c // Entraînement en sourçant neural_network.c
train(batches, couches, neurons, recovery, images, labels, out);
exit(0); exit(0);
} }
if (! strcmp(argv[1], "recognize")) { if (! strcmp(argv[1], "recognize")) {

View File

@ -100,11 +100,14 @@ int* creation_de_la_sortie_voulue(Reseau* reseau_neuronal, int pos_nombre_voulu)
/* Renvoie la liste des sorties voulues à partir du nombre /* Renvoie la liste des sorties voulues à partir du nombre
de couches, de la liste du nombre de neurones par couche et de la de couches, de la liste du nombre de neurones par couche et de la
position du résultat voulue, */ position du résultat voulue, */
int nb_neurones = reseau_neuronal->couches[reseau_neuronal->nb_couches-1]->nb_neurones;
int* sortie_voulue = (int*)malloc(sizeof(int)); int* sortie_voulue = (int*)malloc(sizeof(int)*nb_neurones);
for (int i=0; i<reseau_neuronal->couches[reseau_neuronal->nb_couches-1]->nb_neurones; i++) // On initialise toutes les sorties à 0 par défault
sortie_voulue[i]=0; for (int i=0; i < nb_neurones; i++) // On initialise toutes les sorties à 0 par défault
sortie_voulue[pos_nombre_voulu]=1; // Seule la sortie voulue vaut 1 sortie_voulue[i] = 0;
sortie_voulue[pos_nombre_voulu] = 1; // Seule la sortie voulue vaut 1
return sortie_voulue; return sortie_voulue;
} }

View File

@ -60,7 +60,6 @@ Reseau* lire_reseau(char* filename) {
uint32_t magic_number; uint32_t magic_number;
uint32_t nb_couches; uint32_t nb_couches;
uint32_t tmp; uint32_t tmp;
reseau->nb_couches = nb_couches;
fread(&magic_number, sizeof(uint32_t), 1, ptr); fread(&magic_number, sizeof(uint32_t), 1, ptr);
if (magic_number != MAGIC_NUMBER) { if (magic_number != MAGIC_NUMBER) {
@ -69,6 +68,7 @@ Reseau* lire_reseau(char* filename) {
} }
fread(&nb_couches, sizeof(uint32_t), 1, ptr); fread(&nb_couches, sizeof(uint32_t), 1, ptr);
reseau->nb_couches = nb_couches;
Couche** couches = malloc(sizeof(Couche*)*nb_couches); Couche** couches = malloc(sizeof(Couche*)*nb_couches);
@ -77,7 +77,7 @@ Reseau* lire_reseau(char* filename) {
reseau->couches = couches; reseau->couches = couches;
for (int i=0; i < nb_couches; i++) { for (int i=0; i < nb_couches; i++) {
couches[i] = malloc(sizeof(int)+sizeof(Neurone**)); couches[i] = malloc(sizeof(Couche));
fread(&tmp, sizeof(tmp), 1, ptr); fread(&tmp, sizeof(tmp), 1, ptr);
couches[i]->nb_neurones = tmp; couches[i]->nb_neurones = tmp;
nb_neurones_couche[i] = tmp; nb_neurones_couche[i] = tmp;