-
Notifications
You must be signed in to change notification settings - Fork 0
/
callback.py
104 lines (78 loc) · 3.18 KB
/
callback.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
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
103
104
from sklearn.metrics import confusion_matrix, f1_score, fbeta_score, cohen_kappa_score
from catalyst.dl import AccuracyCallback, MetricCallback, State, Callback, CriterionCallback, OptimizerCallback
from pytorch_toolbelt.utils.torch_utils import to_numpy
from catalyst.core.callback import Callback, CallbackOrder
from scipy.special import softmax
import torch
import torch.nn.functional as F
from torch import nn
import numpy as np
from loss import IoUOneExample
import math
# custom function
def sigmoid(x):
return 1 / (1 + math.exp(-x))
# define vectorized sigmoid
sigmoid_v = np.vectorize(sigmoid)
class MyAccuracyCallback(Callback):
def __init__(self,
input_key: str = "targets",
output_key: str = "logits",
prefix: str = "accuracy01"):
"""
:param input_key: input key to use for precision calculation; specifies our `y_true`.
:param output_key: output key to use for precision calculation; specifies our `y_pred`.
"""
super().__init__(CallbackOrder.metric)
self.prefix = prefix
self.output_key = output_key
self.input_key = input_key
self.sum_correct = 0
self.count = 0
def on_loader_start(self, state):
self.sum_correct = 0
self.count = 0
def on_batch_end(self, state):
targets = state.input[self.input_key].detach()
outputs = state.output[self.output_key].detach()
targets = np.array(targets[:, 0].cpu())
outputs = outputs[:, 0]
outputs = np.array([1 if a > 0.5 else 0 for a in outputs])
self.sum_correct += int((targets == outputs).sum())
self.count += targets.shape[0]
def on_loader_end(self, state: State):
state.loader_metrics[self.prefix] = self.sum_correct / self.count
def IoUAll(pred, target):
n = len(pred)
iou = 0
for i in range(n):
iou += IoUOneExample(sigmoid_v(pred[i]), target[i])
return iou / n
class IoUCallback(Callback):
def __init__(self,
input_key: str = "targets",
output_key: str = "logits",
prefix: str = "IoU"):
"""
:param input_key: input key to use for precision calculation; specifies our `y_true`.
:param output_key: output key to use for precision calculation; specifies our `y_pred`.
"""
super().__init__(CallbackOrder.metric)
self.prefix = prefix
self.output_key = output_key
self.input_key = input_key
self.targets = []
self.predictions = []
def on_loader_start(self, state):
self.targets = []
self.predictions = []
def on_batch_end(self, state):
targets = to_numpy(state.input[self.input_key].detach())
outputs = to_numpy(state.output[self.output_key].detach())
self.targets.extend(targets[:, 1:])
self.predictions.extend(outputs[:, 1:])
def on_loader_end(self, state: State):
# predictions = to_numpy(self.predictions)
# predictions = np.argmax(predictions, axis=1)
score = IoUAll(self.predictions, self.targets)
state.loader_metrics[self.prefix] = float(score)