-
Notifications
You must be signed in to change notification settings - Fork 64
/
Copy pathutils.py
76 lines (59 loc) · 2.34 KB
/
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
69
70
71
72
73
74
75
76
import numpy as np
import torch
import pandas as pd
import random
import string
# https://github.com/benhamner/Metrics/blob/master/Python/ml_metrics/average_precision.py
def apk(actual, predicted, k=10):
if len(predicted)>k:
predicted = predicted[:k]
score = 0.0
num_hits = 0.0
for i,p in enumerate(predicted):
if p in actual and p not in predicted[:i]:
num_hits += 1.0
score += num_hits / (i+1.0)
if not actual:
return 0.0
return score / min(len(actual), k)
def mapk(actual, predicted, k=10):
return np.mean([apk(a,p,k) for a,p in zip(actual, predicted)])
def map5kfast(preds, targs, k=10):
predicted_idxs = preds.sort(descending=True)[1]
top_5 = predicted_idxs[:, :5]
scores = torch.zeros(len(preds), k).float()
for kk in range(k):
scores[:,kk] = (top_5[:,kk] == targs).float() / float((kk+1))
return scores.max(dim=1)[0].mean()
def map5(preds,targs):
if type(preds) is list:
return torch.cat([map5fast(p, targs, 5).view(1) for p in preds ]).mean()
return map5kfast(preds,targs, 5)
def top_5_preds(preds): return np.argsort(preds.numpy())[:, ::-1][:, :5]
def top_5_pred_labels(preds, classes):
top_5 = top_5_preds(preds)
labels = []
for i in range(top_5.shape[0]):
labels.append(' '.join([classes[idx] for idx in top_5[i]]))
return labels
def create_submission(preds, data, name, classes=None):
if not classes: classes = data.classes
sub = pd.DataFrame({'Image': [path.name for path in data.test_ds.x.items]})
sub['Id'] = top_5_pred_labels(preds, classes)
sub.to_csv(f'subs/{name}.csv.gz', index=False, compression='gzip')
def intersection(preds, targs):
# preds and targs are of shape (bs, 4), pascal_voc format
max_xy = torch.min(preds[:, 2:], targs[:, 2:])
min_xy = torch.max(preds[:, :2], targs[:, :2])
inter = torch.clamp((max_xy - min_xy), min=0)
return inter[:, 0] * inter[:, 1]
def area(boxes):
return ((boxes[:, 2]-boxes[:, 0]) * (boxes[:, 3]-boxes[:, 1]))
def union(preds, targs):
return area(preds) + area(targs) - intersection(preds, targs)
def IoU(preds, targs):
return intersection(preds, targs) / union(preds, targs)
def name(n=10, print_it=True):
name = "".join(random.choice(string.ascii_lowercase) for _ in range(n))
if print_it: print(name)
return name