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 <stdio.h>
|
||||
#include <math.h>
|
||||
#include <float.h> // Is it used ?
|
||||
#include <math.h>
|
||||
|
||||
#include "include/backpropagation.h"
|
||||
#include "include/initialisation.h"
|
||||
@ -33,7 +34,80 @@ int will_be_drop(int 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;
|
||||
for (int i=0; i < padding; i++) {
|
||||
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 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
|
||||
*/
|
||||
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
|
||||
|
@ -6,7 +6,7 @@
|
||||
/*
|
||||
* 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é
|
||||
|
@ -188,7 +188,7 @@ int main(int argc, char* argv[]) {
|
||||
printf_error("Pas de modèle à utiliser spécifié.\n");
|
||||
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;
|
||||
}
|
||||
if (! strcmp(argv[1], "recognize")) {
|
||||
|
@ -12,7 +12,7 @@
|
||||
#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
|
||||
int width, height; // Dimensions des images
|
||||
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
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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
|
||||
jpegDataset* dataset = loadJpegDataset(data_dir);
|
||||
|
||||
@ -71,7 +75,7 @@ void test_network_jpg(Network* network, char* data_dir, bool preview_fails) {
|
||||
int maxi;
|
||||
|
||||
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);
|
||||
fflush(stdout);
|
||||
}
|
||||
@ -86,23 +90,35 @@ void test_network_jpg(Network* network, char* data_dir, bool preview_fails) {
|
||||
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->labels);
|
||||
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);
|
||||
float* results;
|
||||
|
||||
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 {
|
||||
test_network_jpg(network, data_dir, preview_fails);
|
||||
results = test_network_jpg(network, data_dir, preview_fails, to_stdout);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
|
@ -51,7 +51,7 @@ void* train_thread(void* parameters) {
|
||||
|
||||
for (int i=start; i < start+nb_images; i++) {
|
||||
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);
|
||||
maxi = indice_max(network->input[network->size-1][0][0], 10);
|
||||
if (maxi == -1) {
|
||||
@ -106,6 +106,7 @@ void train(int dataset_type, char* images_file, char* labels_file, char* data_di
|
||||
srand(time(NULL));
|
||||
float loss;
|
||||
float batch_loss; // May be redundant with loss, but gives more informations
|
||||
float test_accuracy = 0.; // Used to decrease Learning rate
|
||||
float accuracy;
|
||||
float batch_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();
|
||||
|
||||
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_time(elapsed_time);
|
||||
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);
|
||||
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
|
||||
(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);
|
||||
|
||||
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
|
||||
}
|
||||
//* 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");
|
||||
#endif
|
||||
write_network(out, network);
|
||||
// If you want to test the network between each epoch, uncomment the following line:
|
||||
test_network(0, out, "data/mnist/t10k-images-idx3-ubyte", "data/mnist/t10k-labels-idx1-ubyte", NULL, false);
|
||||
// If you want to test the network between each epoch, uncomment the following lines:
|
||||
/*
|
||||
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
|
||||
network->learning_rate -= LEARNING_RATE*(1./(float)(epochs+1));
|
||||
test_results = test_network(0, out, "data/mnist/t10k-images-idx3-ubyte", "data/mnist/t10k-labels-idx1-ubyte", NULL, false, false, false);
|
||||
printf("Tests sans offset: Accuracy: %0.2lf%%\tLoss: %lf\n", test_results[0], test_results[1]);
|
||||
free(test_results);
|
||||
*/
|
||||
}
|
||||
|
||||
//* Fin de l'algo
|
||||
|
Loading…
Reference in New Issue
Block a user