diff --git a/src/cnn/cnn.c b/src/cnn/cnn.c
index c18a37b..abc8357 100644
--- a/src/cnn/cnn.c
+++ b/src/cnn/cnn.c
@@ -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.;
         }
     }
 }
diff --git a/src/cnn/include/cnn.h b/src/cnn/include/cnn.h
index 5f117d0..150f9b8 100644
--- a/src/cnn/include/cnn.h
+++ b/src/cnn/include/cnn.h
@@ -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
diff --git a/src/cnn/include/test_network.h b/src/cnn/include/test_network.h
index de7f62b..109229e 100644
--- a/src/cnn/include/test_network.h
+++ b/src/cnn/include/test_network.h
@@ -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é
diff --git a/src/cnn/main.c b/src/cnn/main.c
index 2fe2d46..a641b68 100644
--- a/src/cnn/main.c
+++ b/src/cnn/main.c
@@ -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")) {
diff --git a/src/cnn/test_network.c b/src/cnn/test_network.c
index 316aa25..6b83c40 100644
--- a/src/cnn/test_network.c
+++ b/src/cnn/test_network.c
@@ -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);
 
     
diff --git a/src/cnn/train.c b/src/cnn/train.c
index 3855a56..42033ff 100644
--- a/src/cnn/train.c
+++ b/src/cnn/train.c
@@ -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