def _euclidean_squared_distance(input1, input2): """Computes euclidean squared distance. Args: input1 : 2-D feature matrix. input2 : 2-D feature matrix. Returns: distance matrix. """ m, n = input1.shape[0], input2.shape[0] temp1 = math.reduce_sum(math.pow( input1, flow.constant_like(input1, 2, dtype=flow.float32)), axis=1) temp2 = math.reduce_sum(math.pow( input2, flow.constant_like(input2, 2, dtype=flow.float32)), axis=1) shape_tensor1 = flow.constant(value=0.0, dtype=flow.float32, shape=(m, n)) shape_tensor2 = flow.constant(value=0.0, dtype=flow.float32, shape=(n, m)) temp1 = flow.broadcast_like(temp1, like=shape_tensor1, broadcast_axes=[1]) temp2 = flow.transpose(flow.broadcast_like(temp2, like=shape_tensor2, broadcast_axes=[1]), perm=(1, 0)) dismat = math.add(temp1, temp2) return math.add( dismat, math.multiply(-2, flow.matmul(input1, flow.transpose(input2, perm=(1, 0)))))
def build(self, inputs, targets): """ Args: inputs (torch.Tensor): feature matrix with shape (batch_size, feat_dim). targets (torch.LongTensor): ground truth labels with shape (num_classes). """ n = inputs.shape[0] dist = math.reduce_sum(math.pow( inputs, flow.constant_like(inputs, 2, dtype=flow.float32)), axis=1) shape_tensor = flow.constant(value=0.0, dtype=flow.float32, shape=(n, n)) dist = flow.broadcast_like(dist, like=shape_tensor, broadcast_axes=[1]) dist = math.add( dist, flow.transpose(dist, perm=(1, 0), batch_axis_non_change=True)) temp1 = math.multiply( -2, flow.matmul( inputs, flow.transpose(inputs, perm=(1, 0), batch_axis_non_change=True))) dist = math.add(dist, temp1) dist = math.sqrt(flow.clamp(dist, min_value=1e-12)) mask = math.equal( flow.broadcast_like(targets, like=shape_tensor, broadcast_axes=[1]), flow.transpose(flow.broadcast_like(targets, like=shape_tensor, broadcast_axes=[1]), perm=(1, 0), batch_axis_non_change=True)) mask_rev = math.not_equal( flow.broadcast_like(targets, like=shape_tensor, broadcast_axes=[1]), flow.transpose(flow.broadcast_like(targets, like=shape_tensor, broadcast_axes=[1]), perm=(1, 0), batch_axis_non_change=True)) dist_ap, dist_an = [], [] for i in range(n): temp_dist = flow.slice_v2(dist, [(i, i + 1, 1)]) temp_mask = flow.slice_v2(mask, [(i, i + 1, 1)]) temp_mask_rev = flow.slice_v2(mask_rev, [(i, i + 1, 1)]) dist_ap.append( math.reduce_max( flow.gather_nd(temp_dist, flow.where(temp_mask)))) dist_an.append( math.reduce_min( flow.gather_nd(temp_dist, flow.where(temp_mask_rev)))) dist_ap = flow.concat(dist_ap, 0) dist_an = flow.concat(dist_an, 0) y = flow.ones_like(dist_an) # return dist_an, dist_ap, y return self._MarginRankingLoss(dist_an, dist_ap, y)
def _MarginRankingLoss(input1, input2, target, margin = 0, reduction='mean'): low_bound = flow.constant_like(target, 0, dtype= flow.float32) if reduction == 'none': ret = math.maximum(low_bound, math.add(margin,math.multiply(target,math.multiply(-1,math.subtract(input1,input2))))) else: ret = math.reduce_mean(math.maximum(low_bound, math.add(margin,math.multiply(target,math.multiply(-1,math.subtract(input1,input2)))))) return ret
def _MarginRankingLoss(self, input1, input2, target, reduction='mean'): if reduction == 'none': ret = flow.clip( math.add(self.margin, math.multiply(target, math.multiply(-1, math.subtract(input1, input2)))), min_value=0) else: ret = math.reduce_mean(flow.clip( math.add(self.margin, math.multiply(target, math.multiply(-1, math.subtract(input1, input2)))), min_value=0)) return ret
def forward(self, inputs, label): """ Args: inputs (torch.Tensor): prediction matrix (before softmax) with shape (batch_size, num_classes). targets (torch.LongTensor): ground truth labels with shape (batch_size). Each position contains the label index. """ one_hot_label = flow.one_hot(indices=flow.cast(label, flow.int32), depth=self.num_classes, axis=-1, dtype=flow.float32) log_probs = math.log(flow.nn.softmax(inputs, axis=1)) targets = math.add(math.multiply((1 - self.epsilon), one_hot_label), (self.epsilon / self.num_classes)) temp = math.multiply(log_probs, math.multiply(-1, targets)) temp2 = math.reduce_mean(temp, axis=0) loss = math.reduce_sum(temp2) return loss