-
Notifications
You must be signed in to change notification settings - Fork 12
/
loss.py
38 lines (29 loc) · 1.19 KB
/
loss.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from util import *
def euclidean_metric(a, b):
n = a.shape[0]
m = b.shape[0]
a = a.unsqueeze(1).expand(n, m, -1)
b = b.unsqueeze(0).expand(n, m, -1)
logits = -((a - b)**2).sum(dim=2)
return logits
class BoundaryLoss(nn.Module):
def __init__(self, num_labels=10, feat_dim=2):
super(BoundaryLoss, self).__init__()
self.num_labels = num_labels
self.feat_dim = feat_dim
self.delta = nn.Parameter(torch.randn(num_labels).cuda())
nn.init.normal_(self.delta)
def forward(self, pooled_output, centroids, labels):
logits = euclidean_metric(pooled_output, centroids)
probs, preds = F.softmax(logits.detach(), dim=1).max(dim=1)
delta = F.softplus(self.delta)
c = centroids[labels]
d = delta[labels]
x = pooled_output
euc_dis = torch.norm(x - c,2, 1).view(-1)
pos_mask = (euc_dis > d).type(torch.cuda.FloatTensor)
neg_mask = (euc_dis < d).type(torch.cuda.FloatTensor)
pos_loss = (euc_dis - d) * pos_mask
neg_loss = (d - euc_dis) * neg_mask
loss = pos_loss.mean() + neg_loss.mean()
return loss, delta