forked from RicardooYoung/LatentDistributionAdjusting
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcontainers.py
117 lines (94 loc) · 2.5 KB
/
containers.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
105
106
107
108
109
110
111
112
113
114
115
116
117
from dataclasses import dataclass
from typing import Any
import torch
@dataclass
class Rect2i:
"""
Rectangle. Analagous to OpenCV Rect2i
"""
x: int
y: int
width: int
height: int
@property
def x1(self) -> int:
return int(self.x)
@property
def x2(self) -> int:
return int(self.x + self.width)
@property
def y1(self) -> int:
return int(self.y)
@property
def y2(self) -> int:
return int(self.y + self.height)
@property
def left(self) -> int:
return self.x
@property
def top(self) -> int:
return self.y
@property
def right(self) -> int:
return int(self.x + self.width)
@property
def bottom(self) -> int:
return int(self.y + self.height)
@property
def area(self) -> int:
return int(self.width * self.height)
@dataclass
class ClassificationMetrics:
precision: float = 0.0
recall: float = 0.0 # == sensitivity
specificity: float = 0.0
f1: float = 0.0
f3: float = 0.0
apcer: float = 0.0
bpcer: float = 0.0
acer: float = 0.0
far: float = 0.0
frr: float = 0.0
hter: float = 0.0
threshold: float = 0.0
def __repr__(self) -> str:
text = (f"APCER: {self.apcer*100:.2f}%, "
f"BPCER: {self.bpcer*100:.2f}%, "
f"ACER: {self.acer*100:.2f}%, "
f"F1: {self.f1*100:.2f}%, "
f"F3: {self.f3*100:.2f}%, "
f"P: {self.precision*100:.2f}%, "
f"R: {self.recall*100:.2f}%, "
f"S: {self.specificity*100:.2f}%"
)
return text
@dataclass
class PredictionCounters:
tp: int = 0
fp: int = 0
tn: int = 0
fn: int = 0
def __add__(self, other):
return PredictionCounters(
tp = self.tp + other.tp,
fp = self.fp + other.fp,
tn = self.tn + other.tn,
fn = self.fn + other.fn
)
def as_tensor(self) -> torch.Tensor:
return torch.Tensor((self.tp, self.fp, self.tn, self.fn))
@staticmethod
def from_tensor(tensor: torch.Tensor):
assert len(tensor) == 4
return PredictionCounters(
tp = tensor[0],
fp = tensor[1],
tn = tensor[2],
fn = tensor[3]
)
@dataclass
class BestMetric:
value: float
epoch: int
def __call__(self) -> float:
return self.value