summaryrefslogtreecommitdiff
path: root/utils/triplet_loss.py
diff options
context:
space:
mode:
Diffstat (limited to 'utils/triplet_loss.py')
-rw-r--r--utils/triplet_loss.py36
1 files changed, 0 insertions, 36 deletions
diff --git a/utils/triplet_loss.py b/utils/triplet_loss.py
deleted file mode 100644
index 954def2..0000000
--- a/utils/triplet_loss.py
+++ /dev/null
@@ -1,36 +0,0 @@
-import torch
-import torch.nn as nn
-import torch.nn.functional as F
-
-
-class BatchAllTripletLoss(nn.Module):
- def __init__(self, margin: float = 0.2):
- super().__init__()
- self.margin = margin
-
- def forward(self, x, y):
- p, n, c = x.size()
-
- # Euclidean distance p x n x n
- x_squared_sum = torch.sum(x ** 2, dim=2)
- x1_squared_sum = x_squared_sum.unsqueeze(2)
- x2_squared_sum = x_squared_sum.unsqueeze(1)
- x1_times_x2_sum = x @ x.transpose(1, 2)
- dist = torch.sqrt(
- F.relu(x1_squared_sum - 2 * x1_times_x2_sum + x2_squared_sum)
- )
-
- hard_positive_mask = y.unsqueeze(1) == y.unsqueeze(2)
- hard_negative_mask = y.unsqueeze(1) != y.unsqueeze(2)
- all_hard_positive = dist[hard_positive_mask].view(p, n, -1, 1)
- all_hard_negative = dist[hard_negative_mask].view(p, n, 1, -1)
- positive_negative_dist = all_hard_positive - all_hard_negative
- all_loss = F.relu(self.margin + positive_negative_dist).view(p, -1)
-
- # Non-zero parted mean
- non_zero_counts = (all_loss != 0).sum(1)
- parted_loss_mean = all_loss.sum(1) / non_zero_counts
- parted_loss_mean[non_zero_counts == 0] = 0
-
- loss = parted_loss_mean.mean()
- return loss