ssd.pytorchのVOC07メトリックでのmAPを検証してみた


https://github.com/amdegroot/ssd.pytorch のeval.pyについて検証してみました。
VOC2007のメトリック(11 point metric)で公式のツールと比較した結果、次の修正を行うことでより近い値になることが確認できました。

```python:eval.py(diff)
        splitlines = [x.strip().split(' ') for x in lines]
        image_ids = [x[0] for x in splitlines]
        confidence = np.array([float(x[1]) for x in splitlines])
        BB = np.array([[float(z) for z in x[2:]] for x in splitlines])
        BB = np.array([[float(z) - 1. for z in x[2:]] for x in splitlines])

        # sort by confidence
        sorted_ind = np.argsort(-confidence)
@@ -327,12 +327,12 @@ def voc_eval(detpath,
                iymin = np.maximum(BBGT[:, 1], bb[1])
                ixmax = np.minimum(BBGT[:, 2], bb[2])
                iymax = np.minimum(BBGT[:, 3], bb[3])
-                iw = np.maximum(ixmax - ixmin, 0.)
-                ih = np.maximum(iymax - iymin, 0.)
+                iw = np.maximum(ixmax - ixmin + 1., 0.)
+                ih = np.maximum(iymax - iymin + 1., 0.)
                inters = iw * ih
-                uni = ((bb[2] - bb[0]) * (bb[3] - bb[1]) +
-                       (BBGT[:, 2] - BBGT[:, 0]) *
-                       (BBGT[:, 3] - BBGT[:, 1]) - inters)
+                uni = ((bb[2] - bb[0] + 1.) * (bb[3] - bb[1] + 1.) +
+                       (BBGT[:, 2] - BBGT[:, 0] + 1.) *
+                       (BBGT[:, 3] - BBGT[:, 1] + 1.) - inters)
                overlaps = inters / uni
                ovmax = np.max(overlaps)
                jmax = np.argmax(overlaps)
```

重みとして[ssd300_mAP_77.43_v2.pth](https://s3.amazonaws.com/amdegroot-models/ssd300_mAP_77.43_v2.pth)を使用した場合の結果を示します(使用しているデータはVOC2007のテストデータです)。

|ap	    |MATLAB   |	python(修正後)| python(修正前)|
|-----------|---------|--------------|--------------|
|aeroplane  |	0.8202|	0.8208       |0.8207        |
|bicycle    |	0.8567|	0.8568       |0.8568        |
|bird       |	0.7594|	0.7596       |0.7546        |
|boat       |	0.7006|	0.7005       |0.6952        |
|bottle     |	0.5116|	0.5117       |0.5019        |
|bus        |	0.848 |	0.848        |0.8479        |
|car        |	0.8625|	0.8624       |0.8584        |
|cat        |	0.8732|	0.8734       |0.8734        |
|chair      |	0.6237|	0.6234       |0.6136        |
|cow        |	0.8307|	0.8306       |0.8243        |
|diningtable|	0.7905|	0.7905       |0.7906        |
|dog        |	0.8569|	0.8571       |0.8566        |
|horse      |	0.8714|	0.8714       |0.8714        |
|motorbike  |	0.8405|	0.8403       |0.8403        |
|person     |	0.7951|	0.795        |0.7895        |
|pottedplant|	0.5117|	0.5101       |0.5069        |
|sheep      |	0.7827|	0.7826       |0.7767        |
|sofa       |	0.7894|	0.7894       |0.7894        |
|train      |	0.8616|	0.8623       |0.8623        |
|tvmonitor  |	0.7713|	0.7714       |0.7670        |
|mAP        |	0.7779|	0.7779       |0.7749        |

公式ツールは[Pascal VOC Dataset Mirror](https://pjreddie.com/projects/pascal-voc-dataset-mirror/)のVOC 2007のDevalopment Kitから入手可能です。
僕はMATLABユーザーではないので、octaveをインストールして、ssd.pytorchの結果についてのmAPを計算するように修正して実行しました。

VOC2010からメトリックが変わっていて、一応ssd.pytorchも対応しているのですが、その計算結果については載せていません。VOC2010のメトリックについては[ここ](https://qiita.com/nnabeyang/items/0b39698b1e1085fbaa50)を参照してください。


2020年現在では僕が用意した[nnabeyang/ssd.pytorch](https://github.com/nnabeyang/ssd.pytorch/commit/92ece74d83e6d91b5e39b75476f072d9c3d1b619)のリポジトリのほうが実行が容易かもしれません。mAPのメトリックに対するフラグの追加と、今回の修正も取り込んだ変更をしています。