わくわく計算ライフ

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

今更読むSSD:Single Shot MultiBox Detector(おまけ編)

今更ながら物体検出モデルSSDを読む第4回。
前回までで、一通りの解説が完了しました。
今回は全体を通して気になったBounding Boxについてつらつら書いていこうと思います。

前回記事はこちら

calc-life.hatenablog.com

1. 元論文

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

2. 基準矩形の設定について

前回までの解説で、SSDは

  • 各スケールの特徴量マップの各位置に4~6個の基準矩形を割り当てる
  • 正解矩形に対しJaccard係数の高い基準矩形をベースにした推定矩形で学習する

という作りになっているのが分かりました。
各推定矩形に割り当てられる特徴量は、 nクラス分類に用の n次元のデータと、正解矩形との差分を表す4次元のデータのみです。
つまり、1個の矩形の領域には1つの物体が写っている想定の構造になっています。

ところで画像は2次元のデータではありますが、写真等は3次元から作り出されたデータなので、「物体が重なっている状態」というのが当然あります。
SSDの様な矩形に1物体を割り当てるモデルではこのようなケースは上手く学習できない可能性があります。

如何に具体例をいくつか挙げます

  • 兄の前に半身で弟が立っている
  • テレビや額縁の中に人がいる
  • 鉄棒の下に人が居る

被ったり、入れ子になっているシーンですね。
極端な例では次の様なケースだと、2つの物体と重なっている量が同じ基準矩形が複数存在することもあり得ます。

基準矩形に複数物体が被るケース

このような場合はどうしたらよいか?と考えると。

基準矩形に正解矩形が対応付けられた時点で使用済みチェックをつけることにし、
未使用の基準矩形の中から最もオーバーラップ量が大きい物を割りあてる、とすればとりあえずは良さそうです。

先ほどの例でいえば、図中の青の矩形はどちらかの人に割り当てられ、もう一人はしぶしぶ他方の矩形を割り当てられることになるでしょう。
同じ位置の横長の矩形などが割り当てられるかもしれません。
この場合、Jaccard係数的にNo.1ではない矩形が割り当てられることで若干の悪影響があるかもしれません。

ベンチに座った人などの様に縦横の関係が明らかなっている場合は、ベンチに横長、人に縦長の矩形が割り当てられると考えられるのでこういうケースは悪影響が少なくなると予想されます。

3. 苦手ケース

SSDに限らずな話にはなりますが、この手の物体検出モデルで学習がうまく行かない、あるあるケースについてちょっと紹介します。

3.1. 小さすぎる物体

モデル自体の解像度に起因する問題。
論文読んで式ばっかり見てるとたまに忘れるのですが、CNNの特徴量マップは入力画像を空間方向に量子化した離散的な構造を取っています。
よってこの量子化したセルに対して十分に小さい物体は正しく学習/検出が出来ません。

3.1.1. なぜうまく学習/検出ができないか

SSD300のネットワーク構成図をベースに説明します。
まず第一の関門ですが、入力画像が  300\times 300 な訳ですが、 300\times 300 の画像上で  3\times 3ぐらいのドットの集合を想像すると「なんだかそれだけだと物体の判別は出来なそうだな」と理解できると思います。
一方、最近のカメラは解像度が高いので  3000\times 3000 ぐらいの画像が気楽に撮影されるわけですが、先ほどの  300\times 300 上の  3\times 3 って  3000\times 3000 ぐらいの画像上だと  30\times 30 ぐらいの大きさで、人間素晴らしいものでこれぐらいの解像度があると結構物体として認識できてしまう。
身近物ですとWindowsの中サイズアイコンが  32\times 32 ぐらいです。つまり、OS作ってる人がこれくらいのサイズでは十分に表現力があると考えているサイズなのです。
なので、人間が調子に乗って元画像上で  30\times 30 ぐらいの大きさの物体を囲んでアノテーションしてもSSD等に届くときには既に  3\times 3 ぐらいになっていて「なんもわからん」みたいな状態になることが結構あります。

第二の関門が特徴量レイヤーの解像度です。
SSDで最も解像度の高い①のレイヤーは  38\times 38 の解像度です。
①のレイヤー上の1つの点は入力画像の  1/38 程度の領域に対応することになります。
実際には何層ものConv層の演算で周辺情報が取り込まれている可能性が高いので実際にはもう少し大きい範囲です。 先ほどの  3000\times 3000 程度の画像を例にとると元画像上で  3000 / 38 \simeq 78 pixel程度の大きさより物体が小さくなってくると、大分ネットワークによる分析が怪しくなってきます。

推論が怪しくなってくるということは、怪しい推論と正解を突き合わせても効果的に学習が出来ないということになります。

3.1.2. 対策

代表的なものをいくつか程挙げます。

(1) ネットワークの解像度を上げる
力で殴る解決策。
ただし、これはモデルが大きくなるため演算量がスケールの2乗以上で増えてしまいます。
以上としたのは解像度を上げた場合に特徴量マップの層数も増やすケースが出てくるからです。

(2) 小さい物体は無視する
泣く泣く諦める解決策。
アノテーションはとりあえず気にせずやってもらいますが、学習時に一定の大きさより幅または高さが小さい物体は除外してしまうというものです。
具体的には、基準とするネットワークの入力解像度または特徴量マップの解像度をベースに、それらの上での最小サイズを規定し、元画像に当てはめた場合の大きさを閾値として小さい物を省きます。
小さいものはとれなくなってしまいますが、それ以外の学習に悪影響を与えないので、簡単にできて効果が高い手法だと思います。

(3) 入力画像を分割する
入力画像を分割してネットワークに入力することで、画像を小さくしリサイズされる量を低減し、より小さい物体を検出できるようにします。
例えば、  3000\times 3000 の画像を縦横半分の  1500\times 1500 の画像4枚に分割して4回かければ全領域を一応カバーできます。
問題点としては以下の2つが上げられます、

  • ネットワークに入力する回数が増えるため演算量が上がる
  • 分割した境界により物体も切れてしまうことがある

(4) 階層的に物体検出を掛ける
例えば「街中の写真から人が掛けているメガネを検出する」といった問題の場合。

  1. 画像全体から大き目の物体である「人」を検出する
  2. 検出した人の周辺のみを切り出してくる
  3. 切り出した画像ごとにメガネを検出する

というフローが使えます。 大小と位置が関連しているようなケースであれば、大きいアンカーを探し、その後アンカー周辺を細かく探すという手法がとれます。
この場合は、街から人を検出する物体検出器と、人の周辺からメガネを検出する検出器を個別に学習させ各段を特化させることで精度を上げることもできます。
特に後段のネットワークは初段のネットワークで切り出した画像のみが対象となるので、関係ない場所の映像によるノイズの影響から切り離されるため少ない画像枚数でも精度を出すことができます。

3.2. 斜めの細い物体はしんどい of しんどい

3.2.1. 説明!

これは図を見ると一発なので、図を出します。

雑バット君

この雑に描いたバットですが、全く同じ図形で右は左の物を45°傾けた物です。
Bounding Boxは理想的には45°傾いてくれればよいのですが、計算の都合上そうはいかずバットが対角線の様になります。
左のまっすぐバットを囲う矩形の範囲内にはバット以外の領域が含まれませんが、右のバットの矩形の中身はむしろバット以外の面積の方が大きいわけです。
これを同じように学習できるかというと難しい話になります。

3.2.2. 解決策例

対策としては、以下のNVIDIAのブログで紹介されているように回転したBoundingBoxを取り扱えるモデルを使うというのがあります。 developer.nvidia.com

あります…が…
「傾いたBoundingBoxのアノテーションがしんど過ぎるので却下されます。」
ハイ…。既存にそういうデータも少ないしね…。

4. アノテーション時の指針

Bounding Boxのアノテーションをどう指示したらいいかわからない!
という人が居るかもしれないのでオススメの囲み方を紹介しておきます。

なるべく小さく。ただし、物体形状が確定する程度には広めにとる

これがオススメです。
「なるべく小さくとる」は背景情報をノイズとしてなるべく含まないようにするためです。
「物体形状が確定する程度には広めにとる」は次の数字の例で説明します。

この数字は?

この数字はなんでしょう???
正解は…

4でした

「4」でした!(ハイ、クソー)。

となります。 上記のBoundingBoxのつけ方の問題点は「BoundingBoxの境界の外側にも同一の物体の続きがあるかも?」という状態になっているのが問題です。
よって、物体のギリギリでは無く周りの余白も若干入れて矩形内で物体形状が確定させることが大事です。
また、一般にはネットワークに入力する際に小さいサイズにリサイズすることが多いと思いますので、リサイズの結果余白がつぶれてなくならないように余白にも余裕を持たせるとよいです。

こんな感じで囲おう!

5. さいごに

今回は物体検出モデルを扱う際に気を付ける点について解説してみました。
意外と既存のモデルに適当にアノテーションした画像を食わせて「全然学習できない…」ってなっている方が居るので(特に業務系でとりあえずAI使わされてる人とか)、助けになればと思いました。