わくわく計算ライフ

ドムプラをキメつづけるブログになりつつある。

今更読むSSD:Single Shot MultiBox Detector(学習編)

今更ながら物体検出モデルSSDを読む第3回。
前回のは評価関数について説明しました。
しかし、そのまま学習させると色々問題がある、ということで今回はその対策について。

前回記事はこちら

calc-life.hatenablog.com

1. 元論文

arXivへのリンク
画像の引用もこちらの論文から行っています。

2. 前回のあらすじ

全体がこれ

 \displaystyle
L(x, c, l, g)=\frac{1}{N}(L_{conf}(x, c) + \alpha L_{loc}(x, l, g))

矩形推定の損失関数がこれ(学習対象の正解矩形にもっとも近い基準矩形ベースの推論が対象)  

 \displaystyle
L_{loc}(x, l, g)=\sum^N_{i \in Pos} \sum_{m\in \\{cx, cy, w,h\\}} x_{ij}^k smooth_{L1}(l_i^m - \hat{g}^m_j)

矩形のクラス推定の損失関数がこれ

 \displaystyle
L_{conf} (x, c)  = -\sum_{i \in Pos}^N x_{ij}^p log(\hat{c}_i^p) -\sum_{i \in Neg} log(\hat{c}_i^0)

詳細は前回記事を参照してください。

3. 基準矩形の設定

矩形推定のCNNへの特徴量マップの各点に対して、基準矩形が設定されているという話は今までしてきた。
ここでは、今までしてこなかった具体的にどのような基準矩形を用意しているのかを解説する。
(論文中 P.5 Choosing scales and aspect ratios for default boxes)

3.1. スケール定数

各スケールの特徴量マップに割り当てる基準矩形のスケール s_kについては以下の様に設定されている。

 \displaystyle
s_k  = s_{min} + \frac{s_{max}-s_{min}}{m-1}(k -1)

ここで、 mはスケールの段数(本論文では6つのスケールの特徴量マップから矩形推定しているので m=6)である。
特徴量マップが比較的1段毎に約1/2になっている(指数的)なのに、線形(すなわちマップサイズの変量の対数)で良いの?とは感じた。
6段程度だとそれほどは厳密性が要らないのかもしれない。

 {s_{min}} = 0.2

 s_{max} = 0.9

となっているが、ここでの1.0は画像全体の幅、高さを1.0としたときのサイズに相当する。

3.2. アスペクト比のバリエーション

1つのスケールに対してアスペクト比のバリエーションを a_r \in \{1, 2, 3, 1/2, 1/3\}として設ける。

以上からスケール k,アスペクト比 aの矩形のサイズは次式で定義される。
 {w_k}^a =  s_k \sqrt{a_r}, {h_k}^a =  s_k /\sqrt{a_r}

 {w_k}^a {h_k}^a = {s_k}^2 より、同一スケール内のアスペクト比違いは同じ面積にそろえているようである。
また、アスペクト比1の矩形については、一つ上のスケールとの相乗平均のスケールの物も用意する
 {s_k}' = \sqrt{s_k s_{k + 1}}

また、基準矩形の中心座標はすべて、特徴量マップ上の各点に相当する範囲の矩形の中心点となる。
ソースを確認した範囲では最も小さいスケールと、大きい側の2段階のスケールでは \{3, 1/3\}を除いた
 a_r \in \{1, 2, 1/2\} {s_k}'の4パターンが使用される。

4. Hard negative mining

名前がカッコいい。なんとなく年齢制限を感じる。
その実 Hard(難しい) negative(負例)をmining(掘り起こしてくる)。
前回ちょろっと出しましたが、

 \displaystyle
L_{conf} (x, c)  = -\sum_{i \in Pos}^N x_{ij}^p log(\hat{c}_i^p) -\sum_{i \in Neg} log(\hat{c}_i^0)

この式だとNegative(負例)の数が多すぎて、そちらの推定精度に引っ張られて正例(分類したいクラス)の学習が上手くいかない可能性が高い。
そういう場合によくやるのが、

  • 出現頻度で学習時に重みづけする
  • いい感じに間引きを行って学習したい各クラス間のサンプル数の差が大きくなりすぎないようにする

辺りですが、Hard negative miningは後者です。
SSDでは正解クラスの確信度でソートして確信度が上位のNegativeサンプル(=正例と間違えやすい負例)をピックアップすることで、正例:負例の比率をおよそ1:3までに抑え込んでいます。

5. DataAugumentation

SSDで提案されているDataAugumentationについて。
以下のどれかを使って画像を拡張し、よりロバストにしているとのこと。

5.1. 画像全体を使う

何もしていない。これがベース。

5.2. Jaccard係数を見ながらクロップ

画像パッチをオリジナル画像からクロップする。
この時。クロップ領域とクロップ領域内の物体矩形とのJaccard係数の最小値を見ながらクロップ範囲を調整する。
最小Jaccard係数が 0.1, 0.3, 0.5, 0.7, 0.9等のクロップが例示されている。

5.3. ランダムにクロップ

正にランダムにクロップする。

5.4. クロップ時に設ける制約

スケールは元画像を1.0とした場合に [0.1, 1]の範囲に収める。
クロップ時のアスペクト比は [1/2, 2]の範囲に収める(最終的に入力の300x300にリサイズされるのでクロップ時アス比に応じて歪む)。
また、最終的には水平反転もランダムでしているとのこと。
論文中には挙げられてないが他にもやれることはいっぱいある(色とか明るさをちょっと弄ったりとか)。

6. マルチスケール特徴量補足

最後になったが、各物体検出CNNの適用対象となるマルチスケール特徴量の作成方法について補足説明をする。
基本的には

  • 前段に学習済みVGG16のConv5_3レイヤーまでを使う
  • 後段は1x1のConvで特徴量を調整しつつ,3x3のConvフィルタをステップを2にしてダウンサイジング

している。例えばFig2中のConv: 3x3x256-s2の記述は
「3x3]のConvolutionフィルタを256個用意する。
フィルタを適用する際のストライドステップは2とする(s2)の意味である。

7. まとめ

論文中のここまで整理されれば実装可能というところまで解説しました。
(実験結果とかは今回は省略)
次回はおまけ編。物体検出モデル全般の扱いとかについてちょっと書きます。

calc-life.hatenablog.com

==== ↓個人的には1Q毎のお楽しみにしている本 ====