リサーチ河田こんにちは。先進技術部でアルバイトをしている河田です。Dangにより2018年8月に提案された物体検出手法CornerNet[1]について紹介します。Boxの左上・右下のコーナーを検出という点で、多くの物体検出手法の中で異彩を放っていました(発表当時)。本記事では、まずCornerNetの仕組みについて説明したのち、弊社で再現実装を行い独自データセットで訓練した結果を紹介します。物体検出とはCornerNetの具体的な解説にうつる前に、まず物体検出の基礎的な事柄について説明します。物体検出とは、画像認識タスクの一つで、「画像のどの位置に」「何が写っているのか(クラス)」を検出するものです。一つの画像に複数の物体が写っていた場合、それぞれについて位置とクラスを検出しなければなりません。(BBox)と呼びます。h\right)を、ニューラルネットワークを用いて推定します。Boxと呼ばれる矩形のテンプレートを変形させることで予測BBoxを作り出すという方法が取られました。R-CNN以降の物体検出手法にも受け継がれ、物体検出における事実上のスタンダードとなっています。Boxとは、図1に示すように、異なる大きさ・縦横比を持った矩形のテンプレートです。Boxから最も形の合うものを一つ選び、それを変形して予測BBoxとします。Boxに小さな変形を施すだけで予測BBoxを作成できるため、問題が簡単になり、訓練の安定性や検出精度の向上が期待できます。Boxの設計は注意深く行われる必要があります。detectorに分類されます。detectorでは、まず1段階目でBBoxの候補を抽出します。2段階目でクラス予測とBBoxの修正を行い、最終的な予測結果を生成します。detectorはBBox生成とクラス予測を一度に行います。detectorは構成がシンプルになり、学習や推論の高速化が見込めます。detectorに劣る傾向があります。detectorに分類されます。y\right)をそれぞれ推定します。その後、同一物体の左上と右下の頂点を対応付けることで、物体を検出します(図2)。クラス予測は、頂点の検出と同時に行います。Boxが不要となっています。検出の流れをもう少し具体的に見ていきましょう。Networkに入力して、特徴抽出を行います。Poolingレイヤーを通した後、それぞれでHeatmap、Embedding、Offsetの3つ出力させます。最後にこれらの出力を合わせて検出結果とします。以降では、それぞれのモジュールについて順に説明していきます。NetworkはCornerNetで用いられている特徴抽出用ネットワークです。砂時計をいくつも繋げたような形になっていることからHourglass(砂時計)という名前がつけられているようです。Networkはもともと姿勢推定[2]で提案されたアーキテクチャで、特徴マップのサイズを小さくしたり大きくしたりを繰り返すことで異なるスケールの情報を統合しようという意図で設計されています。NetworkはResNetと同様、Residual(残差)構造を採用しており、特徴マップの拡大縮小をまたいで空間情報が落ちてしまうのを防いでいます。Networkの内部構造の一部。Poolingに通されます。PoolingがCornerNetの鍵となります。いうのも、物体を囲うBBoxの頂点を検出するという問題設定は、そのままでは大きな欠点を抱えているからです。これらの画像ではBBoxの頂点部分に物体の一部ではなく背景が写っており、そのままでは頂点の検出は困難です。CNNは位置関係を保存して特徴抽出を行うため、画像上で物体の存在しない領域については、特徴マップ上にも情報が存在しないと考えられるからです。頂点の画素に物体が写っていない例そこで、物体の情報を左上と右下の頂点になんらかの方法で集める必要があります。Poolingを図6に示します。Pooling左上に情報を集めるためには、下から上に、また右から左にと特徴マップを走査していけばよいわけです。ReLUのような活性化関数を用いたネットワークでは、特徴の存在する位置の値は大きくなるため、走査しながら、それまでの最大値で特徴マップの値を上書きしていきます。最後に下から上、右から左に走査した結果を足し合わせて、それを出力とします。具体的な数値で計算をしてみましょう。図7の赤枠部分に注目してください。この2つの赤枠は、右から左への走査の、走査前と走査後の様子を示しています。走査前では、一番右の数は2,その次の数は0です。これを右から順番に見ていき、それまでに見た最大値で上書きします。したがって、二番目の0は2で上書きされます。これまでの最大値は2ですから、上書きはしません。これまでの最大値は3なので、1を3で上書きします。......と繰り返し、最後に右から左の走査結果と下から上の走査結果を足し算するわけです。Poolingによってほんとうに頂点を検出できるかどうか、簡単な例で確かめてみたいと思います。Poolingに通される特徴マップです。青い部分に物体が存在しているとします。Networkで抽出された特徴量で、値が大きいほどなんらかの特徴が存在することを意味しているとしましょう。Poolingを適用したものが、一番右の図です。値が大きいのが黄色で示している部分で、これが頂点として検出されます。実際、これを左上頂点とする矩形で囲ってみると、物体のある領域をうまく捉えられていることがわかります。頂点に特徴量が集まっていることが分かるHeatmapではここからはCornerNetの3つの出力について順に述べていきます。HeatmapはBBoxの頂点の存在確率を示します。Heatmapにはクラス数と同数のチャネルが存在し、各チャネルが対応するクラスの頂点に反応するよう訓練されます。HeatmapはSigmoid関数によって0~1の値をとるよう調節されており、物体頂点がありそうな位置のHeatmapの値は1に近づいていきます。Heatmapはどのように訓練されるのでしょうか。“person”)など)。CornerNetではこの正解データを用いて、正解Heatmapを作成し、これと推論されたHeatmapを比較してLoss(損失)を計算します。正解Heatmapは、正解BBoxの頂点の値を1として、これを中心にガウス分布に従う広がり(式1参照)をもたせたものを利用します(図9)。仮に頂点の座標のみに1を立てたようなHeatmapを正解データとして使うと、予測が1ピクセルでもずれると完全に間違いということになってしまうため、多少の誤差を許容するために正解に広がりをもたせているわけです。その際、BBoxのサイズによってズレが予測に与える影響は変わるため、σを調節してペナルティの大きさを制御します。小さいBBoxではσを小さくして分布の広がりを狭め、逆に大きなBBoxではσを大きめにするのです。正解Heatmapの例では今度はLossの計算式を見てみましょう。Lossは式2に示すように、「ぴったり正解BBoxの頂点に一致した点」とそれ以外の点とで計算式が異なります。β=4))ぴったり正解BBoxの頂点に一致する点(y_{cij}=1)については、式2の上の式でLossを計算します。この式では、予測Heatmapの値が1に近いほどLossは小さくなります。それ以外の点では式2の下の式で計算します。こちらの式では、予測Heatmapの値が0に近いほどLossが小さくなります。正解BBoxの頂点に近くても、一致しない限りはHeatmapの値を0に近づけるということです。(=y_{cij}が大きければ)Lossが小さくなる、つまりペナルティが軽減されるということになります。EmbeddingHeatmapによって各物体の左上と右下の頂点候補を得ることができますが、このままでは、どの左上頂点とどの右下頂点がペアなのかわかりません。HeatmapだけではBBoxを一意に決められないそこで頂点ペアの決定に用いられるのがEmbedding(埋め込みベクトル)です。Embeddingはクラス数に関係なく共通のベクトルで、各ピクセルに対して一つずつ得られます。論文ではEmbeddingは1次元になっています。このEmbeddingが近いものがペアであるということにすれば、BBoxを一意に決定することができそうです。図中の数字がEmbedding.例えば0.34と0.36が近いのでグループ化可能さてこのようにEmbeddingを用いて頂点のグルーピングをするためには、同一BBox上でペアになる頂点間のEmbeddingの距離が近く、逆にペアではない頂点間ではEmbeddingの距離が遠くなればよいわけです。このように学習したいこれを実現するために、式3にもとづいてLossを計算します。ペアとなる頂点間で定義されるLossで、L_{push}がペアではない頂点間で定義されるLossです。順に説明していきましょう。Lossの計算では、ペアとなる頂点間のEmbeddingの平均を、基準として用います。)に近づくようにします。これは少々わかりにくいかもしれません。