forked from srivatsansridhar99/TrackNetPytorch
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathgeneral.py
More file actions
105 lines (94 loc) · 4.28 KB
/
Copy pathgeneral.py
File metadata and controls
105 lines (94 loc) · 4.28 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
import torch
import time
import numpy as np
import torch.nn as nn
import cv2
from scipy.spatial import distance
def train(model, train_loader, optimizer, device, epoch, max_iters=200):
start_time = time.time()
losses = []
criterion = nn.CrossEntropyLoss()
for iter_id, batch in enumerate(train_loader):
optimizer.zero_grad()
model.train()
out = model(batch[0].float().to(device))
gt = torch.tensor(batch[1], dtype=torch.long, device=device)
loss = criterion(out, gt)
loss.backward()
optimizer.step()
optimizer.zero_grad()
end_time = time.time()
duration = time.strftime("%H:%M:%S", time.gmtime(end_time - start_time))
print('train | epoch = {}, iter = [{}|{}], loss = {}, time = {}'.format(epoch, iter_id, max_iters,
round(loss.item(), 6), duration))
losses.append(loss.item())
if iter_id > max_iters - 1:
break
return np.mean(losses)
def validate(model, val_loader, device, epoch, min_dist=5):
losses = []
tp = [0, 0, 0, 0]
fp = [0, 0, 0, 0]
tn = [0, 0, 0, 0]
fn = [0, 0, 0, 0]
criterion = nn.CrossEntropyLoss()
model.eval()
for iter_id, batch in enumerate(val_loader):
with torch.no_grad():
out = model(batch[0].float().to(device))
gt = torch.tensor(batch[1], dtype=torch.long, device=device)
loss = criterion(out, gt)
losses.append(loss.item())
# metrics
output = out.argmax(dim=1).detach().cpu().numpy()
for i in range(len(output)):
x_pred, y_pred = postprocess(output[i])
x_gt = batch[2][i]
y_gt = batch[3][i]
vis = batch[4][i]
if x_pred:
if vis != 0:
dst = distance.euclidean((x_pred, y_pred), (x_gt, y_gt))
if dst < min_dist:
tp[vis] += 1
else:
fp[vis] += 1
else:
fp[vis] += 1
if not x_pred:
if vis != 0:
fn[vis] += 1
else:
tn[vis] += 1
print('val | epoch = {}, iter = [{}|{}], loss = {}, tp = {}, tn = {}, fp = {}, fn = {} '.format(epoch,
iter_id,
len(val_loader),
round(np.mean(losses), 6),
sum(tp),
sum(tn),
sum(fp),
sum(fn)))
eps = 1e-15
precision = sum(tp) / (sum(tp) + sum(fp) + eps)
vc1 = tp[1] + fp[1] + tn[1] + fn[1]
vc2 = tp[2] + fp[2] + tn[2] + fn[2]
vc3 = tp[3] + fp[3] + tn[3] + fn[3]
recall = sum(tp) / (vc1 + vc2 + vc3 + eps)
f1 = 2 * precision * recall / (precision + recall + eps)
print('precision = {}'.format(precision))
print('recall = {}'.format(recall))
print('f1 = {}'.format(f1))
return np.mean(losses), precision, recall, f1
def postprocess(feature_map, scale=2):
feature_map *= 255
feature_map = feature_map.reshape((360, 640))
feature_map = feature_map.astype(np.uint8)
ret, heatmap = cv2.threshold(feature_map, 127, 255, cv2.THRESH_BINARY)
circles = cv2.HoughCircles(heatmap, cv2.HOUGH_GRADIENT, dp=1, minDist=1, param1=50, param2=2, minRadius=2,
maxRadius=7)
x,y = None, None
if circles is not None:
if len(circles) == 1:
x = circles[0][0][0]*scale
y = circles[0][0][1]*scale
return x, y