Skip to content

Commit 1b11fbf

Browse files
authored
[Bug] Fix eval segm multiprocess spawn issue (#2314)
* fix eval segm multiprocess spawn issue * fix wrong indent * change context scope
1 parent 93d66ed commit 1b11fbf

File tree

1 file changed

+40
-47
lines changed
  • src/otx/algorithms/detection/adapters/mmdet/evaluation

1 file changed

+40
-47
lines changed

src/otx/algorithms/detection/adapters/mmdet/evaluation/evaluator.py

Lines changed: 40 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
# See the License for the specific language governing permissions
1515
# and limitations under the License.
1616

17-
from multiprocessing import Pool
17+
import multiprocessing as mp
1818
from typing import Dict, List, Tuple
1919

2020
import mmcv
@@ -300,54 +300,47 @@ def evaluate_mask(self, results, logger, iou_thr):
300300
"""
301301
assert len(results) == len(self.annotation[0]), "number of images should be equal!"
302302
num_imgs = len(results)
303-
pool = Pool(self.nproc) # pylint: disable=consider-using-with
304303
eval_results = []
305-
for class_id in range(self.num_classes):
306-
# get gt and det bboxes of this class
307-
cls_dets, cls_scores = self.get_mask_det_results(results, class_id)
308-
cls_gts = self.annotation[class_id]
309304

310-
# compute tp and fp for each image with multiple processes
311-
tpfpmiou = pool.starmap(
312-
tpfpmiou_func, zip(cls_dets, cls_gts, cls_scores, [iou_thr for _ in range(num_imgs)])
313-
)
314-
tp, fp, miou = tuple(zip(*tpfpmiou)) # pylint: disable=invalid-name
315-
316-
# NOTE: Use the following instead as Coverage could not pick up thread pool func.
317-
# tp, fp, miou = [], [], []
318-
# for i in range(num_imgs):
319-
# _tp, _fp, _miou = tpfpmiou_func(cls_dets[i], cls_gts[i], cls_scores[i], iou_thr)
320-
# tp.append(_tp)
321-
# fp.append(_fp)
322-
# miou.append(_miou)
323-
324-
# sort all det bboxes by score, also sort tp and fp
325-
cls_scores = np.hstack(cls_scores)
326-
num_dets = cls_scores.shape[0]
327-
num_gts = np.sum([len(cls_gts) for cls_gts in cls_gts])
328-
sort_inds = np.argsort(cls_scores)[::-1]
329-
tp = np.hstack(tp)[sort_inds] # pylint: disable=invalid-name
330-
fp = np.hstack(fp)[sort_inds] # pylint: disable=invalid-name
331-
# calculate recall and precision with tp and fp
332-
tp = np.cumsum(tp) # pylint: disable=invalid-name
333-
fp = np.cumsum(fp) # pylint: disable=invalid-name
334-
eps = np.finfo(np.float32).eps
335-
recalls = tp / np.maximum(num_gts, eps)
336-
precisions = tp / np.maximum((tp + fp), eps)
337-
miou = np.mean(np.stack(miou))
338-
# calculate AP
339-
ap = average_precision(recalls, precisions, "area") # pylint: disable=invalid-name
340-
eval_results.append(
341-
{
342-
"num_gts": num_gts,
343-
"num_dets": num_dets,
344-
"recall": recalls,
345-
"precision": precisions,
346-
"ap": ap,
347-
"miou": miou,
348-
}
349-
)
350-
pool.close()
305+
ctx = mp.get_context("spawn")
306+
with ctx.Pool(self.nproc) as p:
307+
for class_id in range(self.num_classes):
308+
# get gt and det bboxes of this class
309+
cls_dets, cls_scores = self.get_mask_det_results(results, class_id)
310+
cls_gts = self.annotation[class_id]
311+
312+
# compute tp and fp for each image with multiple processes
313+
tpfpmiou = p.starmap(
314+
tpfpmiou_func, zip(cls_dets, cls_gts, cls_scores, [iou_thr for _ in range(num_imgs)])
315+
)
316+
tp, fp, miou = tuple(zip(*tpfpmiou)) # pylint: disable=invalid-name
317+
318+
# sort all det bboxes by score, also sort tp and fp
319+
cls_scores = np.hstack(cls_scores)
320+
num_dets = cls_scores.shape[0]
321+
num_gts = np.sum([len(cls_gts) for cls_gts in cls_gts])
322+
sort_inds = np.argsort(cls_scores)[::-1]
323+
tp = np.hstack(tp)[sort_inds] # pylint: disable=invalid-name
324+
fp = np.hstack(fp)[sort_inds] # pylint: disable=invalid-name
325+
# calculate recall and precision with tp and fp
326+
tp = np.cumsum(tp) # pylint: disable=invalid-name
327+
fp = np.cumsum(fp) # pylint: disable=invalid-name
328+
eps = np.finfo(np.float32).eps
329+
recalls = tp / np.maximum(num_gts, eps)
330+
precisions = tp / np.maximum((tp + fp), eps)
331+
miou = np.mean(np.stack(miou))
332+
# calculate AP
333+
ap = average_precision(recalls, precisions, "area") # pylint: disable=invalid-name
334+
eval_results.append(
335+
{
336+
"num_gts": num_gts,
337+
"num_dets": num_dets,
338+
"recall": recalls,
339+
"precision": precisions,
340+
"ap": ap,
341+
"miou": miou,
342+
}
343+
)
351344

352345
metrics = {"mAP": 0.0, "mIoU": 0.0}
353346
mious, aps = [], []

0 commit comments

Comments
 (0)