From 5bee0562fcbd0cbf807805bd1da2f6b8e0d2bb01 Mon Sep 17 00:00:00 2001
From: Luc Giffon <luc.giffon@lis-lab.fr>
Date: Wed, 12 Sep 2018 21:10:31 +0200
Subject: [PATCH] scripts for training convolution on omniglot: siamese network
 and standard conv network use these convolutions on evaluation on the
 background set fix cluger and executioner update omniglot dataset and dataset
 classes add vinyals transformer improve lecun and vgg transformer TODO:
 gather vinyals, lecun and vgg19 transformers into kerasmodel transformer

---
 skluc/{ => examples}/data/__init__.py         |   0
 .../omniglot/pretrained/__init__.py           |   0
 .../omniglot_28x28_pretrained_lenet.py        |  61 +++++
 ...omniglot_28x28_pretrained_siamese_lenet.py |  60 +++++
 ...8x28_pretrained_siamese_vgg19_less_pool.py |  68 ++++++
 ...niglot_28x28_pretrained_siamese_vinyals.py |  60 +++++
 ...niglot_28x28_pretrained_vgg19_less_pool.py |  68 ++++++
 .../omniglot_28x28_pretrained_vinyals.py      |  61 +++++
 .../omniglot/scratch/__init__.py              |   0
 .../omniglot_28x28_lenet.py}                  |  55 +++--
 .../scratch/omniglot_28x28_vgg19_less_pool.py | 185 +++++++++++++++
 .../omniglot_28x28_vinyals.py}                |  45 +++-
 .../{ => scratch}/omniglot_32x32_vgg19.py     |   6 +-
 .../omniglot_28x28_siamese_networks_lenet.py  |   4 +-
 ..._28x28_siamese_networks_vgg19_less_pool.py | 216 ++++++++++++++++++
 ...mniglot_28x28_siamese_networks_vinyals.py} |  59 +++--
 .../omniglot_32x32_siamese_networks_vgg19.py  |   4 +-
 skluc/main/data/mldatasets/Dataset.py         |   3 +-
 skluc/main/data/mldatasets/OmniglotDataset.py |   3 +
 .../transformation/KerasModelTransformer.py   |   2 +
 .../data/transformation/LeCunTransformer.py   |  53 ++++-
 .../VGG19Transformer/__init__.py              |  49 ++--
 .../data/transformation/VinyalsTransformer.py |  73 ++++++
 skluc/main/tools/experiences/cluger.py        |   4 +-
 skluc/main/tools/experiences/executioner.py   |   2 +-
 25 files changed, 1057 insertions(+), 84 deletions(-)
 rename skluc/{ => examples}/data/__init__.py (100%)
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/__init__.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_lenet.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_lenet.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vgg19_less_pool.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vinyals.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vgg19_less_pool.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vinyals.py
 create mode 100644 skluc/examples/tasks/classification/omniglot/scratch/__init__.py
 rename skluc/examples/tasks/classification/omniglot/{omniglot_28x28_simple.py => scratch/omniglot_28x28_lenet.py} (58%)
 create mode 100644 skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vgg19_less_pool.py
 rename skluc/examples/tasks/classification/omniglot/{omniglot_28x28_lenet.py => scratch/omniglot_28x28_vinyals.py} (64%)
 rename skluc/examples/tasks/classification/omniglot/{ => scratch}/omniglot_32x32_vgg19.py (98%)
 create mode 100644 skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vgg19_less_pool.py
 rename skluc/examples/tasks/verification/omniglot/{omniglot_28x28_siamese_networks_simple.py => omniglot_28x28_siamese_networks_vinyals.py} (72%)
 create mode 100644 skluc/main/data/transformation/VinyalsTransformer.py

diff --git a/skluc/data/__init__.py b/skluc/examples/data/__init__.py
similarity index 100%
rename from skluc/data/__init__.py
rename to skluc/examples/data/__init__.py
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/__init__.py b/skluc/examples/tasks/classification/omniglot/pretrained/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_lenet.py b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_lenet.py
new file mode 100644
index 0000000..80435e8
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_lenet.py
@@ -0,0 +1,61 @@
+import time
+
+import numpy as np
+from keras import Sequential, optimizers
+from keras.initializers import he_normal
+from keras.layers import Dense, Activation, BatchNormalization
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.LeCunTransformer import LecunTransformer
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+
+if __name__ == "__main__":
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    weight_decay = 0.0001
+    num_classes = 964
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+    lenet_transformer = LecunTransformer("omniglot_28x28", cut_layer_name="activation_2")
+    data.apply_transformer(lenet_transformer)
+    data.normalize()
+    data.flatten()
+
+    model = Sequential()
+
+    model.add(Dense(120, kernel_initializer=he_normal(), input_shape=data.train.data[0].shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(84, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+
+    print('Using real-time data augmentation.')
+    x_train, y_train = data.train
+    x_test, y_test = data.test
+    x_val, y_val = data.validation
+
+    model.fit(x_train, y_train,
+              batch_size=batch_size,
+              epochs=n_epoch,
+              validation_data=(x_val, y_val))
+
+    model.save('{}_{}.h5'.format(time.time(), __file__))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_lenet.py b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_lenet.py
new file mode 100644
index 0000000..4f2ce32
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_lenet.py
@@ -0,0 +1,60 @@
+import time
+
+import numpy as np
+from keras import Sequential, optimizers
+from keras.initializers import he_normal
+from keras.layers import Dense, Activation, BatchNormalization
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.LeCunTransformer import LecunTransformer
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+
+if __name__ == "__main__":
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    weight_decay = 0.0001
+    num_classes = 964
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+    siamese_lenet_transformer = LecunTransformer("siamese_omniglot_28x28", cut_layer_index=-4)
+    data.apply_transformer(siamese_lenet_transformer)
+    data.normalize()
+
+    model = Sequential()
+
+    model.add(Dense(120, kernel_initializer=he_normal(), input_shape=data.train.data[0].shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(84, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+
+    print('Using real-time data augmentation.')
+    x_train, y_train = data.train
+    x_test, y_test = data.test
+    x_val, y_val = data.validation
+
+    model.fit(x_train, y_train,
+              batch_size=batch_size,
+              epochs=n_epoch,
+              validation_data=(x_val, y_val))
+
+    model.save('{}_{}.h5'.format(time.time(), __file__))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vgg19_less_pool.py b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vgg19_less_pool.py
new file mode 100644
index 0000000..0cde789
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vgg19_less_pool.py
@@ -0,0 +1,68 @@
+import time
+
+import keras
+import numpy as np
+from keras import Sequential, optimizers
+from keras.initializers import he_normal
+from keras.layers import Dense, Activation, BatchNormalization
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.data.transformation.VGG19Transformer import VGG19Transformer
+
+if __name__ == "__main__":
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    weight_decay = 0.0001
+    num_classes = 964
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+    siamese_vgg19_transformer = VGG19Transformer("siamese_omniglot_28x28", cut_layer_name="activation_16")
+    data.apply_transformer(siamese_vgg19_transformer)
+    data.normalize()
+    data.flatten()
+
+    model = Sequential()
+
+    # Block 1
+    model.add(Dense(512, use_bias=True, kernel_regularizer=keras.regularizers.l2(weight_decay),
+                    kernel_initializer=he_normal(), input_shape=data.train.data[0].shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(
+        Dense(512, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(), name='fc2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(),
+                    name='predictions'))
+
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+
+    print('Using real-time data augmentation.')
+    x_train, y_train = data.train
+    x_test, y_test = data.test
+    x_val, y_val = data.validation
+
+    model.fit(x_train, y_train,
+              batch_size=batch_size,
+              epochs=n_epoch,
+              validation_data=(x_val, y_val))
+
+    model.save('{}_{}.h5'.format(time.time(), __file__))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vinyals.py b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vinyals.py
new file mode 100644
index 0000000..752a2a2
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_siamese_vinyals.py
@@ -0,0 +1,60 @@
+import time
+
+import numpy as np
+from keras import Sequential, optimizers
+from keras.initializers import he_normal
+from keras.layers import Dense, Activation, BatchNormalization
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.data.transformation.VinyalsTransformer import VinyalsTransformer
+
+if __name__ == "__main__":
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    weight_decay = 0.0001
+    num_classes = 964
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+    siamese_vinyals_transformer = VinyalsTransformer("siamese_omniglot_28x28", cut_layer_index=-4)
+    data.apply_transformer(siamese_vinyals_transformer)
+    data.normalize()
+
+    model = Sequential()
+
+    model.add(Dense(120, kernel_initializer=he_normal(), input_shape=data.train.data[0].shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(84, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+
+    print('Using real-time data augmentation.')
+    x_train, y_train = data.train
+    x_test, y_test = data.test
+    x_val, y_val = data.validation
+
+    model.fit(x_train, y_train,
+              batch_size=batch_size,
+              epochs=n_epoch,
+              validation_data=(x_val, y_val))
+
+    model.save('{}_{}.h5'.format(time.time(), __file__))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vgg19_less_pool.py b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vgg19_less_pool.py
new file mode 100644
index 0000000..2346c6c
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vgg19_less_pool.py
@@ -0,0 +1,68 @@
+import time
+
+import keras
+import numpy as np
+from keras import Sequential, optimizers
+from keras.initializers import he_normal
+from keras.layers import Dense, Activation, BatchNormalization
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.data.transformation.VGG19Transformer import VGG19Transformer
+
+if __name__ == "__main__":
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    weight_decay = 0.0001
+    num_classes = 964
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+    siamese_vgg19_transformer = VGG19Transformer("omniglot_28x28", cut_layer_name="activation_16")
+    data.apply_transformer(siamese_vgg19_transformer)
+    data.normalize()
+    data.flatten()
+
+    model = Sequential()
+
+    # Block 1
+    model.add(Dense(512, use_bias=True, kernel_regularizer=keras.regularizers.l2(weight_decay),
+                    kernel_initializer=he_normal(), input_shape=data.train.data[0].shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(
+        Dense(512, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(), name='fc2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(),
+                    name='predictions'))
+
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+
+    print('Using real-time data augmentation.')
+    x_train, y_train = data.train
+    x_test, y_test = data.test
+    x_val, y_val = data.validation
+
+    model.fit(x_train, y_train,
+              batch_size=batch_size,
+              epochs=n_epoch,
+              validation_data=(x_val, y_val))
+
+    model.save('{}_{}.h5'.format(time.time(), __file__))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vinyals.py b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vinyals.py
new file mode 100644
index 0000000..51b1f51
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/pretrained/omniglot_28x28_pretrained_vinyals.py
@@ -0,0 +1,61 @@
+import time
+
+import numpy as np
+from keras import Sequential, optimizers
+from keras.initializers import he_normal
+from keras.layers import Dense, Activation, BatchNormalization
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.data.transformation.VinyalsTransformer import VinyalsTransformer
+
+if __name__ == "__main__":
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    weight_decay = 0.0001
+    num_classes = 964
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+    siamese_vinyals_transformer = VinyalsTransformer("omniglot_28x28", cut_layer_name="activation_4")
+    data.apply_transformer(siamese_vinyals_transformer)
+    data.normalize()
+    data.flatten()
+
+    model = Sequential()
+
+    model.add(Dense(120, kernel_initializer=he_normal(), input_shape=data.train.data[0].shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(84, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+
+    print('Using real-time data augmentation.')
+    x_train, y_train = data.train
+    x_test, y_test = data.test
+    x_val, y_val = data.validation
+
+    model.fit(x_train, y_train,
+              batch_size=batch_size,
+              epochs=n_epoch,
+              validation_data=(x_val, y_val))
+
+    model.save('{}_{}.h5'.format(time.time(), __file__))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/scratch/__init__.py b/skluc/examples/tasks/classification/omniglot/scratch/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/skluc/examples/tasks/classification/omniglot/omniglot_28x28_simple.py b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_lenet.py
similarity index 58%
rename from skluc/examples/tasks/classification/omniglot/omniglot_28x28_simple.py
rename to skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_lenet.py
index d03d477..6a4c421 100644
--- a/skluc/examples/tasks/classification/omniglot/omniglot_28x28_simple.py
+++ b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_lenet.py
@@ -2,14 +2,16 @@ import time
 
 import numpy as np
 from keras import optimizers
-from keras.callbacks import LearningRateScheduler, TensorBoard
-from keras.layers import Conv2D, MaxPooling2D
-from keras.layers import Dense, Flatten
+from keras.callbacks import LearningRateScheduler
+from keras.initializers import he_normal
+from keras.layers import Conv2D, MaxPooling2D, Activation, Dense, Flatten
+from keras.layers.normalization import BatchNormalization
 from keras.models import Sequential
 from keras.preprocessing.image import ImageDataGenerator
 
 import skluc.main.data.mldatasets as dataset
 from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.utils import logger
 
 
 def scheduler(epoch):
@@ -28,30 +30,48 @@ def scheduler(epoch):
 
 def model_definition():
     model = Sequential()
-    model.add(
-        Conv2D(6, (5, 5), padding='valid', activation='relu', kernel_initializer='he_normal', input_shape=input_shape))
+
+    model.add(Conv2D(64, (5, 5), padding='same', kernel_initializer=he_normal(), input_shape=input_shape))
+    model.add(BatchNormalization())
     model.add(MaxPooling2D((2, 2), strides=(2, 2)))
-    model.add(Conv2D(16, (5, 5), padding='valid', activation='relu', kernel_initializer='he_normal'))
+    model.add(Activation('relu'))
+
+    model.add(Conv2D(128, (5, 5), padding='same', kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
     model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation('relu'))
+
+
     model.add(Flatten())
-    model.add(Dense(120, activation='relu', kernel_initializer='he_normal'))
-    model.add(Dense(84, activation='relu', kernel_initializer='he_normal'))
-    model.add(Dense(num_classes, activation='softmax', kernel_initializer='he_normal'))
+
+    model.add(Dense(120, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(84, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Dense(num_classes, kernel_initializer=he_normal()))
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+
     sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
     model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
     return model
 
 
 if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
     validation_size = 10000
     seed = 0
     num_classes = 964
     batch_size = 128
-    epochs = 2000
-    dropout = 0.5
+    epochs = 100
+    # dropout = 0.5
     weight_decay = 0.0001
     input_shape = (28, 28, 1)
-    log_filepath = r'./simple_retrain_logs/'
+    log_filepath = r'./lenet_logs/'
 
     data = dataset.OmniglotDataset(validation_size=1000, seed=seed)
     data.load()
@@ -60,16 +80,17 @@ if __name__ == "__main__":
     data.data_astype(np.float32)
     data.labels_astype(np.float32)
     data.to_image()
-    resizetrans = ResizeTransformer(data.s_name, (28, 28))
+    resizetrans = ResizeTransformer(data.s_name, input_shape[:-1])
     data.apply_transformer(resizetrans)
     (x_train, y_train), (x_test, y_test) = data.train, data.test
     x_val, y_val = data.validation
 
     model = model_definition()
 
-    tb_cb = TensorBoard(log_dir=log_filepath, histogram_freq=0)
+    # tb_cb = TensorBoard(log_dir=log_filepath, histogram_freq=1, write_grads=True, write_images=True)
     change_lr = LearningRateScheduler(scheduler)
-    cbks = [change_lr, tb_cb]
+    # cbks = [change_lr, tb_cb]
+    cbks = [change_lr]
 
     print('Using real-time data augmentation.')
     datagen = ImageDataGenerator(horizontal_flip=True,
@@ -82,7 +103,7 @@ if __name__ == "__main__":
                         steps_per_epoch=iterations,
                         epochs=epochs,
                         callbacks=cbks,
-                        validation_data=(x_val[:200], y_val[:200]))
+                        validation_data=(x_val, y_val))
 
-    model.save('{}_simple_omniglot.h5'.format(time.time()))
+    model.save('{}_lenet_omniglot_28x28.h5'.format(time.time()))
     print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vgg19_less_pool.py b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vgg19_less_pool.py
new file mode 100644
index 0000000..198d2f6
--- /dev/null
+++ b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vgg19_less_pool.py
@@ -0,0 +1,185 @@
+import time
+
+import keras
+import numpy as np
+from keras import optimizers
+from keras.callbacks import LearningRateScheduler, TensorBoard
+from keras.initializers import he_normal
+from keras.layers import Conv2D, MaxPooling2D
+from keras.layers import Dense, Dropout, Activation, Flatten
+from keras.layers.normalization import BatchNormalization
+from keras.models import Sequential
+from keras.preprocessing.image import ImageDataGenerator
+
+import skluc.main.data.mldatasets as dataset
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.utils import logger
+
+
+def scheduler(epoch):
+    """
+    Function to pass to the "LearningrateScheduler"
+
+    :param epoch:
+    :return:
+    """
+    if epoch < 80:
+        return 0.1
+    if epoch < 160:
+        return 0.01
+    return 0.001
+
+
+def model_definition():
+    model = Sequential()
+
+    # Block 1
+    model.add(Conv2D(64, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block1_conv1', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(64, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block1_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool'))
+
+    # Block 2
+    model.add(Conv2D(128, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block2_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(128, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block2_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool'))
+
+    # Block 3
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv3'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv4'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool'))
+
+    # Block 4
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv3'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv4'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool'))
+
+    # Block 5
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv3'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv4'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    model.add(Flatten(name='flatten'))
+
+    model.add(Dense(512, use_bias=True, kernel_regularizer=keras.regularizers.l2(weight_decay),
+                    kernel_initializer=he_normal(), name='fc_cifa10'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Dropout(dropout))
+
+    model.add(
+        Dense(512, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(), name='fc2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Dropout(dropout))
+
+    model.add(Dense(num_classes, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(),
+                    name='predictions'))
+
+    model.add(BatchNormalization())
+    model.add(Activation('softmax'))
+
+    # -------- optimizer setting -------- #
+    sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
+    model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
+    return model
+
+
+if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
+
+    validation_size = 10000
+    seed = 0
+    num_classes = 964
+    batch_size = 128
+    epochs = 200
+    dropout = 0.5
+    weight_decay = 0.0001
+    input_shape = (28, 28, 1)
+    log_filepath = r'./vgg19_logs/'
+
+    data = dataset.OmniglotDataset(validation_size=1000, seed=seed)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resizetrans = ResizeTransformer(data.s_name, input_shape[:-1])
+    data.apply_transformer(resizetrans)
+    (x_train, y_train), (x_test, y_test) = data.train, data.test
+    x_val, y_val = data.validation
+
+    model = model_definition()
+
+    tb_cb = TensorBoard(log_dir=log_filepath, histogram_freq=0)
+    change_lr = LearningRateScheduler(scheduler)
+    cbks = [change_lr, tb_cb]
+
+    print('Using real-time data augmentation.')
+    datagen = ImageDataGenerator(horizontal_flip=True,
+                                 width_shift_range=0.125, height_shift_range=0.125, fill_mode='constant', cval=0.)
+
+    datagen.fit(x_train)
+
+    iterations = int(data.train.data.shape[0] / batch_size)
+    model.fit_generator(datagen.flow(x_train, y_train, batch_size=batch_size),
+                        steps_per_epoch=iterations,
+                        epochs=epochs,
+                        callbacks=cbks,
+                        validation_data=(x_val[:200], y_val[:200]))
+
+    model.save('{}_vgg19_omniglot.h5'.format(time.time()))
+    print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/omniglot_28x28_lenet.py b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vinyals.py
similarity index 64%
rename from skluc/examples/tasks/classification/omniglot/omniglot_28x28_lenet.py
rename to skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vinyals.py
index 9133933..d9b1ccd 100644
--- a/skluc/examples/tasks/classification/omniglot/omniglot_28x28_lenet.py
+++ b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_28x28_vinyals.py
@@ -3,13 +3,14 @@ import time
 import numpy as np
 from keras import optimizers
 from keras.callbacks import LearningRateScheduler, TensorBoard
-from keras.layers import Conv2D, MaxPooling2D
+from keras.layers import Conv2D, MaxPooling2D, BatchNormalization, Activation
 from keras.layers import Dense, Flatten
 from keras.models import Sequential
 from keras.preprocessing.image import ImageDataGenerator
 
 import skluc.main.data.mldatasets as dataset
 from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.utils import logger
 
 
 def scheduler(epoch):
@@ -28,30 +29,54 @@ def scheduler(epoch):
 
 def model_definition():
     model = Sequential()
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
     model.add(
-        Conv2D(6, (5, 5), padding='valid', activation='relu', kernel_initializer='he_normal', input_shape=input_shape))
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
     model.add(MaxPooling2D((2, 2), strides=(2, 2)))
-    model.add(Conv2D(16, (5, 5), padding='valid', activation='relu', kernel_initializer='he_normal'))
+    model.add(Activation("relu"))
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
     model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
+
     model.add(Flatten())
-    model.add(Dense(120, activation='relu', kernel_initializer='he_normal'))
-    model.add(Dense(84, activation='relu', kernel_initializer='he_normal'))
-    model.add(Dense(num_classes, activation='softmax', kernel_initializer='he_normal'))
+
+    model.add(Dense(num_classes, kernel_initializer='he_normal'))
+    model.add(Activation("softmax"))
+
     sgd = optimizers.SGD(lr=.1, momentum=0.9, nesterov=True)
     model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])
     return model
 
 
 if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
+
     validation_size = 10000
     seed = 0
     num_classes = 964
     batch_size = 128
-    epochs = 2000
+    epochs = 200
     dropout = 0.5
     weight_decay = 0.0001
     input_shape = (28, 28, 1)
-    log_filepath = r'./lenet_retrain_logs/'
+    log_filepath = r'./vinyals_logs/'
 
     data = dataset.OmniglotDataset(validation_size=1000, seed=seed)
     data.load()
@@ -82,7 +107,7 @@ if __name__ == "__main__":
                         steps_per_epoch=iterations,
                         epochs=epochs,
                         callbacks=cbks,
-                        validation_data=(x_val[:200], y_val[:200]))
+                        validation_data=(x_val, y_val))
 
-    model.save('{}_lenet_omniglot.h5'.format(time.time()))
+    model.save('{}_vinyals_omniglot.h5'.format(time.time()))
     print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/classification/omniglot/omniglot_32x32_vgg19.py b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_32x32_vgg19.py
similarity index 98%
rename from skluc/examples/tasks/classification/omniglot/omniglot_32x32_vgg19.py
rename to skluc/examples/tasks/classification/omniglot/scratch/omniglot_32x32_vgg19.py
index ec9d6ab..65cca16 100644
--- a/skluc/examples/tasks/classification/omniglot/omniglot_32x32_vgg19.py
+++ b/skluc/examples/tasks/classification/omniglot/scratch/omniglot_32x32_vgg19.py
@@ -140,11 +140,11 @@ if __name__ == "__main__":
     seed = 0
     num_classes = 964
     batch_size = 128
-    epochs = 2000
+    epochs = 300
     dropout = 0.5
     weight_decay = 0.0001
     input_shape = (32, 32, 1)
-    log_filepath = r'./vgg19_retrain_logs/'
+    log_filepath = r'./vgg19_logs/'
 
     data = dataset.OmniglotDataset(validation_size=1000, seed=seed)
     data.load()
@@ -177,5 +177,5 @@ if __name__ == "__main__":
                         callbacks=cbks,
                         validation_data=(x_val[:200], y_val[:200]))
 
-    model.save('{}_vgg19_omniglot.h5'.format(time.time()))
+    model.save('{}_vgg19_less_pool_omniglot.h5'.format(time.time()))
     print("Final evaluation on val set: {}".format(model.evaluate(x_val, y_val)))
diff --git a/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_lenet.py b/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_lenet.py
index a94bcc1..1e9d10a 100644
--- a/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_lenet.py
+++ b/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_lenet.py
@@ -15,6 +15,7 @@ from keras.optimizers import Adam
 from skluc.main.data.mldatasets import OmniglotDataset
 from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
 from skluc.main.tensorflow_.utils import batch_generator
+from skluc.main.utils import logger
 
 
 def W_init(shape, name=None):
@@ -66,6 +67,7 @@ def model_definition():
 
 
 if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
     input_shape = (28, 28, 1)
     validation_size = 1000
     n_epoch = 200
@@ -121,4 +123,4 @@ if __name__ == "__main__":
 
     timing = time.time()
     siamese_net.save('{}_siamese_lenet_omniglot_full.h5'.format(timing))
-    siamese_net.save('{}_siamese_lenet_omniglot_conv.h5'.format(timing))
+    convnet_model.save('{}_siamese_lenet_omniglot_conv.h5'.format(timing))
diff --git a/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vgg19_less_pool.py b/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vgg19_less_pool.py
new file mode 100644
index 0000000..9951c0c
--- /dev/null
+++ b/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vgg19_less_pool.py
@@ -0,0 +1,216 @@
+import time
+
+# import dill as pickle
+import keras
+import numpy as np
+import numpy.random as rng
+from keras import backend as K
+from keras.callbacks import TensorBoard
+from keras.initializers import he_normal
+from keras.layers import Conv2D, MaxPooling2D
+from keras.layers import Dense, Dropout, Activation, Flatten
+from keras.layers import Input, Lambda
+from keras.layers.normalization import BatchNormalization
+from keras.models import Model
+from keras.models import Sequential
+from keras.optimizers import Adam
+
+from skluc.main.data.mldatasets import OmniglotDataset
+from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
+from skluc.main.tensorflow_.utils import batch_generator
+from skluc.main.utils import logger
+
+
+def W_init(shape, name=None):
+    values = rng.normal(loc=0, scale=1e-2, size=shape)
+    return K.variable(values, name=name)
+
+
+def b_init(shape, name=None):
+    values = rng.normal(loc=0.5, scale=1e-2, size=shape)
+    return K.variable(values, name=name)
+
+
+def pairwise_output_shape(shapes):
+    shape1, shape2 = shapes
+    return shape1
+
+
+def build_vgg19_model():
+    model = Sequential()
+
+    # Block 1
+    model.add(Conv2D(64, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block1_conv1', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(64, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block1_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block1_pool'))
+
+    # Block 2
+    model.add(Conv2D(128, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block2_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(128, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block2_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block2_pool'))
+
+    # Block 3
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv3'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(256, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block3_conv4'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block3_pool'))
+
+    # Block 4
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv3'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block4_conv4'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(MaxPooling2D((2, 2), strides=(2, 2), name='block4_pool'))
+
+    # Block 5
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv1'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv3'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Conv2D(512, (3, 3), padding='same', kernel_regularizer=keras.regularizers.l2(weight_decay),
+                     kernel_initializer=he_normal(), name='block5_conv4'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+
+    # model modification for cifar-10
+    model.add(Flatten(name='flatten'))
+    model.add(Dense(512, use_bias=True, kernel_regularizer=keras.regularizers.l2(weight_decay),
+                    kernel_initializer=he_normal(), name='fc_cifa10'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Dropout(dropout))
+    model.add(
+        Dense(512, kernel_regularizer=keras.regularizers.l2(weight_decay), kernel_initializer=he_normal(), name='fc2'))
+    model.add(BatchNormalization())
+    model.add(Activation('relu'))
+    model.add(Dropout(dropout))
+
+    return model
+
+
+def model_definition():
+    x1 = Input(input_shape)
+    x2 = Input(input_shape)
+
+    convnet_model = build_vgg19_model()
+
+    repr_x1 = convnet_model(x1)
+    repr_x2 = convnet_model(x2)
+
+    pairwise_l1_dis = Lambda(lambda x: K.abs(x[0] - x[1]), output_shape=pairwise_output_shape)([repr_x1, repr_x2])
+    prediction = Dense(1, activation="sigmoid", bias_initializer=b_init)(pairwise_l1_dis)
+
+    siamese_net = Model(inputs=[x1, x2], outputs=prediction)
+
+    optimizer = Adam(6e-5)
+    siamese_net.compile(loss="binary_crossentropy", optimizer=optimizer, metrics=['accuracy'])
+
+    return convnet_model, siamese_net
+
+
+if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
+    input_shape = (28, 28, 1)
+    validation_size = 1000
+    n_epoch = 200
+    batch_size = 128
+    eval_every = 10
+    nb_pairs = 30000
+    weight_decay = 0.0001
+    dropout = 0.5
+
+    tensorboard_path = "./siamese_vgg19_28x28_tensorboard"
+
+    convnet_model, siamese_net = model_definition()
+
+    tb_cb = TensorBoard(log_dir=tensorboard_path, histogram_freq=0)
+    cbks = [tb_cb]
+
+    data = OmniglotDataset(validation_size=validation_size, seed=0)
+    data.load()
+    data.normalize()
+    data.to_one_hot()
+    data.data_astype(np.float32)
+    data.labels_astype(np.float32)
+    data.to_image()
+    resize_trans = ResizeTransformer(data.s_name, output_shape=input_shape[:-1])
+    data.apply_transformer(resize_trans)
+
+    same_pairs = data.get_n_pairs(data.train.labels, True, nb_pairs // 2)
+    x_same, y_same = [data.train.data[same_pairs[:, 0]], data.train.data[same_pairs[:, 1]]], np.ones(nb_pairs // 2)
+    diff_pairs = data.get_n_pairs(data.train.labels, False, nb_pairs // 2)
+    x_diff, y_diff = [data.train.data[diff_pairs[:, 0]], data.train.data[diff_pairs[:, 1]]], np.zeros(nb_pairs // 2)
+
+    x_train, y_train = np.array([np.vstack((x_same[0], x_diff[0])), np.vstack((x_same[1], x_diff[1]))]), np.hstack(
+        (y_same, y_diff))
+    x_train = np.swapaxes(x_train, 0, 1)
+    shuffled_indexes = np.random.permutation(len(y_train))
+
+    i = 0
+    while i < n_epoch:
+        for X_batch, Y_batch in batch_generator(x_train[shuffled_indexes], y_train[shuffled_indexes], batch_size,
+                                                False):
+            loss = siamese_net.train_on_batch([X_batch[:, 0], X_batch[:, 1]], Y_batch)
+        if i % eval_every == 0:
+            same_pairs = data.get_n_pairs(data.validation.labels, True, batch_size // 2)
+            x_same, y_same = [data.validation.data[same_pairs[:, 0]], data.validation.data[same_pairs[:, 1]]], np.ones(
+                batch_size // 2)
+            diff_pairs = data.get_n_pairs(data.validation.labels, False, batch_size // 2)
+            x_diff, y_diff = [data.validation.data[diff_pairs[:, 0]], data.validation.data[diff_pairs[:, 1]]], np.zeros(
+                batch_size // 2)
+
+            x_batch, y_batch = [np.vstack((x_same[0], x_diff[0])), np.vstack((x_same[1], x_diff[1]))], np.hstack(
+                (y_same, y_diff))
+
+            result = siamese_net.evaluate(x=x_batch, y=y_batch)
+            print("iteration {}/{}, training loss: {}, eval: {}".format(i + 1, n_epoch, str(loss), str(result)))
+        i += 1
+
+    timing = time.time()
+    siamese_net.save('{}_siamese_vgg19_less_pool_omniglot_28x28_full.h5'.format(timing))
+    convnet_model.save('{}_siamese_vgg19_less_pool_omniglot_28x28_conv.h5'.format(timing))
diff --git a/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_simple.py b/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vinyals.py
similarity index 72%
rename from skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_simple.py
rename to skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vinyals.py
index 2a1734b..641240a 100644
--- a/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_simple.py
+++ b/skluc/examples/tasks/verification/omniglot/omniglot_28x28_siamese_networks_vinyals.py
@@ -5,17 +5,17 @@ import numpy as np
 import numpy.random as rng
 from keras import backend as K
 from keras.callbacks import TensorBoard
-from keras.layers import Conv2D, MaxPooling2D
+from keras.layers import Conv2D, MaxPooling2D, BatchNormalization, Activation
 from keras.layers import Dense, Flatten
 from keras.layers import Input, Lambda
 from keras.models import Model
 from keras.models import Sequential
 from keras.optimizers import Adam
-from keras.regularizers import l2
 
 from skluc.main.data.mldatasets import OmniglotDataset
 from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
 from skluc.main.tensorflow_.utils import batch_generator
+from skluc.main.utils import logger
 
 
 def W_init(shape, name=None):
@@ -33,31 +33,43 @@ def pairwise_output_shape(shapes):
     return shape1
 
 
-def build_simple_model():
-    convnet_model = Sequential()
-    # conv2D takes a function with shape and name arguments for initialization
-    convnet_model.add(Conv2D(64, (10, 10), padding="same", activation="relu", input_shape=input_shape,
-                             kernel_initializer=W_init, kernel_regularizer=l2(2e-4), bias_initializer=b_init))
-    convnet_model.add(MaxPooling2D())
-    convnet_model.add(Conv2D(128, (7, 7), padding="same", activation="relu",
-                             kernel_initializer=W_init, kernel_regularizer=l2(2e-4), bias_initializer=b_init))
-    convnet_model.add(MaxPooling2D())
-    convnet_model.add(Conv2D(128, (4, 4), padding="same", activation="relu",
-                             kernel_initializer=W_init, kernel_regularizer=l2(2e-4), bias_initializer=b_init))
-    convnet_model.add(MaxPooling2D())
-    convnet_model.add(Conv2D(256, (4, 4), padding="same", activation="relu",
-                             kernel_initializer=W_init, kernel_regularizer=l2(2e-4), bias_initializer=b_init))
-    convnet_model.add(Flatten())
-    convnet_model.add(Dense(4096, activation="sigmoid",
-                            kernel_initializer=W_init, kernel_regularizer=l2(1e-3), bias_initializer=b_init))
-    return convnet_model
+def build_vinyals_model():
+    model = Sequential()
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
+    model.add(
+        Conv2D(64, (3, 3), padding='same', kernel_initializer='he_normal', input_shape=input_shape))
+    model.add(BatchNormalization())
+    model.add(MaxPooling2D((2, 2), strides=(2, 2)))
+    model.add(Activation("relu"))
+
+    model.add(Flatten())
+
+    return model
 
 
 def model_definition():
     x1 = Input(input_shape)
     x2 = Input(input_shape)
 
-    convnet_model = build_simple_model()
+    convnet_model = build_vinyals_model()
 
     repr_x1 = convnet_model(x1)
     repr_x2 = convnet_model(x2)
@@ -74,6 +86,7 @@ def model_definition():
 
 
 if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
     input_shape = (28, 28, 1)
     validation_size = 1000
     n_epoch = 200
@@ -128,5 +141,5 @@ if __name__ == "__main__":
         i += 1
 
     timing = time.time()
-    siamese_net.save('{}_siamese_simple_omniglot_full.h5'.format(timing))
-    siamese_net.save('{}_siamese_simple_omniglot_conv.h5'.format(timing))
+    siamese_net.save('{}_siamese_vinyals_omniglot_full.h5'.format(timing))
+    convnet_model.save('{}_siamese_vinyals_omniglot_conv.h5'.format(timing))
diff --git a/skluc/examples/tasks/verification/omniglot/omniglot_32x32_siamese_networks_vgg19.py b/skluc/examples/tasks/verification/omniglot/omniglot_32x32_siamese_networks_vgg19.py
index ae40ca2..a24697a 100644
--- a/skluc/examples/tasks/verification/omniglot/omniglot_32x32_siamese_networks_vgg19.py
+++ b/skluc/examples/tasks/verification/omniglot/omniglot_32x32_siamese_networks_vgg19.py
@@ -18,6 +18,7 @@ from keras.optimizers import Adam
 from skluc.main.data.mldatasets import OmniglotDataset
 from skluc.main.data.transformation.ResizeTransformer import ResizeTransformer
 from skluc.main.tensorflow_.utils import batch_generator
+from skluc.main.utils import logger
 
 
 def W_init(shape, name=None):
@@ -158,6 +159,7 @@ def model_definition():
 
 
 if __name__ == "__main__":
+    logger.debug("Executing file {}".format(__file__))
     input_shape = (32, 32, 1)
     validation_size = 1000
     n_epoch = 200
@@ -213,4 +215,4 @@ if __name__ == "__main__":
 
     timing = time.time()
     siamese_net.save('{}_siamese_vgg19_omniglot_full.h5'.format(timing))
-    siamese_net.save('{}_siamese_vgg19_omniglot_conv.h5'.format(timing))
+    convnet_model.save('{}_siamese_vgg19_omniglot_conv.h5'.format(timing))
diff --git a/skluc/main/data/mldatasets/Dataset.py b/skluc/main/data/mldatasets/Dataset.py
index 807771c..1aa8459 100644
--- a/skluc/main/data/mldatasets/Dataset.py
+++ b/skluc/main/data/mldatasets/Dataset.py
@@ -39,7 +39,8 @@ class Dataset(object):
         kept_indices = self.get_uniform_class_rand_indices_train(new_size)
         self.permuted_index_train = self.permuted_index_train[kept_indices]
 
-    def get_bool_idx_label(self, find_label, labels):
+    @staticmethod
+    def get_bool_idx_label(find_label, labels):
         """
         return the np.array bool where find_label == label in labels
         :param find_label:
diff --git a/skluc/main/data/mldatasets/OmniglotDataset.py b/skluc/main/data/mldatasets/OmniglotDataset.py
index 795f1de..e7141fb 100644
--- a/skluc/main/data/mldatasets/OmniglotDataset.py
+++ b/skluc/main/data/mldatasets/OmniglotDataset.py
@@ -109,6 +109,8 @@ class OmniglotDataset(ImageDataset):
             self._check_validation_size(self._train[0].shape[0])
 
             self.save_npz()
+        logger.debug("Number of labels in train set {}".format(len(np.unique(self._train.labels, axis=0))))
+        logger.debug("Number of labels in evaluation set {}".format(len(np.unique(self._test.labels, axis=0))))
 
 
 if __name__ == "__main__":
@@ -116,6 +118,7 @@ if __name__ == "__main__":
 
     d = OmniglotDataset(validation_size=10000)
     d.load()
+    exit()
     d.to_image()
     d.normalize()
     for i, im in enumerate(d.train.data):
diff --git a/skluc/main/data/transformation/KerasModelTransformer.py b/skluc/main/data/transformation/KerasModelTransformer.py
index 1aa35ea..9108ff4 100644
--- a/skluc/main/data/transformation/KerasModelTransformer.py
+++ b/skluc/main/data/transformation/KerasModelTransformer.py
@@ -1,4 +1,5 @@
 import os
+
 import numpy as np
 
 from skluc.main.data.transformation.Transformer import Transformer
@@ -6,6 +7,7 @@ from skluc.main.utils import check_file_md5, logger
 
 
 class KerasModelTransformer(Transformer):
+    # todo vgg19 et lecun ne changent rien
 
     MAP_DATA_MODEL = {}
 
diff --git a/skluc/main/data/transformation/LeCunTransformer.py b/skluc/main/data/transformation/LeCunTransformer.py
index 92e0ddf..39bc52b 100644
--- a/skluc/main/data/transformation/LeCunTransformer.py
+++ b/skluc/main/data/transformation/LeCunTransformer.py
@@ -1,12 +1,11 @@
-from keras.models import load_model
-
 from keras import Model
+from keras.models import load_model
 
 from skluc.main.data.transformation.KerasModelTransformer import KerasModelTransformer
-from skluc.main.utils import logger, create_directory, download_data, check_file_md5, DownloadableModel
+from skluc.main.utils import logger, create_directory, download_data, check_file_md5, DownloadableModel, Singleton
 
 
-class LecunTransformer(KerasModelTransformer):
+class LecunTransformer(KerasModelTransformer, metaclass=Singleton):
     """
     Uses the lenet network to transform input data.
     """
@@ -15,12 +14,34 @@ class LecunTransformer(KerasModelTransformer):
         "mnist": DownloadableModel(
             url="https://pageperso.lis-lab.fr/~luc.giffon/models/1524640419.938414_lenet_mnist.h5",
             checksum="527d7235c213278df1d15d3fe685eb5c"),
+        "siamese_omniglot_28x28": DownloadableModel(
+            url="https://pageperso.lis-lab.fr/~luc.giffon/models/1536239708.891906_siamese_lenet_omniglot_conv.h5",
+            checksum="5092edcb0be7b31b808e221afcede3e6"
+        ),
+        "omniglot_28x28": DownloadableModel(
+            url="https://pageperso.lis-lab.fr/~luc.giffon/models/1536750152.6389275_lenet_omniglot_28x28.h5",
+            checksum="c4f20b6dae0722234e1ec0bee85e3a4d"
+        )
     }
 
-    def __init__(self, data_name):
+    def __init__(self, data_name, cut_layer_name=None, cut_layer_index=None):
         if data_name not in self.MAP_DATA_MODEL.keys():
             raise ValueError("Unknown data name. Can't load weights")
-        transformation_name = self.__class__.__name__
+
+        if cut_layer_name is None and cut_layer_index is None:
+            logger.warning(
+                "Cut layer chosen automatically but it eventually will lead to an error in future: index -1 should be specified explicitly")
+            cut_layer_index = -1
+        if cut_layer_name is not None:
+            transformation_name = str(data_name) + "_" + self.__class__.__name__ + "_" + str(cut_layer_name)
+        elif cut_layer_index is not None:
+            transformation_name = str(data_name) + "_" + self.__class__.__name__ \
+                                  + "_" + str(cut_layer_index)
+            # todo sauvegarder index / nom dans le meme dossier si c'est les meme
+        else:
+            raise AttributeError("Cut layer name or cut_layer index must be given to init VGG19Transformer.")
+        self.__cut_layer_name = cut_layer_name
+        self.__cut_layer_index = cut_layer_index
 
         self.keras_model = None
 
@@ -32,10 +53,24 @@ class LecunTransformer(KerasModelTransformer):
         s_model_path = download_data(self.MAP_DATA_MODEL[self.data_name].url, self.s_download_dir)
         check_file_md5(s_model_path, self.MAP_DATA_MODEL[self.data_name].checksum)
         if self.keras_model is None:
-            logger.debug("Loading Lecun model with {} weights".format(self.data_name))
+            logger.debug("Loading {} model for {} transformation with {} weights".format(self.__class__.__name__,
+                                                                                         self.transformation_name,
+                                                                                         self.data_name))
             self.keras_model = load_model(s_model_path)
 
+            logger.debug("Layers of model {}".format([l.name for l in self.keras_model.layers]))
+
+            if self.__cut_layer_index is not None:
+                cut_layer = self.keras_model.layers[-1]
+                self.__cut_layer_name = cut_layer.name
+                logger.debug(
+                    "Found associated layer {} to layer index {}".format(self.__cut_layer_name, self.__cut_layer_index))
+
             self.keras_model = Model(inputs=self.keras_model.input,
-                                     outputs=self.keras_model.get_layer('conv_pool_2').output)
+                                     outputs=self.keras_model.get_layer(name=self.__cut_layer_name).output)
+
         else:
-            logger.debug("Skip loading model Lecun model with {} weights. Already there.".format(self.data_name))
+            logger.debug("Skip loading model {} for {} transformation with {} weights. Already there.".format(
+                self.__class__.__name__,
+                self.transformation_name,
+                self.data_name))
diff --git a/skluc/main/data/transformation/VGG19Transformer/__init__.py b/skluc/main/data/transformation/VGG19Transformer/__init__.py
index 9af31f4..cfbbdde 100644
--- a/skluc/main/data/transformation/VGG19Transformer/__init__.py
+++ b/skluc/main/data/transformation/VGG19Transformer/__init__.py
@@ -14,31 +14,42 @@ class VGG19Transformer(KerasModelTransformer, metaclass=Singleton):
     MAP_DATA_MODEL = {
         "svhn": DownloadableModel(
             url="https://pageperso.lis-lab.fr/~luc.giffon/models/1529968150.5454917_vgg19_svhn.h5",
-            checksum="563a9ec2aad37459bd1ed0e329441b05"),
+            checksum="563a9ec2aad37459bd1ed0e329441b05"
+        ),
         "cifar100": DownloadableModel(
             url="https://pageperso.lis-lab.fr/~luc.giffon/models/1530965727.781668_vgg19_cifar100fine.h5",
-            checksum="edf43e263fec05e2c013dd5a2128fc38"),
+            checksum="edf43e263fec05e2c013dd5a2128fc38"
+        ),
         "cifar10": DownloadableModel(
             url="https://pageperso.lis-lab.fr/~luc.giffon/models/1522967518.1916964_vgg19_cifar10.h5",
-            checksum="0dbb4f02ceb1f4acb6e24831758106e5")
+            checksum="0dbb4f02ceb1f4acb6e24831758106e5"
+        ),
+        "siamese_omniglot_28x28": DownloadableModel(
+            url="https://pageperso.lis-lab.fr/~luc.giffon/models/1536244775.6502118_siamese_vgg19_omniglot_28x28_conv.h5",
+            checksum="90aec06e688ec3248ba89544a10c9f1f"
+        ),
+        "omniglot_28x28": DownloadableModel(
+            url="https://pageperso.lis-lab.fr/~luc.giffon/models/1536764034.66037_vgg19_omniglot.h5",
+            checksum="ef1272e9c7ce070e8f70889ec58d1c33"
+        )
     }
 
     def __init__(self, data_name, cut_layer_name=None, cut_layer_index=None):
         if data_name not in self.MAP_DATA_MODEL.keys():
             raise ValueError("Unknown data name. Can't load weights")
-        else:
-            data_name = data_name
 
         if cut_layer_name is None and cut_layer_index is None:
+            logger.warning(
+                "Cut layer chosen automatically but it eventually will lead to an error in future: block5_pool should be specified explicitly")
             cut_layer_name = "block5_pool"
         if cut_layer_name is not None:
-            transformation_name = self.__class__.__name__ + "_" + str(cut_layer_name)
+            transformation_name = str(data_name) + "_" + self.__class__.__name__ + "_" + str(cut_layer_name)
         elif cut_layer_index is not None:
-            transformation_name = self.__class__.__name__ \
-                                       + "_" + str(cut_layer_index)
+            transformation_name = str(data_name) + "_" + self.__class__.__name__ \
+                                  + "_" + str(cut_layer_index)
             # todo sauvegarder index / nom dans le meme dossier si c'est les meme
         else:
-            raise AttributeError("Cut layer name or cut_layer index must be given to init VGG19Cifar10Transformer.")
+            raise AttributeError("Cut layer name or cut_layer index must be given to init VGG19Transformer.")
         self.__cut_layer_name = cut_layer_name
         self.__cut_layer_index = cut_layer_index
 
@@ -55,15 +66,21 @@ class VGG19Transformer(KerasModelTransformer, metaclass=Singleton):
             logger.debug("Loading VGG19 model for {} transformation with {} weights".format(self.transformation_name, self.data_name))
             self.keras_model = load_model(s_model_path)
 
-            if self.__cut_layer_name is not None:
-                self.keras_model = Model(inputs=self.keras_model.input,
-                                            outputs=self.keras_model.get_layer(name=self.__cut_layer_name).output)
-            elif self.__cut_layer_index is not None:
-                self.keras_model = Model(inputs=self.keras_model.input,
-                                            outputs=self.keras_model.get_layer(name=self.__cut_layer_index).output)
+            logger.debug("Layers of model {}".format([l.name for l in self.keras_model.layers]))
+
+            if self.__cut_layer_index is not None:
+                cut_layer = self.keras_model.layers[-1]
+                self.__cut_layer_name = cut_layer.name
+                logger.debug(
+                    "Found associated layer {} to layer index {}".format(self.__cut_layer_name, self.__cut_layer_index))
+
+            self.keras_model = Model(inputs=self.keras_model.input,
+                                     outputs=self.keras_model.get_layer(name=self.__cut_layer_name).output)
 
         else:
-            logger.debug("Skip loading model VGG19 for {} transformation with {} weights. Already there.".format(self.transformation_name, self.data_name))
+            logger.debug("Skip loading model VGG19 for {} transformation with {} weights. Already there.".format(
+                self.transformation_name,
+                self.data_name))
 
 
 if __name__ == '__main__':
diff --git a/skluc/main/data/transformation/VinyalsTransformer.py b/skluc/main/data/transformation/VinyalsTransformer.py
new file mode 100644
index 0000000..9658af6
--- /dev/null
+++ b/skluc/main/data/transformation/VinyalsTransformer.py
@@ -0,0 +1,73 @@
+from keras import Model
+from keras.models import load_model
+
+from skluc.main.data.transformation.KerasModelTransformer import KerasModelTransformer
+from skluc.main.utils import logger, create_directory, download_data, check_file_md5, DownloadableModel, Singleton
+
+
+class VinyalsTransformer(KerasModelTransformer, metaclass=Singleton):
+    """
+    Uses the vinyals network to transform input data.
+    """
+
+    MAP_DATA_MODEL = {
+        "siamese_omniglot_28x28": DownloadableModel(
+            url="https://pageperso.lis-lab.fr/~luc.giffon/models/1536240331.3177369_siamese_vinyals_omniglot_conv.h5",
+            checksum="a0b815ad2ab81092c75d129f511b2bdb"
+        ),
+        "omniglot_28x28": DownloadableModel(
+            url="https://pageperso.lis-lab.fr/~luc.giffon/models/1536742266.9412131_vinyals_omniglot.h5",
+            checksum="6460eb1b7eaa478301a281b12ecd2461"
+        )
+    }
+
+    def __init__(self, data_name, cut_layer_name=None, cut_layer_index=None):
+        if data_name not in self.MAP_DATA_MODEL.keys():
+            raise ValueError("Unknown data name. Can't load weights")
+
+        if cut_layer_name is None and cut_layer_index is None:
+            logger.warning(
+                "Cut layer chosen automatically but it eventually will lead to an error in future: index -1 should be specified explicitly")
+            cut_layer_index = -1
+        if cut_layer_name is not None:
+            transformation_name = str(data_name) + "_" + self.__class__.__name__ + "_" + str(cut_layer_name)
+        elif cut_layer_index is not None:
+            transformation_name = str(data_name) + "_" + self.__class__.__name__ \
+                                  + "_" + str(cut_layer_index)
+            # todo sauvegarder index / nom dans le meme dossier si c'est les meme
+        else:
+            raise AttributeError("Cut layer name or cut_layer index must be given to init VGG19Transformer.")
+        self.__cut_layer_name = cut_layer_name
+        self.__cut_layer_index = cut_layer_index
+
+        self.keras_model = None
+
+        super().__init__(data_name=data_name,
+                         transformation_name=transformation_name)
+
+    def load(self):
+        create_directory(self.s_download_dir)
+        s_model_path = download_data(self.MAP_DATA_MODEL[self.data_name].url, self.s_download_dir)
+        check_file_md5(s_model_path, self.MAP_DATA_MODEL[self.data_name].checksum)
+        if self.keras_model is None:
+            logger.debug("Loading {} model for {} transformation with {} weights".format(self.__class__.__name__,
+                                                                                         self.transformation_name,
+                                                                                         self.data_name))
+            self.keras_model = load_model(s_model_path)
+
+            logger.debug("Layers of model {}".format([l.name for l in self.keras_model.layers]))
+
+            if self.__cut_layer_index is not None:
+                cut_layer = self.keras_model.layers[-1]
+                self.__cut_layer_name = cut_layer.name
+                logger.debug(
+                    "Found associated layer {} to layer index {}".format(self.__cut_layer_name, self.__cut_layer_index))
+
+            self.keras_model = Model(inputs=self.keras_model.input,
+                                     outputs=self.keras_model.get_layer(name=self.__cut_layer_name).output)
+
+        else:
+            logger.debug("Skip loading model {} for {} transformation with {} weights. Already there.".format(
+                self.__class__.__name__,
+                self.transformation_name,
+                self.data_name))
diff --git a/skluc/main/tools/experiences/cluger.py b/skluc/main/tools/experiences/cluger.py
index 6c02a21..9729850 100644
--- a/skluc/main/tools/experiences/cluger.py
+++ b/skluc/main/tools/experiences/cluger.py
@@ -24,8 +24,8 @@ import time
 
 import docopt
 
-from skluc.main.tools import process_script_params, run as executioner
-from skluc.main.tools import oarcmd
+from skluc.main.tools.experiences.executioner import process_script_params, run as executioner
+from skluc.main.tools.experiences.oarCmdGenerator import oarcmd
 
 if __name__ == '__main__':
     arguments = docopt.docopt(__doc__)
diff --git a/skluc/main/tools/experiences/executioner.py b/skluc/main/tools/experiences/executioner.py
index 8ad5a2c..159ec37 100644
--- a/skluc/main/tools/experiences/executioner.py
+++ b/skluc/main/tools/experiences/executioner.py
@@ -38,7 +38,7 @@ from contextlib import redirect_stdout
 import docopt
 import pip
 
-from skluc.main.tools import oarcmd
+from skluc.main.tools.experiences.oarCmdGenerator import oarcmd
 from skluc.main.utils import create_directory, logger
 
 
-- 
GitLab