わくわく計算ライフ

ゲーマーによる節約生活。はじまります。

今更読むSSD:Single Shot MultiBox Detector(評価関数編)

今更ながら物体検出モデルSSDを読む第2回。
今回は学習部分のうち評価関数周りについて説明しようと思います。

前回記事はこちら
calc-life.hatenablog.com

1. 元論文

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

2. 評価対象矩形の選別

SSDでは様々なアスペクト比およびサイズを持つ8732個の基準矩形をベースに、どの物体クラスに属しているかおよび正解の矩形と基準矩形との位置、サイズの差分を推論する構造になっています(p.4 Fig.2)。
画像上のある物体について、これら8732個の矩形すべてについて推論・学習をする必要があるかというとそれはNoです。

基準矩形の格差

上図において検出したい物体の正解の矩形が R_gであるとします、この時青枠で示した2行3列目のセルに属する基準矩形 R_pは正解付近の特徴量を利用しているし、矩形の差分もそれほど無いのでこれは学習時の評価の対象としても良さそうというのは分かると思います。
反対に図の左下4行1列目に属するグレーの基準矩形 Rnは正解矩形と全然別の箇所の特徴量を見ていますし、変形して矩形を R_gにするにも必要な変形量が多すぎます。
よって R_nを学習で調整して R_gにしよう!というのは無理があると思います。
仮に R_nの位置にもたまたま、 R_gと同じクラスの物体があったとしても、正解の物体がある位置と全く関係ない場所に正解と同じクラスの物体があるか無いかが推論に影響するというのもおかしな話です。

そこでSSDではあらかじめ、正解矩形とすべての基準矩形の領域を評価し、学習は各正解矩形に対して最もオーバーラップ率の高い基準矩形をベースに行います。
オーバーラップ率は正解矩形と基準矩形の面積をベースにしたJaccard係数で起算しています。

 \displaystyle
J(A, B)=\frac{A \cap B}{A \cup B} \ \ ,(A \cup B > 0) \\
J(A, B)=0 \ \ ,(A \cup B = 0)

 0.0 \le J(A,B) \le 1.0の値は上式より明らかです。
加えて、 Aまたは Bが他方に完全に内包されているケースでも、 A, Bの大きさがかけ離れていれば J(A,B)が小さくなることが読み取れます。
これにより様々なスケールおよびアスペクト比で準備された8732個もの矩形のうちある程度位置、サイズ、形状が近い基準矩形をベースに学習を進めることができます。

さらに、上記の中でJaccard 係数が0.5より高い矩形のみに絞り込むことで、オーバーラップ率が高い基準矩形が存在しない正解矩形は学習の対象から外しています。 選別の閾値の 0.5ですが2つの矩形形状が全く同じケースで考えると大体縦横それぞれ6割ぐらい被っている状態なので、結構重なっているなと思えると思います。

この矩形選別は、正解データおよび設計された基準矩形という学習中に変動しない要素で構成されるため、各画像についてどの矩形を使用するかを事前計算して結果を保持しておけば学習を高速化できます。

3. 評価関数

論文p.5辺りから始まる評価関数について(Training objectiveの項)。
論文中では i番目の基準矩形が、クラス p j番目の正解矩形にマッチしている(=学習対象になっている)かを  x_{ij}^p = \{ 1, 0 \} で表しています。

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

 Nは学習対象となる基準矩形(から作成される候補矩形)の数で N=0の場合は L(x, c, l, g)=0です。
 xは先ほどの x_{ij}^p = \{1, 0 \}で、すべての候補矩形に対して学習に使用する/しないを表すインデックス。
 cは各クラスへの所属確率。
 l, gはそれぞれ推定矩形および正解矩形を表します。

学習対象矩形に対して
 L_{loc}(x, l, g) が矩形推定の損失、

 L_{conf}(x, c) がその矩形のクラス推定の損失を表します。

3.1. 矩形推定の損失関数

 \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)

 kは学習を行う矩形がマッチしている正解クラスの番号。
 \hat{g} smooth_{L1}(\cdot)の説明をひとまず置いておくと、推定矩形毎にクラス kの正解矩形との、矩形の形状の差分をlossとして計算している。

smooth L1 lossについてはPytorchの説明を参照すると、基本はL1 lossで0付近 (-\beta \ge x \ge \beta)が2次関数の形で丸まった物になっています。これは正解点付近での勾配をL1 lossに比べて滑らかにして安定させることを狙っています。

次に \hat{g}について。
これは、正解矩形 gを基準矩形 dからの差分で表した形式です。
位置ずれの誤差は学習する矩形サイズのスケールによる影響を打ち消すように、基準矩形のサイズに応じて正規化されます。

 \displaystyle
\hat{g}_j^{cx} = (g_j^{cx} - d_i^{cx}) / d_i^w \\
\hat{g}_j^{cy} = (g_j^{cy} - d_i^{cy}) / d_i^w

一方でサイズの方は

 \displaystyle
\hat{g}_j^{w} = log\frac{g_j^w}{d_i^w} \\
\hat{g}_j^{h} = log\frac{g_j^h}{d_i^h}

とスケール比の対数を使用しています。対数の差分を取るので倍率の変化が無ければ0になります。
全体では N個の推定矩形と正解矩形との誤差の平均がlossになる形です。

3.2. クラス推定の損失関数

 \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)

第1項は学習対象矩形の正解クラス pであると確信している度合い  \hat{c}^p_i の合計。
第2項は学習対象外の矩形が背景クラス 0で確信している度合い \hat{c}^0_iの合計である。

 \displaystyle
\hat{c}^p_i  = \frac{exp(c^p_i)}{\sum_p exp(c^p_i)}

即ちここで用いる確信度 \hat{c}^p_iはネットワークが出力した推定矩形 R_iの各クラスの確信度  {c}^p_i のSoftmaxを取ったものとなる。

3.3. 損失関数のまとめ

以上の説明から感じるのは

  •  {L}_{loc}(x, c, l, g) N個の正解矩形に対応する分しか計算しなくてよいので計算量少なそう
  • 一方 {L}_{conf}(x, c)はPositive, Negativeの全矩形に対する演算があるので重そう
  •  Nは感覚的には数100個ぐらいでも多いと感じる。一方で全体の基準矩形の個数は8732個(SSD300)でNegativeが圧倒的に多く、それに引っ張られそう

4. まとめ

評価関数の基本的な計算式について解説した。
実際の学習時の工夫や、疑問点については次回に回す。

次回「学習編」へ

calc-life.hatenablog.com

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