深層学習／物体検出アルゴリズム

#1.はじめに
　今回は、物体検出アルゴリズムとして、R-CNN, Fast R-CNN, Faster R-CNN, YOLO, SSD, FCN, SegNetについて簡単にまとめる。

#2.評価指標
**1)mAP (mean Average Precision)**
![スクリーンショット 2020-04-16 09.56.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/37ee1105-a518-24eb-7ff2-a27c51f0b0e8.png)
　**mAP**は**ラベルの検出精度**を表します。Precision（適合率）で、検出したラベルの内どれだけ正解だったかを表し、ある区間の平均値を**AP**(Average Precision)、全区間の平均値を**mAP**(mean Average Precision)と言います。

**2)IoU (Intersection over Union)**
![スクリーンショット 2020-04-16 10.04.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/4ddb1826-04dd-d507-0376-8a1505711193.png)
　**IoU**はバウンディングボックスの**位置検出精度**を表します。IoUは、実際画像と予測画像のラップした部分を実際画像＋予測画像で割ったものです。二つの画像が完全に重なっていれば IoU=1、完全にズレている（ラップがない）と IoU＝0 となります。

＊**NMS(non-maximum suppression)**は、IoUを利用して、同じクラスとして認識された重なっている状態の領域を抑制するためのアルゴリズムです。IoU値の閾値を0.3という具合に定め、この閾値よりも大きいものを重複した物体領域の候補として外し、閾値に満たないものは、物体領域の候補として残します。

#3.R-CNN
![スクリーンショット 2020-03-31 18.22.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/5d9140ea-a8d3-ba4f-3c46-e8544bd7687e.png)

R-CNNのアルゴリズムは以下の様です。
1)物体らしさ(Objectness)を見つける既存手法(**Selective Search**)を用いて、画像から領域候補(Region Proposals)を探します(2000個程度)
2)領域候補の領域画像を **全て一定の大きさにリサイズ**して CNNにかけて特徴量を取り出す
3)取り出した特徴量を使って複数の**SVM**によって学習しカテゴリ識別、**回帰**によって正確な領域の推定を行います。

　なお、特徴抽出のCNN, カテゴリ推定のSVMなど各学習の目的ごとに別々に学習させる必要かあります。

#4.Fast R-CNN
![スクリーンショット 2020-03-31 18.23.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/74339a3f-8451-5f52-6cc6-4e72a949048e.png)
　R-CNNの速度を上げるために、識別と領域推定を一括でやりたいわけです。そのため、**multi-task loss** の導入してマルチタスク学習を可能にすると共に、Back Propagationが全層に適用できる様にし単一モデルで統合してトレーニングすることを可能にしました。

#5.Faster R-CNN
　Faster R-CNNはSelective Searchの代わりに**Resion Proposal Network**(RPN)と呼ばれるCNN構造を用いて、物体の候補領域を探し出します。そしてhead部は「物体」と判定された領域について、**RoI Pooling**という手法で固定サイズに変形し、物体のクラスの確率と領域位置を推定します。

　Faster R-CNNは**end-to-end学習**が可能なネットワークアーキテクチャです。

#5.YOLO
![スクリーンショット 2020-03-31 15.25.32.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/2714f297-d529-84c3-c9ac-e52e19358165.png)
　画像を一定の形にリサイズした後n*nのグリッドに分け、グリッドごとにsoftmaxでクラス分類をして大雑把にどこになにがあるかを推定。それと並行して、各セルごとにn個(普通はn=2)ずつバウンディングボックスを推定。2つの情報を統合すると、何がどこにあるかがわかる。最後に non-maximum suppression で候補を絞り込む。そして、IoUが一定以上の領域同士はスコアが最も高いものだけを残しほかを消す。

　YOLOのネットワークアーキテクチャは検出速度は高速だが、画像内のオブジェクト同士が 複数重なっている場合に上手く検出できないという欠点があります。また、その性格上小さい物体の検出が苦手で、回避したい場合は入力画 像を大きくする必要があります。

#6.SSD
![スクリーンショット 2020-03-31 15.28.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/14d854f7-b3ba-bb4c-4710-0719e8b51428.png)
　SSDのアルゴリズムは以下の様です。
1) 1セルごとに**色々なアスペクト比のデフォルトボックス**(基本6個)を使う。 
2) デフォルトボックスを微調整して最終的なbboxを決める(smooth L1)。
3) 段階的に分割数をスケールダウンさせて、色々なサイズのbboxにマッチさせる。

　SSDはデフォルトボックスを予め配置し、さらに段階的に大きくしていく (=分割領域数をスケールダウンする)ことによってYOLOと比べ**小さな物体の検出**を可能にしています。また、色々な大きさのデフォルトボックスを用意することで**アスペクト比の違い**にも強くなると言われています。　

　**Hard negative mining** というテクニックを使っています。デフォルトボックスをたくさん配置したとき、明らかに物体よりは背景(物体がなにもない)部分のほうが圧倒的に多いので、ほとんどのボックスはnegativeになるから、普通に学習すると「すべて背 景領域である」という判定をしても結構損失を下げることができてしまいます。これを回避するために信頼度準にソートして、負例と正例が最大でも3:1 にしかならないような調整をしておくと言うものです。

#7.FCN
![スクリーンショット 2020-04-01 10.12.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/89113bb5-a1d4-bf31-855d-acc811a38f4c.png)
　物体の形を検出するセマンティックセグメンテーションというものがあります。ここからは、その説明です。

　FCN(Fully Convolutional Networks)は、CNNの**最後の全結合層をConvolutionに置き換え**て出力を分類クラスではなく二次元マップに変え、様々なサイズの画像を扱える様にしたアルゴリズムです。CNNでは、プーリング処理により特徴マップはダウンサプリングされ解像度が落ちてしまうためDeconvolution層(逆畳み込み)を追加しています。

　また、**スキップアーキテクチャー**という手法をが採用されています。CNNは畳み込みを繰り返すに連れて画像の高次な特徴を抽出します。一方でローカルな特徴はPoolingを繰り返すに連れて失われていきます。つまり下位のレイヤーはローカルな情報を持ち、上位のレイヤーは高次な特徴を持っているということです。このいいところを両取りしたのがスキップアーキテクチャーです。下位のレイヤーの特徴マップを上位の特徴マップと合流させます。これにより精度の向上が確認されています。

#8.SegNet
![スクリーンショット 2020-04-01 10.31.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/209705/385d90c5-2373-d8e7-0ac3-071026ce256a.png)
　SegNetは、高速・省メモリーを目的に、**FCNの全結合層を全て削除**しEncoder-Decorder構造にしています。また、EnocderのMaxpoolingで採用した値の場所を記録(**Max pooling インデックス**)し、Decorderのupsampling時にその情報を使って位置情報を正確化させています。