Feng Wang
commited on
Commit
·
5f8446e
1
Parent(s):
261bf27
fix(evaluator): compat bug and update requirment (#1416)
Browse files- requirements.txt +0 -3
- setup.cfg +2 -2
- yolox/evaluators/coco_evaluator.py +2 -8
- yolox/evaluators/voc_eval.py +5 -7
- yolox/evaluators/voc_evaluator.py +10 -31
- yolox/utils/model_utils.py +2 -1
requirements.txt
CHANGED
@@ -3,14 +3,11 @@ numpy
|
|
3 |
torch>=1.7
|
4 |
opencv_python
|
5 |
loguru
|
6 |
-
scikit-image
|
7 |
tqdm
|
8 |
torchvision
|
9 |
-
Pillow
|
10 |
thop
|
11 |
ninja
|
12 |
tabulate
|
13 |
-
tensorboard
|
14 |
|
15 |
# verified versions
|
16 |
# pycocotools corresponds to https://github.com/ppwwyyxx/cocoapi
|
|
|
3 |
torch>=1.7
|
4 |
opencv_python
|
5 |
loguru
|
|
|
6 |
tqdm
|
7 |
torchvision
|
|
|
8 |
thop
|
9 |
ninja
|
10 |
tabulate
|
|
|
11 |
|
12 |
# verified versions
|
13 |
# pycocotools corresponds to https://github.com/ppwwyyxx/cocoapi
|
setup.cfg
CHANGED
@@ -3,8 +3,8 @@ line_length = 100
|
|
3 |
multi_line_output = 3
|
4 |
balanced_wrapping = True
|
5 |
known_standard_library = setuptools
|
6 |
-
known_third_party = tqdm,loguru
|
7 |
-
known_data_processing = cv2,numpy,scipy,PIL,matplotlib
|
8 |
known_datasets = pycocotools
|
9 |
known_deeplearning = torch,torchvision,caffe2,onnx,apex,timm,thop,torch2trt,tensorrt,openvino,onnxruntime
|
10 |
known_myself = yolox
|
|
|
3 |
multi_line_output = 3
|
4 |
balanced_wrapping = True
|
5 |
known_standard_library = setuptools
|
6 |
+
known_third_party = tqdm,loguru,tabulate
|
7 |
+
known_data_processing = cv2,numpy,scipy,PIL,matplotlib
|
8 |
known_datasets = pycocotools
|
9 |
known_deeplearning = torch,torchvision,caffe2,onnx,apex,timm,thop,torch2trt,tensorrt,openvino,onnxruntime
|
10 |
known_myself = yolox
|
yolox/evaluators/coco_evaluator.py
CHANGED
@@ -114,14 +114,8 @@ class COCOEvaluator:
|
|
114 |
self.per_class_AR = per_class_AR
|
115 |
|
116 |
def evaluate(
|
117 |
-
self,
|
118 |
-
|
119 |
-
distributed=False,
|
120 |
-
half=False,
|
121 |
-
trt_file=None,
|
122 |
-
decoder=None,
|
123 |
-
test_size=None,
|
124 |
-
return_outputs=False
|
125 |
):
|
126 |
"""
|
127 |
COCO average precision (AP) Evaluation. Iterate inference on the test dataset
|
|
|
114 |
self.per_class_AR = per_class_AR
|
115 |
|
116 |
def evaluate(
|
117 |
+
self, model, distributed=False, half=False, trt_file=None,
|
118 |
+
decoder=None, test_size=None, return_outputs=False
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
):
|
120 |
"""
|
121 |
COCO average precision (AP) Evaluation. Iterate inference on the test dataset
|
yolox/evaluators/voc_eval.py
CHANGED
@@ -1,5 +1,4 @@
|
|
1 |
#!/usr/bin/env python3
|
2 |
-
# -*- coding:utf-8 -*-
|
3 |
# Code are based on
|
4 |
# https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py
|
5 |
# Copyright (c) Bharath Hariharan.
|
@@ -13,7 +12,7 @@ import numpy as np
|
|
13 |
|
14 |
|
15 |
def parse_rec(filename):
|
16 |
-
"""
|
17 |
tree = ET.parse(filename)
|
18 |
objects = []
|
19 |
for obj in tree.findall("object"):
|
@@ -35,7 +34,7 @@ def parse_rec(filename):
|
|
35 |
|
36 |
|
37 |
def voc_ap(rec, prec, use_07_metric=False):
|
38 |
-
"""
|
39 |
Compute VOC AP given precision and recall.
|
40 |
If use_07_metric is true, uses the
|
41 |
VOC 07 11 point method (default:False).
|
@@ -92,9 +91,9 @@ def voc_eval(
|
|
92 |
for i, imagename in enumerate(imagenames):
|
93 |
recs[imagename] = parse_rec(annopath.format(imagename))
|
94 |
if i % 100 == 0:
|
95 |
-
print("Reading annotation for {
|
96 |
# save
|
97 |
-
print("Saving cached annotations to {
|
98 |
with open(cachefile, "wb") as f:
|
99 |
pickle.dump(recs, f)
|
100 |
else:
|
@@ -155,8 +154,7 @@ def voc_eval(
|
|
155 |
# union
|
156 |
uni = (
|
157 |
(bb[2] - bb[0] + 1.0) * (bb[3] - bb[1] + 1.0)
|
158 |
-
+ (BBGT[:, 2] - BBGT[:, 0] + 1.0) * (BBGT[:, 3] - BBGT[:, 1] + 1.0)
|
159 |
-
- inters
|
160 |
)
|
161 |
|
162 |
overlaps = inters / uni
|
|
|
1 |
#!/usr/bin/env python3
|
|
|
2 |
# Code are based on
|
3 |
# https://github.com/rbgirshick/py-faster-rcnn/blob/master/lib/datasets/voc_eval.py
|
4 |
# Copyright (c) Bharath Hariharan.
|
|
|
12 |
|
13 |
|
14 |
def parse_rec(filename):
|
15 |
+
"""Parse a PASCAL VOC xml file"""
|
16 |
tree = ET.parse(filename)
|
17 |
objects = []
|
18 |
for obj in tree.findall("object"):
|
|
|
34 |
|
35 |
|
36 |
def voc_ap(rec, prec, use_07_metric=False):
|
37 |
+
"""
|
38 |
Compute VOC AP given precision and recall.
|
39 |
If use_07_metric is true, uses the
|
40 |
VOC 07 11 point method (default:False).
|
|
|
91 |
for i, imagename in enumerate(imagenames):
|
92 |
recs[imagename] = parse_rec(annopath.format(imagename))
|
93 |
if i % 100 == 0:
|
94 |
+
print(f"Reading annotation for {i + 1}/{len(imagenames)}")
|
95 |
# save
|
96 |
+
print(f"Saving cached annotations to {cachefile}")
|
97 |
with open(cachefile, "wb") as f:
|
98 |
pickle.dump(recs, f)
|
99 |
else:
|
|
|
154 |
# union
|
155 |
uni = (
|
156 |
(bb[2] - bb[0] + 1.0) * (bb[3] - bb[1] + 1.0)
|
157 |
+
+ (BBGT[:, 2] - BBGT[:, 0] + 1.0) * (BBGT[:, 3] - BBGT[:, 1] + 1.0) - inters
|
|
|
158 |
)
|
159 |
|
160 |
overlaps = inters / uni
|
yolox/evaluators/voc_evaluator.py
CHANGED
@@ -21,14 +21,7 @@ class VOCEvaluator:
|
|
21 |
VOC AP Evaluation class.
|
22 |
"""
|
23 |
|
24 |
-
def __init__(
|
25 |
-
self,
|
26 |
-
dataloader,
|
27 |
-
img_size,
|
28 |
-
confthre,
|
29 |
-
nmsthre,
|
30 |
-
num_classes,
|
31 |
-
):
|
32 |
"""
|
33 |
Args:
|
34 |
dataloader (Dataloader): evaluate dataloader.
|
@@ -46,13 +39,8 @@ class VOCEvaluator:
|
|
46 |
self.num_images = len(dataloader.dataset)
|
47 |
|
48 |
def evaluate(
|
49 |
-
self,
|
50 |
-
|
51 |
-
distributed=False,
|
52 |
-
half=False,
|
53 |
-
trt_file=None,
|
54 |
-
decoder=None,
|
55 |
-
test_size=None,
|
56 |
):
|
57 |
"""
|
58 |
VOC average precision (AP) Evaluation. Iterate inference on the test dataset
|
@@ -91,9 +79,7 @@ class VOCEvaluator:
|
|
91 |
model(x)
|
92 |
model = model_trt
|
93 |
|
94 |
-
for cur_iter, (imgs, _, info_imgs, ids) in enumerate(
|
95 |
-
progress_bar(self.dataloader)
|
96 |
-
):
|
97 |
with torch.no_grad():
|
98 |
imgs = imgs.type(tensor_type)
|
99 |
|
@@ -127,13 +113,13 @@ class VOCEvaluator:
|
|
127 |
|
128 |
eval_results = self.evaluate_prediction(data_list, statistics)
|
129 |
synchronize()
|
|
|
|
|
130 |
return eval_results
|
131 |
|
132 |
def convert_to_voc_format(self, outputs, info_imgs, ids):
|
133 |
predictions = {}
|
134 |
-
for
|
135 |
-
outputs, info_imgs[0], info_imgs[1], ids
|
136 |
-
):
|
137 |
if output is None:
|
138 |
predictions[int(img_id)] = (None, None, None)
|
139 |
continue
|
@@ -142,9 +128,7 @@ class VOCEvaluator:
|
|
142 |
bboxes = output[:, 0:4]
|
143 |
|
144 |
# preprocessing: resize
|
145 |
-
scale = min(
|
146 |
-
self.img_size[0] / float(img_h), self.img_size[1] / float(img_w)
|
147 |
-
)
|
148 |
bboxes /= scale
|
149 |
|
150 |
cls = output[:, 6]
|
@@ -175,7 +159,6 @@ class VOCEvaluator:
|
|
175 |
)
|
176 |
]
|
177 |
)
|
178 |
-
|
179 |
info = time_info + "\n"
|
180 |
|
181 |
all_boxes = [
|
@@ -196,13 +179,9 @@ class VOCEvaluator:
|
|
196 |
c_dets = torch.cat((bboxes, scores.unsqueeze(1)), dim=1)
|
197 |
all_boxes[j][img_num] = c_dets[mask_c].numpy()
|
198 |
|
199 |
-
sys.stdout.write(
|
200 |
-
"im_eval: {:d}/{:d} \r".format(img_num + 1, self.num_images)
|
201 |
-
)
|
202 |
sys.stdout.flush()
|
203 |
|
204 |
with tempfile.TemporaryDirectory() as tempdir:
|
205 |
-
mAP50, mAP70 = self.dataloader.dataset.evaluate_detections(
|
206 |
-
all_boxes, tempdir
|
207 |
-
)
|
208 |
return mAP50, mAP70, info
|
|
|
21 |
VOC AP Evaluation class.
|
22 |
"""
|
23 |
|
24 |
+
def __init__(self, dataloader, img_size, confthre, nmsthre, num_classes):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
25 |
"""
|
26 |
Args:
|
27 |
dataloader (Dataloader): evaluate dataloader.
|
|
|
39 |
self.num_images = len(dataloader.dataset)
|
40 |
|
41 |
def evaluate(
|
42 |
+
self, model, distributed=False, half=False, trt_file=None,
|
43 |
+
decoder=None, test_size=None, return_outputs=False,
|
|
|
|
|
|
|
|
|
|
|
44 |
):
|
45 |
"""
|
46 |
VOC average precision (AP) Evaluation. Iterate inference on the test dataset
|
|
|
79 |
model(x)
|
80 |
model = model_trt
|
81 |
|
82 |
+
for cur_iter, (imgs, _, info_imgs, ids) in enumerate(progress_bar(self.dataloader)):
|
|
|
|
|
83 |
with torch.no_grad():
|
84 |
imgs = imgs.type(tensor_type)
|
85 |
|
|
|
113 |
|
114 |
eval_results = self.evaluate_prediction(data_list, statistics)
|
115 |
synchronize()
|
116 |
+
if return_outputs:
|
117 |
+
return eval_results, data_list
|
118 |
return eval_results
|
119 |
|
120 |
def convert_to_voc_format(self, outputs, info_imgs, ids):
|
121 |
predictions = {}
|
122 |
+
for output, img_h, img_w, img_id in zip(outputs, info_imgs[0], info_imgs[1], ids):
|
|
|
|
|
123 |
if output is None:
|
124 |
predictions[int(img_id)] = (None, None, None)
|
125 |
continue
|
|
|
128 |
bboxes = output[:, 0:4]
|
129 |
|
130 |
# preprocessing: resize
|
131 |
+
scale = min(self.img_size[0] / float(img_h), self.img_size[1] / float(img_w))
|
|
|
|
|
132 |
bboxes /= scale
|
133 |
|
134 |
cls = output[:, 6]
|
|
|
159 |
)
|
160 |
]
|
161 |
)
|
|
|
162 |
info = time_info + "\n"
|
163 |
|
164 |
all_boxes = [
|
|
|
179 |
c_dets = torch.cat((bboxes, scores.unsqueeze(1)), dim=1)
|
180 |
all_boxes[j][img_num] = c_dets[mask_c].numpy()
|
181 |
|
182 |
+
sys.stdout.write(f"im_eval: {img_num + 1}/{self.num_images} \r")
|
|
|
|
|
183 |
sys.stdout.flush()
|
184 |
|
185 |
with tempfile.TemporaryDirectory() as tempdir:
|
186 |
+
mAP50, mAP70 = self.dataloader.dataset.evaluate_detections(all_boxes, tempdir)
|
|
|
|
|
187 |
return mAP50, mAP70, info
|
yolox/utils/model_utils.py
CHANGED
@@ -8,7 +8,6 @@ from typing import Sequence
|
|
8 |
|
9 |
import torch
|
10 |
import torch.nn as nn
|
11 |
-
from thop import profile
|
12 |
|
13 |
__all__ = [
|
14 |
"fuse_conv_and_bn",
|
@@ -21,6 +20,8 @@ __all__ = [
|
|
21 |
|
22 |
|
23 |
def get_model_info(model: nn.Module, tsize: Sequence[int]) -> str:
|
|
|
|
|
24 |
stride = 64
|
25 |
img = torch.zeros((1, 3, stride, stride), device=next(model.parameters()).device)
|
26 |
flops, params = profile(deepcopy(model), inputs=(img,), verbose=False)
|
|
|
8 |
|
9 |
import torch
|
10 |
import torch.nn as nn
|
|
|
11 |
|
12 |
__all__ = [
|
13 |
"fuse_conv_and_bn",
|
|
|
20 |
|
21 |
|
22 |
def get_model_info(model: nn.Module, tsize: Sequence[int]) -> str:
|
23 |
+
from thop import profile
|
24 |
+
|
25 |
stride = 64
|
26 |
img = torch.zeros((1, 3, stride, stride), device=next(model.parameters()).device)
|
27 |
flops, params = profile(deepcopy(model), inputs=(img,), verbose=False)
|