-
Notifications
You must be signed in to change notification settings - Fork 104
/
eval_model.py
111 lines (92 loc) · 3.67 KB
/
eval_model.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
import torch
import pandas as pd
import cxr_dataset as CXR
from torchvision import transforms, utils
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
import sklearn
import sklearn.metrics as sklm
from torch.autograd import Variable
import numpy as np
def make_pred_multilabel(data_transforms, model, PATH_TO_IMAGES):
"""
Gives predictions for test fold and calculates AUCs using previously trained model
Args:
data_transforms: torchvision transforms to preprocess raw images; same as validation transforms
model: densenet-121 from torchvision previously fine tuned to training data
PATH_TO_IMAGES: path at which NIH images can be found
Returns:
pred_df: dataframe containing individual predictions and ground truth for each test image
auc_df: dataframe containing aggregate AUCs by train/test tuples
"""
# calc preds in batches of 16, can reduce if your GPU has less RAM
BATCH_SIZE = 16
# set model to eval mode; required for proper predictions given use of batchnorm
model.train(False)
# create dataloader
dataset = CXR.CXRDataset(
path_to_images=PATH_TO_IMAGES,
fold="test",
transform=data_transforms['val'])
dataloader = torch.utils.data.DataLoader(
dataset, BATCH_SIZE, shuffle=False, num_workers=8)
size = len(dataset)
# create empty dfs
pred_df = pd.DataFrame(columns=["Image Index"])
true_df = pd.DataFrame(columns=["Image Index"])
# iterate over dataloader
for i, data in enumerate(dataloader):
inputs, labels, _ = data
inputs, labels = Variable(inputs.cuda()), Variable(labels.cuda())
true_labels = labels.cpu().data.numpy()
batch_size = true_labels.shape
outputs = model(inputs)
probs = outputs.cpu().data.numpy()
# get predictions and true values for each item in batch
for j in range(0, batch_size[0]):
thisrow = {}
truerow = {}
thisrow["Image Index"] = dataset.df.index[BATCH_SIZE * i + j]
truerow["Image Index"] = dataset.df.index[BATCH_SIZE * i + j]
# iterate over each entry in prediction vector; each corresponds to
# individual label
for k in range(len(dataset.PRED_LABEL)):
thisrow["prob_" + dataset.PRED_LABEL[k]] = probs[j, k]
truerow[dataset.PRED_LABEL[k]] = true_labels[j, k]
pred_df = pred_df.append(thisrow, ignore_index=True)
true_df = true_df.append(truerow, ignore_index=True)
if(i % 10 == 0):
print(str(i * BATCH_SIZE))
auc_df = pd.DataFrame(columns=["label", "auc"])
# calc AUCs
for column in true_df:
if column not in [
'Atelectasis',
'Cardiomegaly',
'Effusion',
'Infiltration',
'Mass',
'Nodule',
'Pneumonia',
'Pneumothorax',
'Consolidation',
'Edema',
'Emphysema',
'Fibrosis',
'Pleural_Thickening',
'Hernia']:
continue
actual = true_df[column]
pred = pred_df["prob_" + column]
thisrow = {}
thisrow['label'] = column
thisrow['auc'] = np.nan
try:
thisrow['auc'] = sklm.roc_auc_score(
actual.as_matrix().astype(int), pred.as_matrix())
except BaseException:
print("can't calculate auc for " + str(column))
auc_df = auc_df.append(thisrow, ignore_index=True)
pred_df.to_csv("results/preds.csv", index=False)
auc_df.to_csv("results/aucs.csv", index=False)
return pred_df, auc_df