mirror of
https://github.com/augustin64/projet-tipe
synced 2025-02-02 19:39:39 +01:00
Add random offset to mnist images during learning
This commit is contained in:
parent
1bd92074ab
commit
b893f11da0
@ -1,7 +1,8 @@
|
|||||||
|
#include <stdbool.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <math.h>
|
|
||||||
#include <float.h> // Is it used ?
|
#include <float.h> // Is it used ?
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "include/backpropagation.h"
|
#include "include/backpropagation.h"
|
||||||
#include "include/initialisation.h"
|
#include "include/initialisation.h"
|
||||||
@ -33,7 +34,80 @@ int will_be_drop(int dropout_prob) {
|
|||||||
return (rand() % 100) < dropout_prob;
|
return (rand() % 100) < dropout_prob;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_image_in_network_32(int** image, int height, int width, float** input) {
|
void write_image_in_network_32(int** image, int height, int width, float** input, bool random_offset) {
|
||||||
|
int i_offset = 0;
|
||||||
|
int j_offset = 0;
|
||||||
|
int min_col = 0;
|
||||||
|
int min_ligne = 0;
|
||||||
|
|
||||||
|
if (random_offset) {
|
||||||
|
/*
|
||||||
|
<-- min_ligne
|
||||||
|
.%%:.
|
||||||
|
######%%%%%%%%%.
|
||||||
|
.:.:%##########:
|
||||||
|
. .... ##:
|
||||||
|
.##
|
||||||
|
##.
|
||||||
|
:##
|
||||||
|
.##.
|
||||||
|
:#%
|
||||||
|
%#.
|
||||||
|
:#%
|
||||||
|
.##.
|
||||||
|
##%
|
||||||
|
%##
|
||||||
|
##.
|
||||||
|
##:
|
||||||
|
:##.
|
||||||
|
.###.
|
||||||
|
:###
|
||||||
|
:#%
|
||||||
|
<-- max_ligne
|
||||||
|
^-- min_col
|
||||||
|
^-- max_col
|
||||||
|
*/
|
||||||
|
int sum_colonne[width];
|
||||||
|
int sum_ligne[height];
|
||||||
|
|
||||||
|
for (int i=0; i < width; i++) {
|
||||||
|
sum_colonne[i] = 0;
|
||||||
|
}
|
||||||
|
for (int j=0; j < height; j++) {
|
||||||
|
sum_ligne[j] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i < width; i++) {
|
||||||
|
for (int j=0; j < height; j++) {
|
||||||
|
sum_ligne[i] += image[i][j];
|
||||||
|
sum_colonne[j] += image[i][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
min_ligne = -1;
|
||||||
|
while (sum_ligne[min_ligne+1] == 0 && min_ligne < width+1) {
|
||||||
|
min_ligne++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_ligne = width;
|
||||||
|
while (sum_ligne[max_ligne-1] == 0 && max_ligne > 0) {
|
||||||
|
max_ligne--;
|
||||||
|
}
|
||||||
|
|
||||||
|
min_col = -1;
|
||||||
|
while (sum_colonne[min_col+1] == 0 && min_col < height+1) {
|
||||||
|
min_col++;
|
||||||
|
}
|
||||||
|
|
||||||
|
int max_col = height;
|
||||||
|
while (sum_colonne[max_col-1] == 0 && max_col > 0) {
|
||||||
|
max_col--;
|
||||||
|
}
|
||||||
|
|
||||||
|
i_offset = rand()%(27-max_ligne+min_ligne);
|
||||||
|
j_offset = rand()%(27-max_col+min_col);
|
||||||
|
}
|
||||||
|
|
||||||
int padding = (32 - height)/2;
|
int padding = (32 - height)/2;
|
||||||
for (int i=0; i < padding; i++) {
|
for (int i=0; i < padding; i++) {
|
||||||
for (int j=0; j < 32; j++) {
|
for (int j=0; j < 32; j++) {
|
||||||
@ -46,7 +120,10 @@ void write_image_in_network_32(int** image, int height, int width, float** input
|
|||||||
|
|
||||||
for (int i=0; i < width; i++) {
|
for (int i=0; i < width; i++) {
|
||||||
for (int j=0; j < height; j++) {
|
for (int j=0; j < height; j++) {
|
||||||
input[i+2][j+2] = (float)image[i][j] / 255.0f;
|
int adjusted_i = i + min_ligne - i_offset;
|
||||||
|
int adjusted_j = j + min_col - j_offset;
|
||||||
|
// Make sure not to be out of the image
|
||||||
|
input[i+2][j+2] = adjusted_i < height && adjusted_j < width && adjusted_i >= 0 && adjusted_j >= 0 ? (float)image[adjusted_i][adjusted_j] / 255.0f : 0.;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ int will_be_drop(int dropout_prob);
|
|||||||
/*
|
/*
|
||||||
* Écrit une image 28*28 au centre d'un tableau 32*32 et met à 0 le reste
|
* Écrit une image 28*28 au centre d'un tableau 32*32 et met à 0 le reste
|
||||||
*/
|
*/
|
||||||
void write_image_in_network_32(int** image, int height, int width, float** input);
|
void write_image_in_network_32(int** image, int height, int width, float** input, bool random_offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Écrit une image linéarisée de 256*256*3 pixels dans un tableau de taille 260*260*3
|
* Écrit une image linéarisée de 256*256*3 pixels dans un tableau de taille 260*260*3
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
/*
|
/*
|
||||||
* Renvoie le taux de réussite d'un réseau sur des données de test
|
* 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);
|
float* test_network(int dataset_type, char* modele, char* images_file, char* labels_file, char* data_dir, bool preview_fails, bool to_stdout, bool with_offset);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Classifie un fichier d'images sous le format MNIST à partir d'un réseau préalablement entraîné
|
* Classifie un fichier d'images sous le format MNIST à partir d'un réseau préalablement entraîné
|
||||||
|
@ -188,7 +188,7 @@ int main(int argc, char* argv[]) {
|
|||||||
printf_error("Pas de modèle à utiliser spécifié.\n");
|
printf_error("Pas de modèle à utiliser spécifié.\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
test_network(dataset_type, modele, images_file, labels_file, data_dir, preview_fails);
|
(void)test_network(dataset_type, modele, images_file, labels_file, data_dir, preview_fails, true, false);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (! strcmp(argv[1], "recognize")) {
|
if (! strcmp(argv[1], "recognize")) {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
#include "include/cnn.h"
|
#include "include/cnn.h"
|
||||||
|
|
||||||
|
|
||||||
void test_network_mnist(Network* network, char* images_file, char* labels_file, bool preview_fails) {
|
float* test_network_mnist(Network* network, char* images_file, char* labels_file, bool preview_fails, bool to_stdout, bool with_offset) {
|
||||||
(void)preview_fails; // Inutilisé pour le moment
|
(void)preview_fails; // Inutilisé pour le moment
|
||||||
int width, height; // Dimensions des images
|
int width, height; // Dimensions des images
|
||||||
int nb_elem; // Nombre d'éléments
|
int nb_elem; // Nombre d'éléments
|
||||||
@ -36,11 +36,11 @@ void test_network_mnist(Network* network, char* images_file, char* labels_file,
|
|||||||
|
|
||||||
// Load image in the first layer of the Network
|
// Load image in the first layer of the Network
|
||||||
for (int i=0; i < nb_elem; i++) {
|
for (int i=0; i < nb_elem; i++) {
|
||||||
if(i %(nb_elem/100) == 0) {
|
if(i %(nb_elem/100) == 0 && to_stdout) {
|
||||||
printf("Avancement: %.0f%%\r", 100*i/(float)nb_elem);
|
printf("Avancement: %.0f%%\r", 100*i/(float)nb_elem);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
write_image_in_network_32(images[i], height, width, network->input[0][0]);
|
write_image_in_network_32(images[i], height, width, network->input[0][0], with_offset);
|
||||||
forward_propagation(network);
|
forward_propagation(network);
|
||||||
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
||||||
|
|
||||||
@ -59,11 +59,15 @@ void test_network_mnist(Network* network, char* images_file, char* labels_file,
|
|||||||
free(images[i]);
|
free(images[i]);
|
||||||
}
|
}
|
||||||
free(images);
|
free(images);
|
||||||
printf("%d Images. Taux de réussite: %.2f%%\tLoss: %lf\n", nb_elem, 100*accuracy/(float)nb_elem, loss/nb_elem);
|
|
||||||
|
float* results = malloc(sizeof(float)*2);
|
||||||
|
results[0] = 100*accuracy/(float)nb_elem;
|
||||||
|
results[1] = loss/(float)nb_elem;
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_network_jpg(Network* network, char* data_dir, bool preview_fails) {
|
float* test_network_jpg(Network* network, char* data_dir, bool preview_fails, bool to_stdout) {
|
||||||
(void)preview_fails; // Inutilisé pour le moment
|
(void)preview_fails; // Inutilisé pour le moment
|
||||||
jpegDataset* dataset = loadJpegDataset(data_dir);
|
jpegDataset* dataset = loadJpegDataset(data_dir);
|
||||||
|
|
||||||
@ -71,7 +75,7 @@ void test_network_jpg(Network* network, char* data_dir, bool preview_fails) {
|
|||||||
int maxi;
|
int maxi;
|
||||||
|
|
||||||
for (int i=0; i < (int)dataset->numImages; i++) {
|
for (int i=0; i < (int)dataset->numImages; i++) {
|
||||||
if(i %(dataset->numImages/100) == 0) {
|
if(i %(dataset->numImages/100) == 0 && to_stdout) {
|
||||||
printf("Avancement: %.1f%%\r", 1000*i/(float)dataset->numImages);
|
printf("Avancement: %.1f%%\r", 1000*i/(float)dataset->numImages);
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
}
|
}
|
||||||
@ -86,23 +90,35 @@ void test_network_jpg(Network* network, char* data_dir, bool preview_fails) {
|
|||||||
free(dataset->images[i]);
|
free(dataset->images[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%d Images. Taux de réussite: %.2f%%\n", dataset->numImages, 100*accuracy/(float)dataset->numImages);
|
float* results = malloc(sizeof(float)*2);
|
||||||
|
results[0] = 100*accuracy/(float)dataset->numImages;
|
||||||
|
results[1] = 0;
|
||||||
|
|
||||||
free(dataset->images);
|
free(dataset->images);
|
||||||
free(dataset->labels);
|
free(dataset->labels);
|
||||||
free(dataset);
|
free(dataset);
|
||||||
|
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void test_network(int dataset_type, char* modele, char* images_file, char* labels_file, char* data_dir, bool preview_fails) {
|
float* test_network(int dataset_type, char* modele, char* images_file, char* labels_file, char* data_dir, bool preview_fails, bool to_stdout, bool with_offset) {
|
||||||
Network* network = read_network(modele);
|
Network* network = read_network(modele);
|
||||||
|
float* results;
|
||||||
|
|
||||||
if (dataset_type == 0) {
|
if (dataset_type == 0) {
|
||||||
test_network_mnist(network, images_file, labels_file, preview_fails);
|
results = test_network_mnist(network, images_file, labels_file, preview_fails, to_stdout, with_offset);
|
||||||
} else {
|
} else {
|
||||||
test_network_jpg(network, data_dir, preview_fails);
|
results = test_network_jpg(network, data_dir, preview_fails, to_stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
free_network(network);
|
free_network(network);
|
||||||
|
|
||||||
|
if (to_stdout) {
|
||||||
|
printf("Accuracy: %lf\tLoss: %lf\n", results[0], results[1]);
|
||||||
|
free(results); // Will not be used if to_stdout is used
|
||||||
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -130,7 +146,7 @@ void recognize_mnist(Network* network, char* input_file, char* out) {
|
|||||||
printf("\"%d\" : [", i);
|
printf("\"%d\" : [", i);
|
||||||
}
|
}
|
||||||
|
|
||||||
write_image_in_network_32(images[i], height, width, network->input[0][0]);
|
write_image_in_network_32(images[i], height, width, network->input[0][0], false);
|
||||||
forward_propagation(network);
|
forward_propagation(network);
|
||||||
|
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ void* train_thread(void* parameters) {
|
|||||||
|
|
||||||
for (int i=start; i < start+nb_images; i++) {
|
for (int i=start; i < start+nb_images; i++) {
|
||||||
if (dataset_type == 0) {
|
if (dataset_type == 0) {
|
||||||
write_image_in_network_32(images[index[i]], height, width, network->input[0][0]);
|
write_image_in_network_32(images[index[i]], height, width, network->input[0][0], true);
|
||||||
forward_propagation(network);
|
forward_propagation(network);
|
||||||
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
||||||
if (maxi == -1) {
|
if (maxi == -1) {
|
||||||
@ -106,6 +106,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
srand(time(NULL));
|
srand(time(NULL));
|
||||||
float loss;
|
float loss;
|
||||||
float batch_loss; // May be redundant with loss, but gives more informations
|
float batch_loss; // May be redundant with loss, but gives more informations
|
||||||
|
float test_accuracy = 0.; // Used to decrease Learning rate
|
||||||
float accuracy;
|
float accuracy;
|
||||||
float batch_accuracy;
|
float batch_accuracy;
|
||||||
float current_accuracy;
|
float current_accuracy;
|
||||||
@ -233,7 +234,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
end_time = omp_get_wtime();
|
end_time = omp_get_wtime();
|
||||||
|
|
||||||
elapsed_time = end_time - start_time;
|
elapsed_time = end_time - start_time;
|
||||||
printf("Taux d'apprentissage initial: %lf\n", network->learning_rate);
|
printf("Taux d'apprentissage initial: %0.2e\n", network->learning_rate);
|
||||||
printf("Initialisation: ");
|
printf("Initialisation: ");
|
||||||
printf_time(elapsed_time);
|
printf_time(elapsed_time);
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
@ -308,7 +309,6 @@ 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.2f%%" RESET " \tBatch Accuracy: " YELLOW "%0.2f%%" RESET, nb_threads, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100, batch_accuracy*100);
|
printf("\rThreads [%d]\tÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: " YELLOW "%0.2f%%" RESET " \tBatch Accuracy: " YELLOW "%0.2f%%" RESET, nb_threads, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100, batch_accuracy*100);
|
||||||
fflush(stdout);
|
|
||||||
#else
|
#else
|
||||||
(void)nb_images_total_remaining; // Juste pour enlever un warning
|
(void)nb_images_total_remaining; // Juste pour enlever un warning
|
||||||
|
|
||||||
@ -331,7 +331,6 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
update_bias(network, network);
|
update_bias(network, network);
|
||||||
|
|
||||||
printf("\rÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: " YELLOW "%0.4f%%" RESET "\tBatch Accuracy: " YELLOW "%0.2f%%" RESET, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100, batch_accuracy*100);
|
printf("\rÉpoque [%d/%d]\tImage [%d/%d]\tAccuracy: " YELLOW "%0.4f%%" RESET "\tBatch Accuracy: " YELLOW "%0.2f%%" RESET, i, epochs, BATCHES*(j+1), nb_images_total, current_accuracy*100, batch_accuracy*100);
|
||||||
fflush(stdout);
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
//* Fin d'une époque: affichage des résultats et sauvegarde du réseau
|
//* Fin d'une époque: affichage des résultats et sauvegarde du réseau
|
||||||
@ -347,11 +346,25 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
|||||||
printf("\n");
|
printf("\n");
|
||||||
#endif
|
#endif
|
||||||
write_network(out, network);
|
write_network(out, network);
|
||||||
// If you want to test the network between each epoch, uncomment the following line:
|
// If you want to test the network between each epoch, uncomment the following lines:
|
||||||
test_network(0, out, "data/mnist/t10k-images-idx3-ubyte", "data/mnist/t10k-labels-idx1-ubyte", NULL, false);
|
/*
|
||||||
|
float* test_results = test_network(0, out, "data/mnist/t10k-images-idx3-ubyte", "data/mnist/t10k-labels-idx1-ubyte", NULL, false, false, true);
|
||||||
|
printf("Tests: Accuracy: %0.2lf%%\tLoss: %lf\n", test_results[0], test_results[1]);
|
||||||
|
if (test_results[0] < test_accuracy) {
|
||||||
|
network->learning_rate *= 0.1;
|
||||||
|
printf("Decreased learning rate to %0.2e\n", network->learning_rate);
|
||||||
|
}
|
||||||
|
if (test_results[0] == test_accuracy) {
|
||||||
|
network->learning_rate *= 2;
|
||||||
|
printf("Increased learning rate to %0.2e\n", network->learning_rate);
|
||||||
|
}
|
||||||
|
test_accuracy = test_results[0];
|
||||||
|
free(test_results);
|
||||||
|
|
||||||
// Learning Rate decay
|
test_results = test_network(0, out, "data/mnist/t10k-images-idx3-ubyte", "data/mnist/t10k-labels-idx1-ubyte", NULL, false, false, false);
|
||||||
network->learning_rate -= LEARNING_RATE*(1./(float)(epochs+1));
|
printf("Tests sans offset: Accuracy: %0.2lf%%\tLoss: %lf\n", test_results[0], test_results[1]);
|
||||||
|
free(test_results);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//* Fin de l'algo
|
//* Fin de l'algo
|
||||||
|
Loading…
Reference in New Issue
Block a user