-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathinference.py
More file actions
105 lines (86 loc) · 3.05 KB
/
Copy pathinference.py
File metadata and controls
105 lines (86 loc) · 3.05 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
import argparse
from pathlib import Path
from typing import Union, Any
import numpy as np
import pandas as pd
import torch
from tqdm import tqdm
from nkb_classification.dataset import get_inference_dataset
from nkb_classification.model import get_model
from nkb_classification.utils import load_classes, get_classes_configs, read_py_config
@torch.no_grad()
def inference(
model: torch.nn.Module,
loader: torch.utils.data.DataLoader,
classes: Union[list, dict],
save_path: str,
device: Union[torch.device, str],
cfg: Any
) -> None:
_, idx_to_class = get_classes_configs(classes)
task = cfg.task
assert task in ("single", "multi")
if task == "single":
target_column = cfg.target_column
columns = [target_column]
elif task == "multi":
target_names = cfg.target_names
assert set(target_names) == set(classes.keys())
columns = target_names.copy()
columns.append("path")
inference_annotations = pd.DataFrame(columns=columns)
model.eval()
for imgs, img_paths in tqdm(loader, leave=False, desc="Inference"):
imgs = imgs.float().to(device)
with torch.autocast(
device_type="cuda",
dtype=torch.float16,
enabled=cfg.enable_mixed_presicion,
):
preds = model(imgs)
batch_annotations = []
if task == "single":
pred = preds
pred = pred.argmax(dim=-1).cpu().numpy().tolist()
pred = [idx_to_class[idx] for idx in pred]
batch_annotations.append(pred)
elif task == "multi":
for target_name in target_names:
pred = preds[target_name]
pred = pred.argmax(dim=-1).cpu().numpy().tolist()
pred = [idx_to_class[target_name][idx] for idx in pred]
batch_annotations.append(pred)
batch_annotations.append(list(img_paths))
batch_annotations = np.vstack(batch_annotations).T
inference_annotations = pd.concat(
[
inference_annotations,
pd.DataFrame(batch_annotations, columns=columns),
]
)
inference_annotations.to_csv(Path(save_path, "inference_annotations.csv"), index=False)
def main():
parser = argparse.ArgumentParser(description="Inference arguments")
parser.add_argument(
"-cfg",
"--config",
help="Config file path",
type=str,
default="",
required=True,
)
args = parser.parse_args()
cfg_file = args.config
exec(read_py_config(cfg_file), globals(), globals())
# get dataloader
data_loader = get_inference_dataset(cfg.inference_data, cfg.inference_pipeline)
# load classes config
classes = load_classes(cfg.classes)
# get model
device = torch.device(cfg.device)
model = get_model(cfg.model, classes, device, compile=cfg.compile)
save_path = Path(cfg.save_path)
save_path.mkdir(exist_ok=True, parents=True)
inference(model, data_loader, classes, save_path, device, cfg)
if __name__ == "__main__":
main()