From ef1c03ce9a85055aaf849b98f84c801a541395e7 Mon Sep 17 00:00:00 2001
From: Tiago Freitas Pereira <tiagofrepereira@gmail.com>
Date: Thu, 25 Aug 2016 16:45:04 +0200
Subject: [PATCH] Make Siamese network work

---
 bob/learn/tensorflow/analyzers/Analizer.py       |  5 +++--
 bob/learn/tensorflow/data/DataShuffler.py        |  2 +-
 bob/learn/tensorflow/loss/ContrastiveLoss.py     | 10 +++++-----
 bob/learn/tensorflow/network/Lenet.py            |  3 ++-
 .../tensorflow/script/train_mnist_siamese.py     |  2 +-
 bob/learn/tensorflow/trainers/SiameseTrainer.py  | 16 ++++++++++------
 6 files changed, 22 insertions(+), 16 deletions(-)

diff --git a/bob/learn/tensorflow/analyzers/Analizer.py b/bob/learn/tensorflow/analyzers/Analizer.py
index f307f3cb..27ea52f0 100644
--- a/bob/learn/tensorflow/analyzers/Analizer.py
+++ b/bob/learn/tensorflow/analyzers/Analizer.py
@@ -46,6 +46,7 @@ class Analizer:
     def extract_features(self):
         data, labels = self.data_shuffler.get_batch(train_dataset=False)
         feed_dict = {self.feature_placeholder: data}
+
         return self.session.run([self.graph], feed_dict=feed_dict)[0], labels
 
     def __call__(self):
@@ -98,7 +99,7 @@ class Analizer:
         threshold = bob.measure.eer_threshold(negative_scores, positive_scores)
         far, frr = bob.measure.farfrr(negative_scores, positive_scores, threshold)
         eer = (far + frr) / 2.
-        self.eer .append(eer)
+        self.eer.append(eer)
 
         # Computing FAR 10
         threshold = bob.measure.far_threshold(negative_scores, positive_scores, far_value=0.1)
@@ -115,4 +116,4 @@ class Analizer:
         far, frr = bob.measure.farfrr(negative_scores, positive_scores, threshold)
         self.far1000.append(frr)
 
-        print eer
+        return
diff --git a/bob/learn/tensorflow/data/DataShuffler.py b/bob/learn/tensorflow/data/DataShuffler.py
index e0a93265..76d5d9d6 100644
--- a/bob/learn/tensorflow/data/DataShuffler.py
+++ b/bob/learn/tensorflow/data/DataShuffler.py
@@ -23,7 +23,7 @@ class DataShuffler(object):
         """
 
         self.perc_train = perc_train
-        self.scale = True
+        self.scale = scale
         self.scale_value = 0.00390625
         self.train_batch_size = train_batch_size
         self.validation_batch_size = validation_batch_size
diff --git a/bob/learn/tensorflow/loss/ContrastiveLoss.py b/bob/learn/tensorflow/loss/ContrastiveLoss.py
index 740caec7..2609fe09 100644
--- a/bob/learn/tensorflow/loss/ContrastiveLoss.py
+++ b/bob/learn/tensorflow/loss/ContrastiveLoss.py
@@ -27,20 +27,20 @@ class ContrastiveLoss(BaseLoss):
 
     """
 
-    def __init__(self):
-        return
+    def __init__(self, contrastive_margin=1.0):
+        self.contrastive_margin = contrastive_margin
 
-    def __call__(self, label, left_feature, right_feature, margin):
+    def __call__(self, label, left_feature, right_feature):
         with tf.name_scope("contrastive_loss"):
             label = tf.to_float(label)
             one = tf.constant(1.0)
 
             d = compute_euclidean_distance(left_feature, right_feature)
             between_class = tf.exp(tf.mul(one - label, tf.square(d)))  # (1-Y)*(d^2)
-            max_part = tf.square(tf.maximum(margin - d, 0))
+            max_part = tf.square(tf.maximum(self.contrastive_margin - d, 0))
 
             within_class = tf.mul(label, max_part)  # (Y) * max((margin - d)^2, 0)
 
             loss = 0.5 * tf.reduce_mean(within_class + between_class)
 
-            return tf.reduce_mean(loss), tf.reduce_mean(between_class), tf.reduce_mean(within_class)
+            return loss, tf.reduce_mean(between_class), tf.reduce_mean(within_class)
diff --git a/bob/learn/tensorflow/network/Lenet.py b/bob/learn/tensorflow/network/Lenet.py
index 38972106..bb6d0e44 100644
--- a/bob/learn/tensorflow/network/Lenet.py
+++ b/bob/learn/tensorflow/network/Lenet.py
@@ -24,6 +24,7 @@ class Lenet(SequenceNetwork):
 
                  fc1_output=400,
                  n_classes=10,
+                 feature_layer="fc2",
 
                  seed=10, use_gpu = False):
         """
@@ -41,7 +42,7 @@ class Lenet(SequenceNetwork):
 
             seed = 10
         """
-        super(Lenet, self).__init__(feature_layer="fc2")
+        super(Lenet, self).__init__(feature_layer=feature_layer)
 
         self.add(Conv2D(name="conv1", kernel_size=conv1_kernel_size, filters=conv1_output, activation=tf.nn.tanh))
         self.add(MaxPooling(name="pooling1"))
diff --git a/bob/learn/tensorflow/script/train_mnist_siamese.py b/bob/learn/tensorflow/script/train_mnist_siamese.py
index 9fd2398f..42804b9f 100644
--- a/bob/learn/tensorflow/script/train_mnist_siamese.py
+++ b/bob/learn/tensorflow/script/train_mnist_siamese.py
@@ -44,7 +44,7 @@ def main():
     data_shuffler = PairDataShuffler(data, labels)
 
     # Preparing the architecture
-    lenet = Lenet()
+    lenet = Lenet(feature_layer="fc1")
 
     loss = ContrastiveLoss()
     trainer = SiameseTrainer(architecture=lenet, loss=loss, iterations=ITERATIONS, base_lr=0.00001)
diff --git a/bob/learn/tensorflow/trainers/SiameseTrainer.py b/bob/learn/tensorflow/trainers/SiameseTrainer.py
index 338db546..7b7adf5d 100644
--- a/bob/learn/tensorflow/trainers/SiameseTrainer.py
+++ b/bob/learn/tensorflow/trainers/SiameseTrainer.py
@@ -42,6 +42,7 @@ class SiameseTrainer(object):
         self.weight_decay = weight_decay
         self.convergence_threshold = convergence_threshold
 
+
     def train(self, data_shuffler):
         """
         Do the loop forward --> backward --|
@@ -64,10 +65,9 @@ class SiameseTrainer(object):
         train_right_graph = self.architecture.compute_graph(train_placeholder_right_data)
         feature_graph = self.architecture.compute_graph(feature_placeholder, cut=True)
 
-        loss_train, between_class, within_class = self.loss(train_placeholder_labels,
+        loss_train, within_class, between_class = self.loss(train_placeholder_labels,
                                                             train_left_graph,
-                                                            train_right_graph,
-                                                            0.2)
+                                                            train_right_graph)
 
         batch = tf.Variable(0)
         learning_rate = tf.train.exponential_decay(
@@ -76,8 +76,10 @@ class SiameseTrainer(object):
             data_shuffler.train_data.shape[0],
             self.weight_decay  # Decay step
         )
-        optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_train,
-                                                                              global_step=batch)
+        #optimizer = tf.train.GradientDescentOptimizer(learning_rate).minimize(loss_train,
+        #                                                                      global_step=batch)
+        optimizer = tf.train.MomentumOptimizer(learning_rate, momentum=0.99, use_locking=False,
+                                               name='Momentum').minimize(loss_train, global_step=batch)
 
         #train_prediction = tf.nn.softmax(train_graph)
         #validation_prediction = tf.nn.softmax(validation_graph)
@@ -112,5 +114,7 @@ class SiameseTrainer(object):
 
                 if step % self.snapshot == 0:
                     analizer()
+                    print str(step) + " - " + str(analizer.eer[-1])
+
 
-            train_writer.close()
\ No newline at end of file
+            train_writer.close()
-- 
GitLab