物体検出の回転は要注意！　回転は楕円で考えよう

[2021年のディープラーニング論文を1人で読むAdvent Calendar](https://qiita.com/advent-calendar/2021/solo-dl-papers)4日目の記事です。今回紹介するのはData Augmentationの回転と物体検出です。画像の回転はData Augmentationでは一般的な方法ですが、**物体検出では思わぬ副作用**があります。物体検出におけるBounding Boxの回転について、問題点を指摘しより正確な回転方法や損失関数を提案、ICCV2021にアクセプトされた論文です。

* タイトル：**Towards Rotation Invariance in Object Detection**
* URL：https://openaccess.thecvf.com/content/ICCV2021/html/Kalra_Towards_Rotation_Invariance_in_Object_Detection_ICCV_2021_paper.html
* 出典：Agastya Kalra, Guy Stoppi, Bradley Brown, Rishav Agarwal, Achuta Kadambi; Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV), 2021, pp. 3530-3540
* プロジェクトページ：https://github.com/akasha-imaging/ICCV2021

## 物体検出の回転は精度が下がる
物体検出のBounding boxは$(x, y, w, h)$という4つのベクトルからなります。これで物体の周辺に四角いBounding Boxを描き、それを予測することが物体検出の目的です。Data Augmentationで画像を回転させる際、物体検出ではBounding Boxも回転させる必要があります。

最も簡単なBounding Boxも回転方法は、四角形の四隅の回転後の座標を求めて最大・最小を求めることです。この論文では**Largest Box**と呼んでいます。以前自分もこの方法でやっていました。

例えば、Bounding Boxの四隅の座標が

$$(x_1, y_1), (x_2, y_2), (x_3, y_3), (x_4, y_4)$$

とします。回転後の四隅の座標を

$$(x_1', y_1'), (x_2', y_2'), (x_3', y_3'), (x_4', y_4')$$

とします。実際の$x_1', y_1', \cdots$は回転行列を使って計算します。回転後の新しいBounding Boxは、

* 左上が$(\min(x_1, \cdots, x_4), \min(y_1, \cdots, y_4))$
* 右下が$(\max(x_1, \cdots, x_4), \max(y_1, \cdots, y_4))$

![04_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/cb517930-ff35-0825-9ee4-87f70025118d.png)

とするのがLargest Boxです。ところがこの方法は余計な隙間を生み出すことになります。この**隙間が物体検出の訓練において敵対的に働いてしまい、精度を下げている**という主張が本論文の趣旨です。実際にMS COCOで訓練してみると、

![04_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/87ab9696-8a31-d19d-b185-0a5a2b4ef4de.png)

COCOのテストデータを20°回転させて評価しています。Largest BoxでAugmentationすると、**しない場合と比べてAP75が20以上も下がってしまいました**。これは大問題です。（おそらくLargest Boxを使用している）FastAIではAugmentationにおいて3°以下の回転を推奨しているそうです。

一方で提案手法だと回転のAugmentationを入れても、何もしない場合と比べてAP50，75ともに上昇していることが確認できます。

この図のPerfect Rotation Labelsというのは、回転後の画像に対してラベル付けしたものですが、これは追加のデータやアノテーションが必要になります。AP50ではPerfect Rotationにかなり近い値が出ています。

## 楕円として考える
Largest Boxの問題点は単純なアプローチで解決できます。**Bouding Boxを楕円として考えて回転する**ことです。

![04_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/1e30af57-f055-7986-29a1-5673b3d2034b.png)

楕円なので**Ellipse Box**と呼んでいます。実装上は次のようになります。楕円上の点は、Bouding Boxを中心とした極座標を考えて、任意の角度で点をサンプリングします（これは論文の補助資料にかかれていた内容です）。

![04_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/18533bfa-dbc7-53ab-b240-1e03b53d50e7.png)

回転前の四隅の回転ではなく、**回転前のBouding Boxに内接する楕円を考えて、その円周上の点を回転させて新たなBouding Boxを作る**という処理です。コードの変更量は非常に少ないのもメリットですね。

この例では1°単位でサンプリングしていますが、計算量が気になるならもう少しサンプリング間隔を開けてもいいかもしれません。

実際に15°～30°回転させて、ラベルのAverage Precisionの理論値を計算してみると、

![04_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/69145897-d888-2f76-414e-c9aa84d7b018.png)

楕円で考えたほうがLargest BoxよりもAPの減衰が遅いことがわかります。AP50なら40°回転させてもほとんど減衰せず、AP75なら最大で3倍近くの改善になっています。

![04_07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/603f7c18-7475-9b96-2001-09548abc19d8.png)

また、IoUの理論値と実際のmAPは強く連動します。楕円以外の例として、**八角形やダイヤモンドなどを試したが、結局楕円が一番良かった**とのことです。

## Rotation Uncertainty Loss
楕円による回転の他に、回転の不確実性を考慮した、独自の損失関数を作っています。これは、回転角度が45°、135°、……がもっとも回転の不確実性が高くなることを考慮し、

![04_06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/2fea8e4e-87e2-ce5d-7aa8-5f802a43f867.png)

という$C(\theta)$を考えます。$\theta$はData Augmentationの回転角、$\delta$はハイパーパラメータです。これは回転の信頼性をあらわし、図示すると上のとおりです。**回転角が0°のときは最も信頼性が高いので、この値が1となります。Augmentationの回転角が上がっていくと回転の信頼性が下がっていきます**。

これを損失関数$l_{reg}$の**スレッショルド**として使います。$l_{reg}$とは物体検出の損失関数の1つの項で、予測と実際のBounding Boxの差を回帰問題で定義します。

![04_08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/b8998a54-34ef-83ce-450e-538dcf5e3437.png)

あるBounding Boxに対し、予測と実際のIoU$IoU(p, g_t)$が$\max(0.5, C(\theta))$より小さければ、$l_{reg}$を足します。そうでなければ、Bounding Boxの位置は正しいとみなして$l_{reg}$は足しません。

通常の損失関数だと、回転角やIoUに関係なく$l_{reg}$を足しますが、IoUがスレッショルドより低いときだけ$l_{reg}$を足すというのがRotation Uncertainty Lossの特徴となっています。これもコードの変更数が少なくてすみます。

![04_09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/ffb9fa41-b7a0-563e-647d-ac6ca0ead7da.png)


実際にCOCOで試してみると、**楕円による回転＋Rotation Uncertainty Loss（$\delta$が10°）が最も良かった**ことが示されました。0°の場合でも楕円やRU Lossがよくなっているので、横軸はData Augmentationの角度ではなく、Valデータの回転角だと思われます。いずれの方法も画像の回転に対してよりロバストになることが示されています。

## 回転に対するロバスト性
訓練時の回転角は平均0、標準偏差15の標準分布の乱数から決めています。

![04_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/f598a3c2-ff28-4a9e-fbb9-2fb96914011e.png)

これを複数のデータセットで実験したのがこちらで、いずれもAPが上がっています。テストデータで回転がない場合でもより正確な判定が可能になり、例えばPascal VOCのようにLargest Boxでは奥のヨットが検出できなかったものの、楕円＋RU Lossでは検出できるようになっています。

![04_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/232088/6b9caeea-a720-869d-6788-3511ecbb0a43.png)

Data Augmentationではなく、テスト時の回転に対するロバスト性も実験しています。この論文の手法で訓練したほうが、**Largest Boxで訓練したときよりテスト時の回転に対してよりロバストになっている**のがわかります。**Largest Boxで訓練すると、回転のAugmentationをしない場合よりも、テスト時の回転に対する性能（特にCOCOのAP75）が落ちる**というのは興味深いです。

実際にテスト時の回転に配慮する必要がある物体検出のアプリケーションでは、この手法を使うメリットは大いにあるでしょう。

## まとめと感想
楕円とRU Lossというシンプルな観点に注目するだけで、これだけの性能をあげられるのはすごいです。「回転をすることが最強のData Augmentation」というわけではないのは注意が必要です。「**最強のData Augmentationを知りたいのなら、Auto Augment等を実施すべきで、本論文のスコープではない**」と文中でも断っています。少なくともData Augmentationにおいて、Largest Boxを使う理由はないということは示せているでしょう。

一方で、テスト時の回転に対するロバスト性を上げるというのはかなり意義がありそうです。道路の固定監視カメラなどはほぼ回転することはなさそうですが、例えば**顕微鏡の画像**のように、どこが0°の基準だかわからないようなデータでは、回転に対するロバスト性は大いに検討する必要があるでしょう。頭の片隅においておくと良さそうな論文だと思います。

## 告知
このアドベントカレンダーが本になりました！
**https://koshian2.booth.pm/items/3595424**
Amazonでも扱いあります詳しくは👉　https://shikoan.com