-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathlosses.py
51 lines (41 loc) · 1.91 KB
/
losses.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
39
40
41
42
43
44
45
46
47
48
49
50
51
import pdb
import torch
import torch.nn as nn
import torch.nn.functional as F
class Loss(nn.Module):
def __init__(self, alpha=0.25, gamma=2.0, beta=1/9, cls_w=1.0, reg_w=2.0, dir_w=0.2):
super().__init__()
self.alpha = 0.25
self.gamma = 2.0
self.cls_w = cls_w
self.reg_w = reg_w
self.dir_w = dir_w
self.smooth_l1_loss = nn.SmoothL1Loss(reduction='none',
beta=beta)
self.dir_cls = nn.CrossEntropyLoss()
def forward(self,
bbox_cls_pred,
bbox_pred,
bbox_dir_cls_pred,
batched_labels,
num_cls_pos,
batched_bbox_reg,
batched_dir_labels):
# Total loss = bbox class loss + regression loss + direction class loss
nclasses = bbox_cls_pred.size(1)
batched_labels = F.one_hot(batched_labels, nclasses + 1)[:, :nclasses].float() # (n, 3)
bbox_cls_pred_sigmoid = torch.sigmoid(bbox_cls_pred)
weights = self.alpha * (1 - bbox_cls_pred_sigmoid).pow(self.gamma) * batched_labels + \
(1 - self.alpha) * bbox_cls_pred_sigmoid.pow(self.gamma) * (1 - batched_labels) # (n, 3)
cls_loss = F.binary_cross_entropy(bbox_cls_pred_sigmoid, batched_labels, reduction='none')
cls_loss = cls_loss * weights
cls_loss = cls_loss.sum() / num_cls_pos
reg_loss = self.smooth_l1_loss(bbox_pred, batched_bbox_reg)
reg_loss = reg_loss.sum() / reg_loss.size(0)
dir_cls_loss = self.dir_cls(bbox_dir_cls_pred, batched_dir_labels)
total_loss = self.cls_w * cls_loss + self.reg_w * reg_loss + self.dir_w * dir_cls_loss
loss_dict={'cls_loss': cls_loss,
'reg_loss': reg_loss,
'dir_cls_loss': dir_cls_loss,
'total_loss': total_loss}
return loss_dict