皆さんこんにちは
お元気ですか。ちゃっかりKaggleで物体検出のコンペもはじまりました。
Deep Learningは相変わらず日進月歩で凄まじい勢いで進化しています。
特に画像が顕著ですが、他でも色々と進歩が著しいです。
ところで色々感覚的にやりたいことが理解できるものがありますが、
あまり勉強していなかった分野として物体検出系のアルゴリズムがあります。
所謂、Faster RCNN, SSD, Yolo、最近、Mask R-CNNが該当します。
ただ、今回は、個人的に物体検出のアルゴリズムで
なかなか調べても出てこない、あれここどうなってるんだっけ?と思った部分の解説をします。
そのため、案外変なところの解説かもしれません。
Faster RCNNの技術要素から説明しようかなとも思って作りました。
※数式、記号等の細かい説明は論文を参考にしてください。
3/7 15:15 Ancher→Anchorに修正しました
Faster RCNN
Faster RCNNは2015年に発表された論文です。
最近だと特許的な問題でも一時期盛り上がりを見せています。
Deep Learningを利用したEnd to Endで物体検出を
実施したニューラルネットワークです。
https://arxiv.org/pdf/1506.01497.pdf
※特許解説(日本語)
qiita.com
全体構成
Faster RCNNは特徴マップを抽出するConvolutional Layerと物体領域を抽出する
Region Proposal Networkに加え、分類、回帰の結果を出力するネットワークで構成されています。
※論文より引用
Conv Layerで得られた結果をRegion Proposal Networkを使い、領域を抽出し、分類しています。
特に重要なのはRegion Proposal Networkと記載されている部分で
ここが従来手法からのFaster RCNNの改善になる部分です。
Region Proposal Networkは次で説明します。
Region Proposal Network
概要・目的
Region Proposal Networkは画像内から物体領域の候補となる箇所を抽出します。
元々は「Fast RCNN」ではこの物体領域抽出にSelective Searchと呼ばれる手法を使っていたため、
物体候補領域の抽出に時間がかかっていました。
その箇所すらもEnd-to-Endで実施することで従来より高速・精度改善をしています。
全体的には次の処理があります。
- 物体の候補領域を見つけるAncherを作成する。
- (学習時)誤差を計算する。
- 候補の中からNMSなどを実施して、Region Proposal Networkでの物体の候補領域を抽出する。
その中で特に私が不明だった要素をいくつか紹介します。
Anchor
Anchorと呼ばれる領域を生成します。
一言で言えば、物体の領域を示している矩形です。
これらを画像内に一定間隔で生成します。これは後述のLoss Functionで利用されます。
Loss Function
RPN自身を更新するための誤差を計算し、
ニューラルネットワークの全体の誤差と併せて更新します。論文中の式は次の通り。
RPNの誤差は基本的には2つの要素で成り立っています。
①その領域は物体か背景であるか、②どこに領域があるかの領域の位置(詳細)を計算します。
特に私が勉強するまでイメージを持てなかったのは「そもそも教師信号をどうやってこの式に当てはめるのか」です。そもそも与えてるのバウンディングボックスとクラスだけなのですが・・といった疑問です。
教師信号の決め方ですが、物体の有無はAncherと物体のIoU(Intersection over Union)が
0.7(論文中)以上の場合、物体が存在することを示します。(positive anchor)
また、IoUが0.3以下を物体が存在しないこと(negative anchor)を示します。
平たく言ってしまえば、ある程度重なっているAncherに物体が存在するラベルが振られ、
存在しないAncherに物体が存在しないラベルが振られます。
それ以外は学習に貢献しません。
Ancherは回帰を行います。
Ancherのデータの回帰ですが、次の通り計算を行って、スケールの調整を行っています。
(細かい記号は元論文を見てください)
この値からsmooth L1と呼ばれる誤差関数を用いて最適化します。
Non-Maximum Suppression
後処理としてあるのがNon-Maximum Suppression(NMS)です。
これは同じ物体を示している矩形を抽出する手法です。
本手法を利用して、1つの矩形を残し、残りの出力を抑制します。
詳細は次のサイトが詳しいのでこちらに任せます。
これらによって得られた結果に対して、RoI Poolingを行い、分類、回帰を行うネットワークに接続します。
RoI Pooling
RoI Poolingは分類を行う層への入力を固定次元にする役割があります。
物体検出の領域は非常に可変長です。同じ画像から検出された椅子とりんごが同じサイズではないのと
同じようなものです。その得られた領域を次の分類のネットワークで処理するため、
固定次元に縮小する処理を行います。
処理の概要はこちらのサイトがわかりやすいです。
実装
実装サイトはいくつかあります。さくっと検索して発見できたサイトを掲載します。
GitHub - mitmul/chainer-faster-rcnn: Object Detection with Faster R-CNN in Chainer
GitHub - longcw/faster_rcnn_pytorch: Faster RCNN with PyTorch
GitHub - endernewton/tf-faster-rcnn: Tensorflow Faster RCNN for Object Detection
最後に
なんとなく自分が疑問に思った所を中心にまとめてみました。
ちょっとすっきりしました。間違っているところあれば、教えてください。