Commit ad6a9bba by Tiago de Freitas Pereira

### Replaced some classes to functions #37 . Still need to update some tests

parent ee32fe3c
Pipeline #13123 failed with stages
in 4 minutes and 35 seconds
 #!/usr/bin/env python # vim: set fileencoding=utf-8 : # @author: Tiago de Freitas Pereira # @date: Wed 10 Aug 2016 16:38 CEST import logging logger = logging.getLogger("bob.learn.tensorflow") import tensorflow as tf from .BaseLoss import BaseLoss from bob.learn.tensorflow.utils import compute_euclidean_distance class TripletAverageLoss(BaseLoss): """ Compute the triplet loss as in Schroff, Florian, Dmitry Kalenichenko, and James Philbin. "Facenet: A unified embedding for face recognition and clustering." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2015. :math:L = sum( |f_a - f_p|^2 - |f_a - f_n|^2 + \lambda) **Parameters** left_feature: First element of the pair right_feature: Second element of the pair label: Label of the pair (0 or 1) margin: Contrastive margin """ def __init__(self, margin=0.1): self.margin = margin def __call__(self, anchor_embedding, positive_embedding, negative_embedding): with tf.name_scope("triplet_loss"): # Normalize anchor_embedding = tf.nn.l2_normalize(anchor_embedding, 1, 1e-10, name="anchor") positive_embedding = tf.nn.l2_normalize(positive_embedding, 1, 1e-10, name="positive") negative_embedding = tf.nn.l2_normalize(negative_embedding, 1, 1e-10, name="negative") anchor_mean = tf.reduce_mean(anchor_embedding, 0) d_positive = tf.reduce_sum(tf.square(tf.subtract(anchor_mean, positive_embedding)), 1) d_negative = tf.reduce_sum(tf.square(tf.subtract(anchor_mean, negative_embedding)), 1) basic_loss = tf.add(tf.subtract(d_positive, d_negative), self.margin) loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0) return loss, tf.reduce_mean(d_negative), tf.reduce_mean(d_positive)
 #!/usr/bin/env python # vim: set fileencoding=utf-8 : # @author: Tiago de Freitas Pereira # @date: Wed 10 Aug 2016 16:38 CEST import logging logger = logging.getLogger("bob.learn.tensorflow") import tensorflow as tf from .BaseLoss import BaseLoss from bob.learn.tensorflow.utils import compute_euclidean_distance class TripletLoss(BaseLoss): def triplet_loss(anchor_embedding, positive_embedding, negative_embedding, margin=5.0): """ Compute the triplet loss as in ... ... @@ -37,26 +35,110 @@ class TripletLoss(BaseLoss): """ def __init__(self, margin=5.0): self.margin = margin with tf.name_scope("triplet_loss"): # Normalize anchor_embedding = tf.nn.l2_normalize(anchor_embedding, 1, 1e-10, name="anchor") positive_embedding = tf.nn.l2_normalize(positive_embedding, 1, 1e-10, name="positive") negative_embedding = tf.nn.l2_normalize(negative_embedding, 1, 1e-10, name="negative") d_positive = tf.reduce_sum(tf.square(tf.subtract(anchor_embedding, positive_embedding)), 1) d_negative = tf.reduce_sum(tf.square(tf.subtract(anchor_embedding, negative_embedding)), 1) basic_loss = tf.add(tf.subtract(d_positive, d_negative), margin) loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0, name=tf.GraphKeys.LOSSES) loss_dict = dict() loss_dict['loss'] = loss loss_dict['between_class'] = tf.reduce_mean(d_negative) loss_dict['within_class'] = tf.reduce_mean(d_positive) return loss_dict def triplet_fisher_loss(anchor_embedding, positive_embedding, negative_embedding): with tf.name_scope("triplet_loss"): # Normalize anchor_embedding = tf.nn.l2_normalize(anchor_embedding, 1, 1e-10, name="anchor") positive_embedding = tf.nn.l2_normalize(positive_embedding, 1, 1e-10, name="positive") negative_embedding = tf.nn.l2_normalize(negative_embedding, 1, 1e-10, name="negative") average_class = tf.reduce_mean(anchor_embedding, 0) average_total = tf.div(tf.add(tf.reduce_mean(anchor_embedding, axis=0),\ tf.reduce_mean(negative_embedding, axis=0)), 2) length = anchor_embedding.get_shape().as_list()[0] dim = anchor_embedding.get_shape().as_list()[1] split_positive = tf.unstack(positive_embedding, num=length, axis=0) split_negative = tf.unstack(negative_embedding, num=length, axis=0) Sw = None Sb = None for s in zip(split_positive, split_negative): positive = s[0] negative = s[1] buffer_sw = tf.reshape(tf.subtract(positive, average_class), shape=(dim, 1)) buffer_sw = tf.matmul(buffer_sw, tf.reshape(buffer_sw, shape=(1, dim))) buffer_sb = tf.reshape(tf.subtract(negative, average_total), shape=(dim, 1)) buffer_sb = tf.matmul(buffer_sb, tf.reshape(buffer_sb, shape=(1, dim))) if Sw is None: Sw = buffer_sw Sb = buffer_sb else: Sw = tf.add(Sw, buffer_sw) Sb = tf.add(Sb, buffer_sb) # Sw = tf.trace(Sw) # Sb = tf.trace(Sb) #loss = tf.trace(tf.div(Sb, Sw)) loss = tf.trace(tf.div(Sw, Sb), name=tf.GraphKeys.LOSSES) return loss, tf.trace(Sb), tf.trace(Sw) def triplet_average_loss(anchor_embedding, positive_embedding, negative_embedding, margin=5.0): """ Compute the triplet loss as in Schroff, Florian, Dmitry Kalenichenko, and James Philbin. "Facenet: A unified embedding for face recognition and clustering." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2015. :math:L = sum( |f_a - f_p|^2 - |f_a - f_n|^2 + \lambda) **Parameters** left_feature: First element of the pair right_feature: Second element of the pair label: Label of the pair (0 or 1) margin: Contrastive margin """ def __call__(self, anchor_embedding, positive_embedding, negative_embedding): with tf.name_scope("triplet_loss"): # Normalize anchor_embedding = tf.nn.l2_normalize(anchor_embedding, 1, 1e-10, name="anchor") positive_embedding = tf.nn.l2_normalize(positive_embedding, 1, 1e-10, name="positive") negative_embedding = tf.nn.l2_normalize(negative_embedding, 1, 1e-10, name="negative") with tf.name_scope("triplet_loss"): # Normalize anchor_embedding = tf.nn.l2_normalize(anchor_embedding, 1, 1e-10, name="anchor") positive_embedding = tf.nn.l2_normalize(positive_embedding, 1, 1e-10, name="positive") negative_embedding = tf.nn.l2_normalize(negative_embedding, 1, 1e-10, name="negative") anchor_mean = tf.reduce_mean(anchor_embedding, 0) d_positive = tf.reduce_sum(tf.square(tf.subtract(anchor_embedding, positive_embedding)), 1) d_negative = tf.reduce_sum(tf.square(tf.subtract(anchor_embedding, negative_embedding)), 1) d_positive = tf.reduce_sum(tf.square(tf.subtract(anchor_mean, positive_embedding)), 1) d_negative = tf.reduce_sum(tf.square(tf.subtract(anchor_mean, negative_embedding)), 1) basic_loss = tf.add(tf.subtract(d_positive, d_negative), self.margin) loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0) basic_loss = tf.add(tf.subtract(d_positive, d_negative), margin) loss = tf.reduce_mean(tf.maximum(basic_loss, 0.0), 0, name=tf.GraphKeys.LOSSES) loss_dict = dict() loss_dict['loss'] = loss loss_dict['between_class'] = tf.reduce_mean(d_negative) loss_dict['within_class'] = tf.reduce_mean(d_positive) return loss, tf.reduce_mean(d_negative), tf.reduce_mean(d_positive) return loss_dict