-
Notifications
You must be signed in to change notification settings - Fork 11
/
crl_utils.py
68 lines (57 loc) · 2.36 KB
/
crl_utils.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
import numpy as np
import torch
import torch.nn.functional as F
# rank target entropy
def negative_entropy(data, normalize=False, max_value=None):
softmax = F.softmax(data, dim=1)
log_softmax = F.log_softmax(data, dim=1)
entropy = softmax * log_softmax
entropy = -1.0 * entropy.sum(dim=1)
# normalize [0 ~ 1]
if normalize:
normalized_entropy = entropy / max_value
return -normalized_entropy
return -entropy
# correctness history class
class History(object):
def __init__(self, n_data):
self.correctness = np.zeros((n_data))
self.confidence = np.zeros((n_data))
self.max_correctness = 1
# correctness update
def correctness_update(self, data_idx, correctness, output):
probs = torch.nn.functional.softmax(output, dim=1)
confidence, _ = probs.max(dim=1)
data_idx = data_idx.cpu().numpy()
self.correctness[data_idx] += correctness.cpu().numpy()
self.confidence[data_idx] = confidence.cpu().detach().numpy()
# max correctness update
def max_correctness_update(self, epoch):
if epoch > 1:
self.max_correctness += 1
# correctness normalize (0 ~ 1) range
def correctness_normalize(self, data):
data_min = self.correctness.min()
data_max = float(self.max_correctness)
return (data - data_min) / (data_max - data_min)
# get target & margin
def get_target_margin(self, data_idx1, data_idx2):
data_idx1 = data_idx1.cpu().numpy()
cum_correctness1 = self.correctness[data_idx1]
cum_correctness2 = self.correctness[data_idx2]
# normalize correctness values
cum_correctness1 = self.correctness_normalize(cum_correctness1)
cum_correctness2 = self.correctness_normalize(cum_correctness2)
# make target pair
n_pair = len(data_idx1)
target1 = cum_correctness1[:n_pair]
target2 = cum_correctness2[:n_pair]
# calc target
greater = np.array(target1 > target2, dtype='float')
less = np.array(target1 < target2, dtype='float') * (-1)
target = greater + less
target = torch.from_numpy(target).float().cuda()
# calc margin
margin = abs(target1 - target2)
margin = torch.from_numpy(margin).float().cuda()
return target, margin