2018年4月24日火曜日

RefineDet メモ 2

PytorchSSD の実装で,loss functionは,ARM, ODMの出力に対してそれぞれarm_criterion , odm_criterion で、ともにPytorchSSD/layers/modules/refine_multibox_loss.py にあるRefineMultiboxLoss のインスタンスである.

arm_criterion は,PytorchSSD/utils/box_utils.py/match によって,ground truthと最も一致する(Jaccard Indexの大きい) prior boxを計算し,そのprior boxに対応する arm_locarm_conf の組に対してconfidence lossとlocalization loss を計算する.さらに,ground truthに対応していないがarm_conf が高いものたちを選んでconfidence loss を計算し,足す(Hard negative mining).
([Learning Note] Single Shot MultiBox Detector with Pytorch が参考になる)

arm_criterion ではPytorchSSD/utils/box_utils.py/match を,ground truthとprior boxの対応づけにつかうのだが, loc_criterionでは PytorchSSD/utils/box_utils.py/refine_matchによって,ground truthとarm_loc を対応づけて,そのarm_loc に対応したodm_locodm_conf の組に対してarm_criterion と同じ操作を行う(confidence loss はクラスごと).

もとの論文では,ARMはbounding boxの粗いlocalizationを行う ((2) coarsely adjust the locations and sizes of anchors) としていたが,この実装では特別ARMでのbounding box regressionを粗くする工夫は見当たらなかった(オリジナルの実装にはあるのかも).

2018年4月23日月曜日

RefineDet メモ1

RefineDetSSDの進化系.CNNは後ろの方のレイヤーほど(poolingによって)空間的な情報を失い,抽象的な情報を持つようになってくるので,SSDの検出器は前の方にある検出器の性能が低く,したがって小さい物体の検出が苦手だった.(参考:リアルタイム物体検出向けニューラルネット、SSD(Single Shot Multi Detector)及びその派生モデルの解説)
そこで,後ろの方のレイヤーの情報をTransposed Convolutionによって大きくして前のほうのレイヤーと足し合わせ(Elementwise sum)(fig.1),前の方のレイヤーがより多くの抽象的な情報を利用できるようにした.さらにAnchor Refinement Module(ARM)という,bounding boxのあらいrefinementと,objectである/ない の2値のクラス分類を行うモジュールと,Object Detection Module(ODM)という,bounding boxの精密なrefinementとobjectのクラス分類をおこなうモジュールを併用している(fig.2).

figure 1
(figure 1)

(figure 2)

PyTorch実装の一つであるPytorchSSDのコードを読んで混乱したところがあったのでいくつかメモする.

PytorchSSD/models/RefineSSD_vgg.py

ARM部分(fig.3). VGGと追加のレイヤーからの出力(feature map)のうち,いくつかは arm_sources というリストに入れられる.self.arm_loc というレイヤーがバウンディングボックスの座標(x, y, width, height)をself.arm_conf というレイヤーがobjectであるか否かという二値の推定を行い,その値は arm_loc, arm_conf というリストに格納される. arm_sources はARMでは変更されず,そのままTCBに渡される.

(figure 3)

TCB部分(fig.4). TCBというブロックをまとめて実装しているのではなく,ARMからの情報 arm_sourcesをconvolutionするself.trans_layers ,Transposed Convolutionによって小さなfeature mapを引き伸ばすself.up_layers , それらの結果の和をODMに引き渡す前にconvolutionを行うself.latent_layers というレイヤー群をそれぞれ実装していて,最終的にODMに渡す値は obm_sources である.
(この実装ではobmというワードが散見されるが,おそらくODMのタイポである. 混在しててこわい.)

(figure 4)

ODM部分(fig.5).
obm_sourcesself.obm_loc, self.obm_conf に渡され,それぞれbounding boxの精密な座標と,objectのクラス分類を行い,結果はobm_loc, obm_conf に格納される.

(figure 5)