-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathproject_utils.py
More file actions
102 lines (78 loc) · 3.31 KB
/
Copy pathproject_utils.py
File metadata and controls
102 lines (78 loc) · 3.31 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
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets, transforms
from torchvision.datasets import MNIST, CIFAR10
from torch.utils.data import Dataset, DataLoader
# OSR Dataset template
class CombinedDataset(Dataset):
def __init__(self, mnist, ood, transform_mnist=None, transform_ood=None):
self.mnist = mnist
self.ood = ood
# transforms could be defined either here or when you init each dataset.
self.transform_mnist = transform_mnist
self.transform_ood = transform_ood
def __len__(self):
# combined length of MNIST and OOD
return len(self.mnist) + len(self.ood)
def __getitem__(self, idx):
if idx < len(self.mnist):
# if index is within the range of MNIST, return MNIST data and label
data, label = self.mnist[idx]
if self.transform_mnist:
data = self.transform_mnist(data)
return data, label
else:
# if index is beyond the range of MNIST, return OOD data and 10 as label
data, _ = self.ood[idx - len(self.mnist)] # adjust index for OOD
if self.transform_ood:
data = self.transform_ood(data)
return data, 10 # OOD label is always 10
def eval_model(model, data_loader, device):
""" Evaluation function for the OSR task.
Given your OSR predictions, comptues the accuracy on MNIST, OOD set and both.
Note - this function does NOT computes the MNIST baseline accruacy.
Returns:
- acc_mnist
- acc_ood
- acc_total
"""
# Ensure model is in evaluation mode
model.eval()
correct_mnist = 0
total_mnist = 0
correct_ood = 0
total_ood = 0
# No need to track gradients for evaluation, saves memory and computations
with torch.no_grad():
for data, labels in data_loader:
data, labels = data.to(device), labels.to(device)
outputs = model(data)
### Modify output if needed ###
# y pred should be a vector of size (N_batch,) -> [5, 2, ..., 10]
# and not one-hot. You can handle this either in your model or here.
# Assuming the model returns an (N_batch, 11) size output
#probas, y_pred = torch.max(outputs, 1)
# Assuming the model retuns the predicted label (N_batch, )
# y_pred = outputs
# Split MNIST and OOD predictions and labels
# Assuming numerical labels, which is MNIST/CIFAR datasets default
# Note: Not one-hot!
mask_mnist = labels < 10
mask_ood = ~mask_mnist
labels_mnist = labels[mask_mnist]
labels_ood = labels[mask_ood]
pred_mnist = outputs[mask_mnist]
pred_ood = outputs[mask_ood]
total_mnist += labels_mnist.size(0)
total_ood += labels_ood.size(0)
correct_mnist += (pred_mnist == labels_mnist).sum().item()
correct_ood += (pred_ood == labels_ood).sum().item()
acc_mnist = correct_mnist / total_mnist
# changed here
if total_ood == 0:
acc_ood = 0
else:
acc_ood = correct_ood / total_ood
acc_total = (correct_mnist + correct_ood) / (total_mnist + total_ood)
return acc_mnist, acc_ood, acc_total