from __future__ import absolute_import from __future__ import division from __future__ import print_function import paddle.fluid as fluid class TripletLoss(): def __init__(self, margin=0.1): self.margin = margin def loss(self, input, label=None): margin = self.margin fea_dim = input.shape[1] # number of channels #input = fluid.layers.l2_normalize(input, axis=1) input_norm = fluid.layers.sqrt(fluid.layers.reduce_sum(fluid.layers.square(input), dim=1)) input = fluid.layers.elementwise_div(input, input_norm, axis=0) output = fluid.layers.reshape(input, shape = [-1, 3, fea_dim]) anchor, positive, negative = fluid.layers.split(output, num_or_sections = 3, dim = 1) anchor = fluid.layers.reshape(anchor, shape = [-1, fea_dim]) positive = fluid.layers.reshape(positive, shape = [-1, fea_dim]) negative = fluid.layers.reshape(negative, shape = [-1, fea_dim]) a_p = fluid.layers.square(anchor - positive) a_n = fluid.layers.square(anchor - negative) a_p = fluid.layers.reduce_sum(a_p, dim = 1) a_n = fluid.layers.reduce_sum(a_n, dim = 1) #a_p = fluid.layers.sqrt(a_p + 1e-6) #a_n = fluid.layers.sqrt(a_n + 1e-6) loss = fluid.layers.relu(a_p + margin - a_n) return loss