yolo9000を読む

#YOLO9000
[原論文はこちらです。](https://arxiv.org/abs/1612.08242)
YOLO9000を読みます。
introductionは省略します。
全体のまとめが記事の下方にありますので、結果だけ知りたいという方はそちらをご覧になってください。YOLOv2とYOLO9000は同じものなのでしょうか。論文内では区別して書いてあるように感じるのですが、正直よくわかりません。ご存じの方いらっしゃいましたら教えてくださいm(_ _)m


#Better　　
- yoloの誤差を分析したところ、localization error がめっちゃ大きかったそうです。そのうえ、region proposal-basedのモデルと比較するとrecallも低かったそうです。そのため、classification accuracyを維持しながらrecallとlocalization errorを向上させよう！

- 昨今の深層学習モデルのトレンドとしては、より深く、より大きなモデルを構築することとなっている。しかし、yoloモデルはネットワークを簡略化し、速さを維持したまま正確性を上げていく！
- yolov2モデルの速度を維持したまま精度を高めるために様々なアイデアをモデルに適用したようです。
    - **Batch Normalizetion**：Batch Normalizetionは誤差の収束において大きな効力を発揮したそうです。すべての畳み込み層にBatch Normalizationを追加したことでmAPが2%！また、オーバーフィッテングなしにDropoutを取り除くことができたそうです。
    - **High Resolution Classifier**：自分が前回読んだ[yoloのバージョン1の論文](https://arxiv.org/abs/1506.02640)では、モデルは24層の畳み込み層と2層のFC層を持っており、そのうち上層の20層をImageNet 1000-class competition datasetで事前学習させたそうです（画像サイズは224x224）。そして、検出の段階ではサイズ448x448の画像を使用したようです。YOLOv2では初めからclassification networkを448x448の画像で10epoch訓練したそうです。そして、学習したネットワークをファインチューニングしました。こうすることによってネットワークにより高い解像度の画像に対してより良い結果を得られように、ネットワーク自身のフィルターを調整する時間を与えることができるそうです。これによりmAPが4%増加しました。
    - **Convolutional With Anchor Boxes** : yoloは畳み込みを使った特徴抽出器の上層のFC層を使用してバウンディングボックスの座標を直接予測していました。一方、畳み込み層のみで構成されているFaster R-CNNのRPN（Resion Proposal Network）は、anchor boxesに対してoffsets(基準となる値からのズレ、相対位置)とconfidences（物体がボックス中に存在するかどうかを示す値）を予測します。offsetはanchor boxの座標に対するバウンディングボックスの相対位置のことを示しているのだと思います(自身がないのでわかる方教えていただきたいですm(_ _)m)。offsetを予測する方が直接座標を予測するよりも問題を単純に、かつ、訓練を簡単にできるそうです。そのため、yoloモデルからFC層を取り除いてanchorを使うことにしたそうです。また、feature mapを奇数個にしてcenter cell(特徴マップの中心)が欲しかったので入力画像のサイズを416に変更した(上の話どうなってん)。center cellが欲しかった理由は、大きい物体が画像に写っているときを考えるとわかります。大きい物体の中心は多くの場合画像の中心に存在します。そのため、仮に特徴マップが偶数個だった場合、その中心には四つの中心があります（わかりづらいと思うので下図を参照してください）。この状況よりど真ん中にanchor boxの中心がただ一つ存在する方が望ましいため特徴マップを奇数個にしたいみたいです。
![yolo2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/c7990ca9-7d86-0b8d-dae9-f1543b289a96.png)
anchor boxを使うと少しだけ精度が下がったそうです。yoloモデル(多分バージョン１のこと)は画像あたり98のボックスしか予測しなかったのに対し、製作者さまのモデルは1000以上のボックスを予測したそうです。anchor boxの無い中間のモデルはmAP=69.5、recall=81%に対し、anchor boxのあるモデルはmAP=69.2、recall=88%となり、mAPは若干下がったものの、当初の目的であるrecallを改善することができたようです。
    - **Dimension Clusters** : anchorを使用していた時、2つの問題に直面したそうです。1つ目は、anchorの次元(何のことを表しているのかよくわかりません)は手作業で決めなければいけないことです。これは、ネットワークの訓練のしやすさなどを決める大事なファクターになります。そこで、手作業で適当に決めるのではなく、training setのバウンディングボックスにk-means clusteringを適用していいanchorの大きさを決めようではありませんかって感じです。だらだら説明するよりも実装してらっしゃる方がいらっしゃったのでそちらを見るとわかりやすいと思います。[（k-means clustering）](https://lars76.github.io/object-detection/k-means-anchor-boxes/)ここの説明を見た感じ、k-means clusteringを用いて決めるのはanchor boxの大きさやアスペクト比だと思います。![yolo4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/6ed47771-0a27-b04e-046e-1b73c066c514.png)上図の点線からもわかるように、clusterの数は5に決めたそうです。理由は、モデルの複雑さとrecallの兼ね合いだそうです。
   
    - **Direct location prediction** : anchor boxを使う上で、2つ目の問題に直面しました。それは、モデルの不安定性です。特に学習初期段階にそれは起こります。この不安定性はボックスの(x,y)座標を予測することに起因します。region proposal networkはt<sub>x</sub>とt<sub>y</sub>を予測し、これを用いて中心座標(x,y)は

```math
x=(t_x*w_a)-x_a\\
y=(t_y*w_a)-y_a
```

「なんだこのx<sub>a</sub>やらw<sub>a</sub>は！」と思いました。説明されていないんです...
たぶん

```math
x_a = anchorの中心座標のx成分\\
y_a = anchorの中心座標のy成分\\
w_a = anchorの幅\\
h_a = anchorの高さ\\
```

だと思います。添え字あいますし気持ちそうかなって感じです。t<sub>x</sub>=1のとき、右にシフト、t<sub>x</sub>=-1のとき、左にシフトだそうです。「This formulation is unconstrained so any anchor box can end up at any point in the image, regardless of what location predicted the box. 」がようわかりません。「何を予測したかにかかわらず、この式は拘束しない(制限とか？)。だから画像中のどの地点においても、どんなアンカーだろうと終端できる」直訳するとこんな感じですかね？全く意味わからないです。もしこの文の意味が分かる方いらっしゃいましたら教えてくださいm()m。まあ、なんだかんだあって、offsetを予測する代わりにyoloモデルにならってグリッドセルの位置に対する座標を予測することにしたそうです。こうすればground truthを0~1に制限できる。ネットワークの予測をこの範囲に制限するためにロジスティック関数をアクティベーション関数に使用するそうです。ネットワークは5つのバうディングボックスを特徴マップの各cellごとに予測します。さらに、各バウンディングボックスごとにt<sub>x</sub>,t<sub>y</sub>,t<sub>w</sub>,t<sub>h</sub>,t<sub>o</sub>の5つの座標を予測します。セルが（c<sub>x</sub>、c<sub>y</sub>）だけ画像の左上隅からオフセットされ、前の境界ボックスの幅と高さがp<sub>w</sub>、p<sub>h</sub>である場合、予測は

```math
b_x = σ(t_x) + c_x\\
b_y = σ(t_y) + c_y\\
b_w = p_w * e^{t_w}\\
b_h = p_h * e^{t_h}\\
P_r(object) * IoU(b,object) = σ(t_o)
```

yoloでいうところのconfidence scoreをσ(t<sub>o</sub>)にまとめてしまうところが斬新ですね。位置の予測を拘束してしまうことで、ネットワークがより安定して、パラメータ付けが簡単にになったそうです。バウンディングボックスの中心座標を直接求めるのと同時にdimension clusteringを使用すると、yoloのバージョンのanchor boxを使うどのバージョンにおいても5%の向上があったそうです（何が向上したかは書いてないです、もしくは、訳を間違えてます）。
    -　**Fine-Grained Feature** : これによって、yoloモデルの13x13の特徴マップを使用した予測を修正したそうです。13x13の特徴マップを使用することは大きな物体に対しては十分かもしれないけど、より小さい物体の位置の特定に必要な繊細で細やかな特徴を得られるかもしれない。Faster R-CNNとSSDはどちらも様々な解像度の特徴を得るためにネットワーク内のproposal network（たぶんRPN）を様々な特徴マップに使っている（RPNの入力として様々な特徴マップをつかっているってことですかね？）。製作者様はそれとは違うアプローチととりました。それは、手前にあるレイヤー（26x26の解像度(resolution)の出力をもつ）から特徴を持ってきてくれるpassthrough layerを追加したそうです（ResNetのresidual moduleみたいなものでしょうか）。passthrough layerは、違うサイズのchannelの内部にサイズを調整した特徴をstackすることでより高い解像度の特徴と低い解像度の特徴を結合するそうです。これにより26x26x512の特徴マップを13x13x2048の特徴マップにでき、そうすることでオリジナルの特徴と結合することができるそうです。
    - **Multi-Scale Training** : オリジナルのyoloは解像度448x448の画像を使用してしたそうです。anchor boxの追加により製作者様のモデルの入力は416x416になりました。でも、モデルは畳み込みとプーリングを使用しているため、内部で画像のサイズ変えられるそうです。yolov2は様々サイズの入力に対しても頑健なモデルになってほしかったため、以下のことを訓練で行ったそうです。
    - 固定したサイズの入力画像を使用する代わりに、10バッチごとにランダムに入力画像のサイズを変更したそうです。モデルは32のfactorを用いて低下像度処理を施していくため使用する入力のサイズは{320,352,...,608}とするそうです。そのたびにネットワークをリサイズして訓練を続けるそうです。こうすることでモデルは様々な解像度の入力に対して精度よく予測できるようになるそうです。モデルの速さと精度のトレードオフも激しくないから、288x288の低解像度の画像に対しても90FPSでFast R-CNNと同等の精度を得られる。544x544の高解像度の画像に対しては40FPSで動作しながら78.6mAPの精度だそうです。![yolo5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/3508e9d3-5ab7-1403-3c35-3f6cfd28b337.png)
![yolo6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/372182/9d170bb5-d950-3bf0-d947-7859b7cf3a3a.png)

#Faster
検出は速く、正確に行いたい。ロボティクスや自動運転車のような多くの物体検出の応用例では低遅延であることは大事ですよね。そういった応用先の製品のパフォーマンスを最大化するために、YOLOv2をゼロからデザインする。多くの物体検出ネットワークはVGG16を特徴抽出器として利用している。VGG16は力強く、正確な分類モデルだが必要以上に複雑です。VGG16の畳み込み層は224x224の解像度の1枚の画像を1枚モデルに通すと、306.9億の未決定のパラメータに対して処理を行うそうです。YOLOではGoogLeNetをカスタムしたネットワークを使用しています。このネットワークはわずかに正確性は落ちるそうですが、VGG16よりも速く、たったの85.2億の順伝搬処理を行うだけで済みます。single-cropに対してはトップ5の精度で、VGG16が90%に対して、YOLOのカスタムモデルは88%の精度を得たそうです。
- **Darknet-19** : 製作者様はYOLOv2をベースとした、新しい分類モデルを提案しました。

#まとめ
- recallとlocalization errorの改善をしましょう
- 巷ではネットワークを深くすることがはやりだけど、モデルは簡潔にして速く、正確なモデルを作ろう
- たくさん手法を提案した。以下に示す。
    - **Batch Normalization** :いい感じ、dropout無くせた（dropoutは悪者みたいな扱いなのは学習速度を低下させるためです）
    - **High Resolution Classiﬁer** :YOLOv2では448x448のImageNetデータセットを入力として10epochだけ事前学習した後、ファインチューニングした。高解像度のclassification networkを得ることができた。
    - **Convolutional With Anchor Boxes** :YOLOモデルからFC層を取り除く。anchor boxを使用する。入力画像を416x416にした。anchor box使ったら精度が少し下がったけどrecallは向上した。
    - **Dimension Clusters** : anchor boxのサイズを決めるためにk-means clusteringを使用する。Avg IoUとモデルの複雑さのトレードオフを考慮した結果、k-means clusteringのクラス数を5にすることが望ましいとわかった。
    - **Direct location prediction** : ネットワークは各グリッドセルごとに5つのバウンディングボックスを予測し、各バウンディングボックスごとに5つの値を予測する。そのうち4つの値を用いてバウンディングボックスの中心座標を直接求め、それにYOLOモデルのconfidence score的なものを残り一つから求める。
    - **Fine-Grained Features** : passthrough layerと呼ばれるResNetのresidual module的なものを導入して26x26x512の特徴マップを13x13x2048の特徴マップにする。
    - **Multi-ScaleTraining** : 訓練時、10batchごとに入力画像のサイズを変更して（320,352,・・・,608のサイズ）、その都度ネットワークの形状も変化させて学習を行う。

#　感想
想像以上に長くなってしまったのでパート分けします。　　
ここまで読んでわかったのはyolo9000はYOLO、YOLOv2はもちろんのこと、Faster R-CNN等のregion proposal-basedモデルの論文も読まないとよくわかんないなってことです。そりゃそうですよね。今後もゆったり論文読んで、実装頑張ります。