forked from arimousa/DDAD
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmetrics.py
More file actions
executable file
·116 lines (93 loc) · 4.83 KB
/
metrics.py
File metadata and controls
executable file
·116 lines (93 loc) · 4.83 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
103
104
105
106
107
108
109
110
111
112
113
114
115
import torch
from torchmetrics import ROC, AUROC, F1Score
import os
from torchvision.transforms import transforms
from skimage import measure
import pandas as pd
from statistics import mean
import numpy as np
from sklearn.metrics import auc
from sklearn import metrics
from sklearn.metrics import roc_auc_score, roc_curve
class Metric:
def __init__(self,labels_list, predictions, anomaly_map_list, gt_list, config) -> None:
self.labels_list = labels_list
self.predictions = predictions
self.anomaly_map_list = anomaly_map_list
self.gt_list = gt_list
self.config = config
self.threshold = 0.5
def image_auroc(self):
auroc_image = roc_auc_score(self.labels_list, self.predictions)
return auroc_image
def pixel_auroc(self):
resutls_embeddings = self.anomaly_map_list[0]
for feature in self.anomaly_map_list[1:]:
resutls_embeddings = torch.cat((resutls_embeddings, feature), 0)
resutls_embeddings = ((resutls_embeddings - resutls_embeddings.min())/ (resutls_embeddings.max() - resutls_embeddings.min()))
gt_embeddings = self.gt_list[0]
for feature in self.gt_list[1:]:
gt_embeddings = torch.cat((gt_embeddings, feature), 0)
resutls_embeddings = resutls_embeddings.clone().detach().requires_grad_(False)
gt_embeddings = gt_embeddings.clone().detach().requires_grad_(False)
auroc_p = AUROC(task="binary")
gt_embeddings = torch.flatten(gt_embeddings).type(torch.bool).cpu().detach()
resutls_embeddings = torch.flatten(resutls_embeddings).cpu().detach()
auroc_pixel = auroc_p(resutls_embeddings, gt_embeddings)
return auroc_pixel
def optimal_threshold(self):
fpr, tpr, thresholds = roc_curve(self.labels_list, self.predictions)
# Calculate Youden's J statistic for each threshold
youden_j = tpr - fpr
# Find the optimal threshold that maximizes Youden's J statistic
optimal_threshold_index = np.argmax(youden_j)
optimal_threshold = thresholds[optimal_threshold_index]
self.threshold = optimal_threshold
return optimal_threshold
def pixel_pro(self):
#https://github.com/hq-deng/RD4AD/blob/main/test.py#L337
def _compute_pro(masks, amaps, num_th = 200):
resutls_embeddings = amaps[0]
for feature in amaps[1:]:
resutls_embeddings = torch.cat((resutls_embeddings, feature), 0)
amaps = ((resutls_embeddings - resutls_embeddings.min())/ (resutls_embeddings.max() - resutls_embeddings.min()))
amaps = amaps.squeeze(1)
amaps = amaps.cpu().detach().numpy()
gt_embeddings = masks[0]
for feature in masks[1:]:
gt_embeddings = torch.cat((gt_embeddings, feature), 0)
masks = gt_embeddings.squeeze(1).cpu().detach().numpy()
min_th = amaps.min()
max_th = amaps.max()
delta = (max_th - min_th) / num_th
binary_amaps = np.zeros_like(amaps)
df = pd.DataFrame([], columns=["pro", "fpr", "threshold"])
for th in np.arange(min_th, max_th, delta):
binary_amaps[amaps <= th] = 0
binary_amaps[amaps > th] = 1
pros = []
for binary_amap, mask in zip(binary_amaps, masks):
for region in measure.regionprops(measure.label(mask)):
axes0_ids = region.coords[:, 0]
axes1_ids = region.coords[:, 1]
tp_pixels = binary_amap[axes0_ids, axes1_ids].sum()
pros.append(tp_pixels / region.area)
inverse_masks = 1 - masks
fp_pixels = np.logical_and(inverse_masks , binary_amaps).sum()
fpr = fp_pixels / inverse_masks.sum()
# print(f"Threshold: {th}, FPR: {fpr}, PRO: {mean(pros)}")
df = pd.concat([df, pd.DataFrame({"pro": mean(pros), "fpr": fpr, "threshold": th}, index=[0])], ignore_index=True)
# df = df.concat({"pro": mean(pros), "fpr": fpr, "threshold": th}, ignore_index=True)
# Normalize FPR from 0 ~ 1 to 0 ~ 0.3
df = df[df["fpr"] < 0.3]
df["fpr"] = df["fpr"] / df["fpr"].max()
pro_auc = auc(df["fpr"], df["pro"])
return pro_auc
pro = _compute_pro(self.gt_list, self.anomaly_map_list, num_th = 200)
return pro
def miscalssified(self):
predictions = torch.tensor(self.predictions)
labels_list = torch.tensor(self.labels_list)
predictions0_1 = (predictions > self.threshold).int()
for i,(l,p) in enumerate(zip(labels_list, predictions0_1)):
print('Sample : ', i, ' predicted as: ',p.item() ,' label is: ',l.item(),'\n' ) if l != p else None