2022-04-19 13:55:08 +02:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
2022-09-30 15:44:28 +02:00
|
|
|
#include "include/neural_network.h"
|
|
|
|
#include "include/neuron_io.h"
|
|
|
|
#include "include/mnist.h"
|
2022-04-19 13:55:08 +02:00
|
|
|
|
2022-04-19 21:30:23 +02:00
|
|
|
/*
|
|
|
|
Contient un ensemble de fonctions utiles pour le débogage
|
|
|
|
*/
|
|
|
|
void help(char* call) {
|
2022-05-21 18:06:39 +02:00
|
|
|
printf("Usage: %s ( print-poids | print-biais | creer-reseau | patch-network ) [OPTIONS]\n\n", call);
|
2022-04-19 21:30:23 +02:00
|
|
|
printf("OPTIONS:\n");
|
|
|
|
printf("\tprint-poids:\n");
|
2022-04-30 09:31:52 +02:00
|
|
|
printf("\t\t--reseau | -r [FILENAME]\tFichier contenant le réseau de neurones.\n");
|
|
|
|
printf("\tprint-biais:\n");
|
|
|
|
printf("\t\t--reseau | -r [FILENAME]\tFichier contenant le réseau de neurones.\n");
|
2022-04-22 15:03:21 +02:00
|
|
|
printf("\tcount-labels:\n");
|
|
|
|
printf("\t\t--labels | -l [FILENAME]\tFichier contenant les labels.\n");
|
2022-04-30 09:31:52 +02:00
|
|
|
printf("\tcreer-reseau:\n");
|
|
|
|
printf("\t\t--out | -o [FILENAME]\tFichier où écrire le réseau de neurones.\n");
|
2022-05-21 18:06:39 +02:00
|
|
|
printf("\t\t--number | -n [int]\tNuméro à privilégier.\n");
|
|
|
|
printf("\tpatch-network:\n");
|
|
|
|
printf("\t\t--network | -n [FILENAME]\tFichier contenant le réseau de neurones.\n");
|
|
|
|
printf("\t\t--delta | -d [FILENAME]\tFichier de patch à utiliser.\n");
|
2022-07-01 16:16:55 +02:00
|
|
|
printf("\tprint-images:\n");
|
|
|
|
printf("\t\t--images | -i [FILENAME]\tFichier contenant les images.\n");
|
2022-07-02 10:56:06 +02:00
|
|
|
printf("\tprint-poids-neurone:\n");
|
|
|
|
printf("\t\t--reseau | -r [FILENAME]\tFichier contenant le réseau de neurones.\n");
|
|
|
|
printf("\t\t--neurone | -n [int]\tNuméro du neurone dont il faut afficher les poids.\n");
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-04-25 14:39:45 +02:00
|
|
|
void print_bias(char* filename) {
|
2022-05-03 09:44:40 +02:00
|
|
|
Network* network = read_network(filename);
|
2022-04-19 13:55:08 +02:00
|
|
|
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int i=1; i < network->nb_layers -1; i++) {
|
2022-04-30 09:31:52 +02:00
|
|
|
printf("Couche %d\n", i);
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int j=0; j < network->layers[i]->nb_neurons; j++) {
|
2022-04-30 09:31:52 +02:00
|
|
|
printf("Couche %d\tNeurone %d\tBiais: %f\n", i, j, network->layers[i]->neurons[j]->bias);
|
2022-04-19 13:55:08 +02:00
|
|
|
}
|
|
|
|
}
|
2022-04-25 14:39:45 +02:00
|
|
|
deletion_of_network(network);
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
|
|
|
|
2022-05-10 21:04:48 +02:00
|
|
|
void print_weights(char* filename) {
|
2022-05-03 09:44:40 +02:00
|
|
|
Network* network = read_network(filename);
|
2022-04-25 14:39:45 +02:00
|
|
|
|
|
|
|
for (int i=0; i < network->nb_layers -1; i++) {
|
2022-04-30 09:31:52 +02:00
|
|
|
printf("Couche %d\n", i);
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int j=0; j < network->layers[i]->nb_neurons; j++) {
|
2022-04-30 09:31:52 +02:00
|
|
|
printf("Couche %d\tNeurone %d\tPoids: [", i, j);
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int k=0; k < network->layers[i+1]->nb_neurons; k++) {
|
|
|
|
printf("%f, ", network->layers[i]->neurons[j]->weights[k]);
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
|
|
|
printf("]\n");
|
|
|
|
}
|
|
|
|
}
|
2022-04-25 14:39:45 +02:00
|
|
|
deletion_of_network(network);
|
2022-04-19 13:55:08 +02:00
|
|
|
}
|
|
|
|
|
2022-04-22 15:03:21 +02:00
|
|
|
void count_labels(char* filename) {
|
|
|
|
uint32_t number_of_images = read_mnist_labels_nb_images(filename);
|
|
|
|
|
2022-05-14 14:46:48 +02:00
|
|
|
unsigned int* labels = (unsigned int*)malloc(sizeof(unsigned int)*number_of_images);
|
2022-04-22 15:03:21 +02:00
|
|
|
labels = read_mnist_labels(filename);
|
|
|
|
|
2022-05-14 14:46:48 +02:00
|
|
|
unsigned int tab[10];
|
2022-04-22 15:03:21 +02:00
|
|
|
|
|
|
|
for (int i=0; i < 10; i++) {
|
|
|
|
tab[i] = 0;
|
|
|
|
}
|
|
|
|
|
2022-05-14 14:46:48 +02:00
|
|
|
for (int i=0; i < (int)number_of_images; i++) {
|
2022-04-22 15:03:21 +02:00
|
|
|
tab[(int)labels[i]]++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i=0; i < 10; i++) {
|
2022-11-08 19:56:58 +01:00
|
|
|
printf("Nombre de %d: %u\n", i, tab[i]);
|
2022-04-22 15:03:21 +02:00
|
|
|
}
|
2022-05-23 17:27:38 +02:00
|
|
|
free(labels);
|
2022-04-22 15:03:21 +02:00
|
|
|
}
|
|
|
|
|
2022-04-25 14:39:45 +02:00
|
|
|
void create_network(char* filename, int sortie) {
|
2022-05-14 14:46:48 +02:00
|
|
|
Network* network = (Network*)malloc(sizeof(Network));
|
2022-04-25 14:39:45 +02:00
|
|
|
Layer* layer;
|
|
|
|
Neuron* neuron;
|
|
|
|
network->nb_layers = 3;
|
2022-04-19 21:30:23 +02:00
|
|
|
|
2022-05-14 14:46:48 +02:00
|
|
|
network->layers = (Layer**)malloc(sizeof(Layer*)*network->nb_layers);
|
2022-04-25 14:39:45 +02:00
|
|
|
int neurons_per_layer[4] = {784, 1, 10, 0};
|
|
|
|
for (int i=0; i < network->nb_layers; i++) {
|
2022-05-14 14:46:48 +02:00
|
|
|
layer = (Layer*)malloc(sizeof(Layer));
|
2022-04-25 14:39:45 +02:00
|
|
|
layer->nb_neurons = neurons_per_layer[i];
|
2022-05-14 14:46:48 +02:00
|
|
|
layer->neurons = (Neuron**)malloc(sizeof(Neuron*)*layer->nb_neurons);
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int j=0; j < layer->nb_neurons; j++) {
|
2022-05-14 14:46:48 +02:00
|
|
|
neuron = (Neuron*)malloc(sizeof(Neuron));
|
2022-04-25 14:39:45 +02:00
|
|
|
|
|
|
|
neuron->bias = 0.;
|
|
|
|
neuron->z = 0.;
|
|
|
|
|
|
|
|
neuron->back_bias = 0.;
|
|
|
|
neuron->last_back_bias = 0.;
|
2022-05-14 14:46:48 +02:00
|
|
|
neuron->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]);
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int k=0; k < neurons_per_layer[i+1]; k++) {
|
|
|
|
neuron->weights[k] = 0.;
|
|
|
|
neuron->back_weights[k] = 0.;
|
|
|
|
neuron->last_back_weights[k] = 0.;
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-05-14 14:46:48 +02:00
|
|
|
layer->neurons[j] = neuron;
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-05-14 14:46:48 +02:00
|
|
|
network->layers[i] = layer;
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-04-25 14:39:45 +02:00
|
|
|
for (int j=0; j < neurons_per_layer[0]; j++) {
|
|
|
|
network->layers[0]->neurons[j]->weights[0] = 1;
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-04-25 14:39:45 +02:00
|
|
|
network->layers[1]->neurons[0]->weights[sortie] = 1;
|
|
|
|
write_network(filename, network);
|
|
|
|
deletion_of_network(network);
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-05-21 18:06:39 +02:00
|
|
|
void patch_stored_network(char* network_filename, char* delta_filename) {
|
|
|
|
// Apply patch to a network stored in a file
|
|
|
|
Network* network = read_network(network_filename);
|
|
|
|
Network* delta = read_delta_network(delta_filename);
|
|
|
|
|
|
|
|
patch_network(network, delta, 1);
|
|
|
|
|
|
|
|
write_network(network_filename, network);
|
|
|
|
deletion_of_network(network);
|
|
|
|
deletion_of_network(delta);
|
|
|
|
}
|
|
|
|
|
2022-04-19 21:30:23 +02:00
|
|
|
|
2022-07-01 16:16:55 +02:00
|
|
|
void print_images(char* filename) {
|
|
|
|
int* parameters = read_mnist_images_parameters(filename);
|
|
|
|
|
|
|
|
int nb_elem = parameters[0];
|
|
|
|
int width = parameters[1];
|
|
|
|
int height = parameters[2];
|
|
|
|
free(parameters);
|
|
|
|
|
|
|
|
int*** images = read_mnist_images(filename);
|
|
|
|
|
|
|
|
printf("[\n");
|
|
|
|
for (int i=0; i < nb_elem; i++) {
|
|
|
|
printf("\t[\n");
|
|
|
|
for (int j=0; j < height; j++) {
|
|
|
|
printf("\t\t[");
|
|
|
|
for (int k=0; k < width; k++) {
|
|
|
|
if (k != width -1)
|
|
|
|
printf("%d, ", images[i][j][k]);
|
|
|
|
else
|
|
|
|
printf("%d", images[i][j][k]);
|
|
|
|
}
|
|
|
|
if (j != height -1)
|
|
|
|
printf("],\n");
|
|
|
|
else
|
|
|
|
printf("]\n");
|
|
|
|
free(images[i][j]);
|
|
|
|
}
|
|
|
|
if (i != nb_elem -1)
|
|
|
|
printf("\t],\n");
|
|
|
|
else
|
|
|
|
printf("\t]\n");
|
|
|
|
free(images[i]);
|
|
|
|
}
|
|
|
|
free(images);
|
|
|
|
printf("]\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-07-02 10:56:06 +02:00
|
|
|
void print_poids_neurone(char* filename, int num_neurone) {
|
|
|
|
Network* network = read_network(filename);
|
|
|
|
int nb_layers = network->nb_layers;
|
|
|
|
|
|
|
|
Layer* layer = network->layers[nb_layers-2];
|
|
|
|
int nb_neurons = layer->nb_neurons;
|
|
|
|
printf("[\n");
|
|
|
|
for (int i=0; i < nb_neurons; i++) {
|
|
|
|
printf("%f", layer->neurons[i]->weights[num_neurone]);
|
|
|
|
if (i != nb_neurons -1)
|
|
|
|
printf(", ");
|
|
|
|
else
|
|
|
|
printf("\n");
|
|
|
|
}
|
|
|
|
printf("]\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-04-19 16:26:28 +02:00
|
|
|
int main(int argc, char* argv[]) {
|
2022-04-19 21:30:23 +02:00
|
|
|
if (argc < 2) {
|
|
|
|
printf("Pas d'action spécifiée\n");
|
|
|
|
help(argv[0]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (! strcmp(argv[1], "print-poids")) {
|
|
|
|
char* filename = NULL;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
2022-04-30 09:31:52 +02:00
|
|
|
if ((! strcmp(argv[i], "--reseau"))||(! strcmp(argv[i], "-r"))) {
|
2022-04-19 21:30:23 +02:00
|
|
|
filename = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (! filename) {
|
2022-05-03 09:44:40 +02:00
|
|
|
printf("Pas de fichier spécifié, utilisation de '.cache/reseau.bin'\n");
|
|
|
|
filename = ".cache/reseau.bin";
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-05-10 21:04:48 +02:00
|
|
|
print_weights(filename);
|
2022-05-16 17:26:04 +02:00
|
|
|
exit(0);
|
2022-04-30 09:31:52 +02:00
|
|
|
} else if (! strcmp(argv[1], "print-biais")) {
|
2022-04-19 21:30:23 +02:00
|
|
|
char* filename = NULL;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
2022-04-30 09:31:52 +02:00
|
|
|
if ((! strcmp(argv[i], "--reseau"))||(! strcmp(argv[i], "-r"))) {
|
2022-04-19 21:30:23 +02:00
|
|
|
filename = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (! filename) {
|
2022-05-03 09:44:40 +02:00
|
|
|
printf("Pas de fichier spécifié, utilisation de '.cache/reseau.bin'\n");
|
|
|
|
filename = ".cache/reseau.bin";
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-04-25 14:39:45 +02:00
|
|
|
print_bias(filename);
|
2022-05-16 17:26:04 +02:00
|
|
|
exit(0);
|
2022-04-30 09:31:52 +02:00
|
|
|
} else if (! strcmp(argv[1], "creer-reseau")) {
|
2022-04-19 21:30:23 +02:00
|
|
|
char* out = NULL;
|
|
|
|
int n = -1;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
|
|
|
if ((! strcmp(argv[i], "--out"))||(! strcmp(argv[i], "-o"))) {
|
|
|
|
out = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else if ((! strcmp(argv[i], "--number"))||(! strcmp(argv[i], "-n"))) {
|
|
|
|
n = strtol(argv[i+1], NULL, 10);
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
2022-05-14 14:46:48 +02:00
|
|
|
create_network(out, n);
|
2022-05-16 17:26:04 +02:00
|
|
|
exit(0);
|
2022-04-22 15:03:21 +02:00
|
|
|
} else if (! strcmp(argv[1], "count-labels")) {
|
|
|
|
char* labels = NULL;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
|
|
|
if ((! strcmp(argv[i], "--labels"))||(! strcmp(argv[i], "-l"))) {
|
|
|
|
labels = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-04-22 15:03:21 +02:00
|
|
|
if (! labels) {
|
|
|
|
printf("Pas de fichier spécifié, défaut: 'data/mnist/train-labels-idx1-ubyte'\n");
|
|
|
|
labels = "data/mnist/train-labels-idx1-ubyte";
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
2022-04-22 15:03:21 +02:00
|
|
|
count_labels(labels);
|
2022-05-16 17:26:04 +02:00
|
|
|
exit(0);
|
2022-07-01 16:16:55 +02:00
|
|
|
} else if (! strcmp(argv[1], "patch-network")) {
|
2022-05-21 18:06:39 +02:00
|
|
|
char* network = NULL;
|
|
|
|
char* delta = NULL;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
|
|
|
if ((! strcmp(argv[i], "--network"))||(! strcmp(argv[i], "-n"))) {
|
|
|
|
network = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else if ((! strcmp(argv[i], "--delta"))||(! strcmp(argv[i], "-d"))) {
|
|
|
|
delta = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!network) {
|
|
|
|
printf("--network: Argument obligatoire.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
if (!delta) {
|
|
|
|
printf("--delta: Argument obligatoire.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
patch_stored_network(network, delta);
|
|
|
|
exit(0);
|
2022-07-01 16:16:55 +02:00
|
|
|
} else if (! strcmp(argv[1], "print-images")) {
|
|
|
|
char* images = NULL;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
|
|
|
if ((! strcmp(argv[i], "--images"))||(! strcmp(argv[i], "-i"))) {
|
|
|
|
images = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!images) {
|
|
|
|
printf("--images: Argument obligatoire.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
print_images(images);
|
|
|
|
exit(0);
|
2022-07-02 10:56:06 +02:00
|
|
|
} else if (! strcmp(argv[1], "print-poids-neurone")) {
|
|
|
|
char* reseau = NULL;
|
|
|
|
int neurone = 0;
|
|
|
|
int i = 2;
|
|
|
|
while (i < argc) {
|
|
|
|
if ((! strcmp(argv[i], "--reseau"))||(! strcmp(argv[i], "-r"))) {
|
|
|
|
reseau = argv[i+1];
|
|
|
|
i += 2;
|
|
|
|
} else if ((! strcmp(argv[i], "--neurone"))||(! strcmp(argv[i], "-n"))) {
|
|
|
|
neurone = strtol(argv[i+1], NULL, 10);
|
|
|
|
i += 2;
|
|
|
|
} else {
|
|
|
|
printf("%s : Argument non reconnu\n", argv[i]);
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!reseau) {
|
|
|
|
printf("--reseau: Argument obligatoire.\n");
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
print_poids_neurone(reseau, neurone);
|
|
|
|
exit(0);
|
2022-04-19 21:30:23 +02:00
|
|
|
}
|
|
|
|
printf("Option choisie non reconnue: %s\n", argv[1]);
|
|
|
|
help(argv[0]);
|
2022-04-19 13:55:08 +02:00
|
|
|
return 1;
|
|
|
|
}
|