From f9965fd85bee1c086e15ea2a9f03c121cbfbecf3 Mon Sep 17 00:00:00 2001 From: Tiago Freitas Pereira <tiagofrepereira@gmail.com> Date: Thu, 6 Oct 2016 10:21:36 +0200 Subject: [PATCH] Several updates. Need to control better these commits --- bob/learn/tensorflow/data/BaseDataShuffler.py | 4 +- .../tensorflow/data/MemoryDataShuffler.py | 4 +- bob/learn/tensorflow/data/TextDataShuffler.py | 27 +++++++++ bob/learn/tensorflow/layers/MaxPooling.py | 5 +- bob/learn/tensorflow/loss/TripletLoss.py | 4 +- bob/learn/tensorflow/network/Chopra.py | 51 ++++++++-------- bob/learn/tensorflow/script/train_mnist.py | 5 +- .../tensorflow/script/train_mnist_siamese.py | 6 +- .../tensorflow/script/train_mnist_triplet.py | 12 ++-- .../tensorflow/trainers/TripletTrainer.py | 59 +++++++++---------- 10 files changed, 103 insertions(+), 74 deletions(-) diff --git a/bob/learn/tensorflow/data/BaseDataShuffler.py b/bob/learn/tensorflow/data/BaseDataShuffler.py index 544f37b4..28a6b621 100644 --- a/bob/learn/tensorflow/data/BaseDataShuffler.py +++ b/bob/learn/tensorflow/data/BaseDataShuffler.py @@ -101,8 +101,8 @@ class BaseDataShuffler(object): def get_one_triplet(self, input_data, input_labels): # Getting a pair of clients index = numpy.random.choice(len(self.possible_labels), 2, replace=False) - label_positive = index[0] - label_negative = index[1] + index[0] = self.possible_labels[index[0]] + index[1] = self.possible_labels[index[1]] # Getting the indexes of the data from a particular client indexes = numpy.where(input_labels == index[0])[0] diff --git a/bob/learn/tensorflow/data/MemoryDataShuffler.py b/bob/learn/tensorflow/data/MemoryDataShuffler.py index d9d350a8..ae2e22d5 100644 --- a/bob/learn/tensorflow/data/MemoryDataShuffler.py +++ b/bob/learn/tensorflow/data/MemoryDataShuffler.py @@ -82,7 +82,7 @@ class MemoryDataShuffler(BaseDataShuffler): return data, data_p, labels_siamese - def get_random_triplet(self, n_triplets=1): + def get_random_triplet(self): """ Get a random triplet @@ -96,7 +96,7 @@ class MemoryDataShuffler(BaseDataShuffler): data_p = numpy.zeros(shape=self.shape, dtype='float32') data_n = numpy.zeros(shape=self.shape, dtype='float32') - for i in range(n_triplets): + for i in range(self.shape[0]): data_a[i, ...], data_p[i, ...], data_n[i, ...] = self.get_one_triplet(self.data, self.labels) return data_a, data_p, data_n diff --git a/bob/learn/tensorflow/data/TextDataShuffler.py b/bob/learn/tensorflow/data/TextDataShuffler.py index 22925f37..1829f53e 100644 --- a/bob/learn/tensorflow/data/TextDataShuffler.py +++ b/bob/learn/tensorflow/data/TextDataShuffler.py @@ -150,3 +150,30 @@ class TextDataShuffler(BaseDataShuffler): return data, data_p, labels_siamese + def get_random_triplet(self): + """ + Get a random pair of samples + + **Parameters** + is_target_set_train: Defining the target set to get the batch + + **Return** + """ + + data_a = numpy.zeros(shape=self.shape, dtype='float32') + data_p = numpy.zeros(shape=self.shape, dtype='float32') + data_n = numpy.zeros(shape=self.shape, dtype='float32') + + for i in range(self.shape[0]): + file_name_a, file_name_p, file_name_n = self.get_one_triplet(self.data, self.labels) + data_a[i, ...] = self.load_from_file(str(file_name_a), self.shape) + data_p[i, ...] = self.load_from_file(str(file_name_p), self.shape) + data_n[i, ...] = self.load_from_file(str(file_name_n), self.shape) + + if self.scale: + data_a *= self.scale_value + data_p *= self.scale_value + data_n *= self.scale_value + + return data_a, data_p, data_n + diff --git a/bob/learn/tensorflow/layers/MaxPooling.py b/bob/learn/tensorflow/layers/MaxPooling.py index e8566003..4897b940 100644 --- a/bob/learn/tensorflow/layers/MaxPooling.py +++ b/bob/learn/tensorflow/layers/MaxPooling.py @@ -10,11 +10,12 @@ from .Layer import Layer class MaxPooling(Layer): - def __init__(self, name): + def __init__(self, name, shape=[1, 2, 2, 1]): """ Constructor """ super(MaxPooling, self).__init__(name, use_gpu=False) + self.shape = shape def create_variables(self, input_layer): self.input_layer = input_layer @@ -22,6 +23,6 @@ class MaxPooling(Layer): def get_graph(self): with tf.name_scope(str(self.name)): - output = tf.nn.max_pool(self.input_layer, ksize=[1, 2, 2, 1], strides=[1, 2, 2, 1], padding='SAME') + output = tf.nn.max_pool(self.input_layer, ksize=self.shape, strides=[1, 1, 1, 1], padding='SAME') return output diff --git a/bob/learn/tensorflow/loss/TripletLoss.py b/bob/learn/tensorflow/loss/TripletLoss.py index abfa5f38..2806b1ec 100644 --- a/bob/learn/tensorflow/loss/TripletLoss.py +++ b/bob/learn/tensorflow/loss/TripletLoss.py @@ -30,7 +30,7 @@ class TripletLoss(BaseLoss): """ - def __init__(self, margin=2.0): + def __init__(self, margin=5.0): self.margin = margin def __call__(self, anchor_feature, positive_feature, negative_feature): @@ -41,5 +41,5 @@ class TripletLoss(BaseLoss): d_negative = tf.square(compute_euclidean_distance(anchor_feature, negative_feature)) loss = tf.maximum(0., d_positive - d_negative + self.margin) - return tf.reduce_mean(loss), tf.reduce_mean(d_positive), tf.reduce_mean(d_negative) + #return loss, d_positive, d_negative diff --git a/bob/learn/tensorflow/network/Chopra.py b/bob/learn/tensorflow/network/Chopra.py index bcc516f3..96f9e346 100644 --- a/bob/learn/tensorflow/network/Chopra.py +++ b/bob/learn/tensorflow/network/Chopra.py @@ -9,6 +9,18 @@ Class that creates the architecture presented in the paper: Chopra, Sumit, Raia Hadsell, and Yann LeCun. "Learning a similarity metric discriminatively, with application to face verification." 2005 IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR'05). Vol. 1. IEEE, 2005. +This is modifield version of the original architecture. +It is inspired on https://gitlab.idiap.ch/bob/xfacereclib.cnn/blob/master/lua/network.lua + +-- C1 : Convolutional, kernel = 7x7 pixels, 15 feature maps +-- M2 : MaxPooling, 2x2 +-- HT : Hard Hyperbolic Tangent +-- C3 : Convolutional, kernel = 6x6 pixels, 45 feature maps +-- M4 : MaxPooling, 4x3 +-- HT : Hard Hyperbolic Tangent +-- R : Reshaping layer HT 5x5 => 25 (45 times; once for each feature map) +-- L5 : Linear 25 => 250 + """ @@ -26,15 +38,16 @@ class Chopra(SequenceNetwork): conv1_kernel_size=7, conv1_output=15, + pooling1_size=[1, 2, 2, 1], + + conv2_kernel_size=6, conv2_output=45, - conv3_kernel_size=5, - conv3_output=250, + pooling2_size=[1, 4, 3, 1], - fc6_output=50, - n_classes=40, - default_feature_layer="fc7", + fc1_output=250, + default_feature_layer="fc1", seed=10, use_gpu=False): @@ -45,19 +58,19 @@ class Chopra(SequenceNetwork): conv1_kernel_size=5, conv1_output=32, + pooling1_size=[1, 2, 2, 1], + conv2_kernel_size=5, conv2_output=64, - conv3_kernel_size=5, - conv3_output=250, + pooling2_size=[1, 4, 3, 1], - fc6_output=50, - n_classes=10 + fc1_output=50, seed = 10 """ super(Chopra, self).__init__(default_feature_layer=default_feature_layer, - use_gpu=use_gpu) + use_gpu=use_gpu) self.add(Conv2D(name="conv1", kernel_size=conv1_kernel_size, filters=conv1_output, @@ -65,7 +78,7 @@ class Chopra(SequenceNetwork): weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu), bias_initialization=Constant(use_gpu=self.use_gpu) )) - self.add(MaxPooling(name="pooling1")) + self.add(MaxPooling(name="pooling1", shape=pooling1_size)) self.add(Conv2D(name="conv2", kernel_size=conv2_kernel_size, filters=conv2_output, @@ -73,21 +86,9 @@ class Chopra(SequenceNetwork): weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu), bias_initialization=Constant(use_gpu=self.use_gpu) )) - self.add(MaxPooling(name="pooling2")) + self.add(MaxPooling(name="pooling2", shape=pooling2_size)) - self.add(Conv2D(name="conv3", kernel_size=conv3_kernel_size, - filters=conv3_output, - activation=tf.nn.tanh, - weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu), - bias_initialization=Constant(use_gpu=self.use_gpu) - )) - - self.add(FullyConnected(name="fc6", output_dim=fc6_output, - activation=tf.nn.tanh, - weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu), - bias_initialization=Constant(use_gpu=self.use_gpu) - )) - self.add(FullyConnected(name="fc7", output_dim=n_classes, + self.add(FullyConnected(name="fc1", output_dim=fc1_output, activation=None, weights_initialization=Xavier(seed=seed, use_gpu=self.use_gpu), bias_initialization=Constant(use_gpu=self.use_gpu))) diff --git a/bob/learn/tensorflow/script/train_mnist.py b/bob/learn/tensorflow/script/train_mnist.py index a8db168f..ee8221c9 100644 --- a/bob/learn/tensorflow/script/train_mnist.py +++ b/bob/learn/tensorflow/script/train_mnist.py @@ -23,7 +23,7 @@ import tensorflow as tf from .. import util SEED = 10 from bob.learn.tensorflow.data import MemoryDataShuffler, TextDataShuffler -from bob.learn.tensorflow.network import Lenet, MLP, Dummy +from bob.learn.tensorflow.network import Lenet, MLP, Dummy, Chopra from bob.learn.tensorflow.trainers import Trainer from bob.learn.tensorflow.loss import BaseLoss @@ -89,7 +89,8 @@ def main(): # Preparing the architecture cnn = True if cnn: - architecture = Lenet(seed=SEED) + architecture = Chopra(seed=SEED) + #architecture = Lenet(seed=SEED) #architecture = Dummy(seed=SEED) loss = BaseLoss(tf.nn.sparse_softmax_cross_entropy_with_logits, tf.reduce_mean) trainer = Trainer(architecture=architecture, loss=loss, iterations=ITERATIONS) diff --git a/bob/learn/tensorflow/script/train_mnist_siamese.py b/bob/learn/tensorflow/script/train_mnist_siamese.py index 465d3227..5cfd16fd 100644 --- a/bob/learn/tensorflow/script/train_mnist_siamese.py +++ b/bob/learn/tensorflow/script/train_mnist_siamese.py @@ -39,7 +39,7 @@ def main(): perc_train = 0.9 # Loading data - mnist = False + mnist = True if mnist: train_data, train_labels, validation_data, validation_labels = \ @@ -118,8 +118,8 @@ def main(): if cnn: # LENET PAPER CHOPRA - #architecture = Chopra(default_feature_layer="fc7") - architecture = Lenet(default_feature_layer="fc2", n_classes=n_classes, conv1_output=8, conv2_output=16,use_gpu=USE_GPU) + architecture = Chopra(seed=SEED) + #architecture = Lenet(default_feature_layer="fc2", n_classes=n_classes, conv1_output=8, conv2_output=16,use_gpu=USE_GPU) #architecture = VGG(n_classes=n_classes, use_gpu=USE_GPU) #architecture = Dummy(seed=SEED) diff --git a/bob/learn/tensorflow/script/train_mnist_triplet.py b/bob/learn/tensorflow/script/train_mnist_triplet.py index cbe1878e..c46eb1c5 100644 --- a/bob/learn/tensorflow/script/train_mnist_triplet.py +++ b/bob/learn/tensorflow/script/train_mnist_triplet.py @@ -39,7 +39,7 @@ def main(): perc_train = 0.9 # Loading data - mnist = True + mnist = False if mnist: train_data, train_labels, validation_data, validation_labels = \ @@ -125,15 +125,15 @@ def main(): #architecture = LenetDropout(default_feature_layer="fc2", n_classes=n_classes, conv1_output=4, conv2_output=8, use_gpu=USE_GPU) loss = TripletLoss() - optimizer = tf.train.GradientDescentOptimizer(0.0001) - + optimizer = tf.train.GradientDescentOptimizer(0.000001) trainer = TripletTrainer(architecture=architecture, loss=loss, iterations=ITERATIONS, snapshot=VALIDATION_TEST, - optimizer=optimizer) - #trainer.train(train_data_shuffler, validation_data_shuffler) - trainer.train(train_data_shuffler) + optimizer=optimizer + ) + trainer.train(train_data_shuffler, validation_data_shuffler) + #trainer.train(train_data_shuffler) else: mlp = MLP(n_classes, hidden_layers=[15, 20]) diff --git a/bob/learn/tensorflow/trainers/TripletTrainer.py b/bob/learn/tensorflow/trainers/TripletTrainer.py index 054edc33..fcb2c2c1 100644 --- a/bob/learn/tensorflow/trainers/TripletTrainer.py +++ b/bob/learn/tensorflow/trainers/TripletTrainer.py @@ -87,36 +87,29 @@ class TripletTrainer(Trainer): bob.io.base.create_directories_safe(self.temp_dir) # Creating two graphs - #train_placeholder_anchor_data, _ = train_data_shuffler.get_placeholders_forprefetch(name="train_anchor") - #train_placeholder_positive_data, _ = train_data_shuffler.get_placeholders_forprefetch(name="train_positive") - #train_placeholder_negative_data, _ = train_data_shuffler.get_placeholders_forprefetch(name="train_negative") + train_placeholder_anchor_data, _ = train_data_shuffler.get_placeholders_forprefetch(name="train_anchor") + train_placeholder_positive_data, _ = train_data_shuffler.get_placeholders_forprefetch(name="train_positive") + train_placeholder_negative_data, _ = train_data_shuffler.get_placeholders_forprefetch(name="train_negative") # Defining a placeholder queue for prefetching - #queue = tf.FIFOQueue(capacity=100, - # dtypes=[tf.float32, tf.float32, tf.float32], - # shapes=[train_placeholder_anchor_data.get_shape().as_list()[1:], - # train_placeholder_positive_data.get_shape().as_list()[1:], - # train_placeholder_negative_data.get_shape().as_list()[1:]]) + queue = tf.FIFOQueue(capacity=100, + dtypes=[tf.float32, tf.float32, tf.float32], + shapes=[train_placeholder_anchor_data.get_shape().as_list()[1:], + train_placeholder_positive_data.get_shape().as_list()[1:], + train_placeholder_negative_data.get_shape().as_list()[1:]]) # Fetching the place holders from the queue - #enqueue_op = queue.enqueue_many([train_placeholder_anchor_data, - # train_placeholder_positive_data, - # train_placeholder_negative_data]) - #train_anchor_feature_batch, train_positive_label_batch, train_negative_label_batch = \ - # queue.dequeue_many(train_data_shuffler.batch_size) + enqueue_op = queue.enqueue_many([train_placeholder_anchor_data, + train_placeholder_positive_data, + train_placeholder_negative_data]) + train_anchor_feature_batch, train_positive_feature_batch, train_negative_feature_batch = \ + queue.dequeue_many(train_data_shuffler.batch_size) # Creating the architecture for train and validation if not isinstance(self.architecture, SequenceNetwork): raise ValueError("The variable `architecture` must be an instance of " "`bob.learn.tensorflow.network.SequenceNetwork`") - - ############# - train_anchor_feature_batch, _ = train_data_shuffler.get_placeholders(name="train_anchor") - train_positive_feature_batch, _ = train_data_shuffler.get_placeholders(name="train_positive") - train_negative_feature_batch, _ = train_data_shuffler.get_placeholders(name="train_negative") - ############# - # Creating the siamese graph #import ipdb; ipdb.set_trace(); train_anchor_graph = self.architecture.compute_graph(train_anchor_feature_batch) @@ -145,9 +138,9 @@ class TripletTrainer(Trainer): tf.initialize_all_variables().run() # Start a thread to enqueue data asynchronously, and hide I/O latency. - #thread_pool = tf.train.Coordinator() - #tf.train.start_queue_runners(coord=thread_pool) - #threads = start_thread() + thread_pool = tf.train.Coordinator() + tf.train.start_queue_runners(coord=thread_pool) + threads = start_thread() # TENSOR BOARD SUMMARY train_writer = tf.train.SummaryWriter(os.path.join(self.temp_dir, 'LOGS'), session.graph) @@ -165,18 +158,24 @@ class TripletTrainer(Trainer): for step in range(self.iterations): - batch_anchor, batch_positive, batch_negative = train_data_shuffler.get_random_triplet() + #batch_anchor, batch_positive, batch_negative = train_data_shuffler.get_random_triplet() + + #feed_dict = {train_anchor_feature_batch: batch_anchor, + # train_positive_feature_batch: batch_positive, + # train_negative_feature_batch: batch_negative} + - feed_dict = {train_anchor_feature_batch: batch_anchor, - train_positive_feature_batch: batch_positive, - train_negative_feature_batch: batch_negative} + #_, l, lr, summary, pos, neg = session.run([optimizer, loss_train, learning_rate, merged, within_class, between_class], feed_dict=feed_dict) + #_, l, lr, pos, neg, f_anchor, f_positive, f_negative = session.run( + # [optimizer, loss_train, learning_rate, within_class, between_class, train_anchor_feature_batch, train_positive_feature_batch, train_negative_feature_batch], feed_dict=feed_dict) + #import ipdb; ipdb.set_trace(); - _, l, lr, summary = session.run([optimizer, loss_train, learning_rate, merged], feed_dict=feed_dict) - #_, l, lr= session.run([optimizer, loss_train, learning_rate]) + _, l, lr, summary = session.run([optimizer, loss_train, learning_rate, merged]) train_writer.add_summary(summary, step) - print str(step) + " -- loss: " + str(l) + #print str(step) + " -- loss: " + str(l) + #print str(step) + " -- loss: {0}; pos: {1}; neg: {2}".format(l, pos, neg) sys.stdout.flush() if validation_data_shuffler is not None and step % self.snapshot == 0: -- GitLab