forked from CoinCheung/pytorch-loss
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathohem_loss.py
79 lines (60 loc) · 2.46 KB
/
ohem_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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#!/usr/bin/python
# -*- encoding: utf-8 -*-
import torch
import torch.nn as nn
import torch.nn.functional as F
import ohem_cpp
from .large_margin_softmax import LargeMarginSoftmaxV3
class OhemCELoss(nn.Module):
def __init__(self, score_thresh, n_min=None, ignore_index=255):
super(OhemCELoss, self).__init__()
self.score_thresh = score_thresh
self.ignore_lb = ignore_index
self.n_min = n_min
self.criteria = nn.CrossEntropyLoss(ignore_index=ignore_index, reduction='mean')
def forward(self, logits, labels):
n_min = labels.numel() // 16 if self.n_min is None else self.n_min
labels = ohem_cpp.score_ohem_label(logits, labels,
self.ignore_lb, self.score_thresh, n_min).detach()
loss = self.criteria(logits, labels)
return loss
class OhemLargeMarginLoss(nn.Module):
def __init__(self, score_thresh, n_min=None, ignore_index=255):
super(OhemLargeMarginLoss, self).__init__()
self.score_thresh = score_thresh
self.ignore_lb = ignore_index
self.n_min = n_min
self.criteria = LargeMarginSoftmaxV3(
ignore_index=ignore_index, reduction='mean')
def forward(self, logits, labels):
n_min = labels.numel() // 16 if self.n_min is None else self.n_min
labels = ohem_cpp.score_ohem_label(logits, labels,
self.ignore_lb, self.score_thresh, n_min).detach()
loss = self.criteria(logits, labels)
return loss
if __name__ == '__main__':
criteria1 = OhemLargeMarginLoss(score_thresh=0.7, n_min=16*20*20//16).cuda()
criteria2 = OhemCELoss(score_thresh=0.7, n_min=16*20*20//16).cuda()
net1 = nn.Sequential(
nn.Conv2d(3, 19, kernel_size=3, stride=2, padding=1),
)
net1.cuda()
net1.train()
net2 = nn.Sequential(
nn.Conv2d(3, 19, kernel_size=3, stride=2, padding=1),
)
net2.cuda()
net2.train()
with torch.no_grad():
inten = torch.randn(16, 3, 20, 20).cuda()
lbs = torch.randint(0, 19, [16, 20, 20]).cuda()
lbs[1, 10, 10] = 255
torch.autograd.set_detect_anomaly(True)
logits1 = net1(inten)
logits1 = F.interpolate(logits1, inten.size()[2:], mode='bilinear', align_corners=True)
logits2 = net2(inten)
logits2 = F.interpolate(logits2, inten.size()[2:], mode='bilinear', align_corners=True)
loss1 = criteria1(logits1, lbs)
loss2 = criteria2(logits2, lbs.clone())
loss = loss1 + loss2
loss.backward()