回転_高速_Rcnn

より速く回転しました rcnn


下の図は未完成で roi_head.forward の部分だけ使っていますが、コード解析は完了しています
まとめる rpn から hbb を使用し、 bbox_head まではシェイプ n と 5 の結果を予測し
、その後学習しますスルーロス。
ただし、p2rb は回転 roi_extractor 抽出メソッドを使用する必要がある
ため、 もう一度 owned_rcnn を読み取るつもりです。

img
extract_feat
rpn_head.forward_train
roi_head.forward_train
loss
roi_head.forward_train
assigner
sampler
bbox_forward_train
self.bbox_forward_train
bbox2roi
_bbox_forward
get_targets
bbox_head.loss
_bbox_forward
bbox_roi_extractor
bbox_head
cls_score,bbox_pred
bbox_head
4_3_2_2_
rpn_head.forward_train

訓練

画像の説明を追加してください

rpn_head.forward_train

画像の説明を追加してください
ただし、その前に、rpn_head.forward 部分である outs=self(x) を実行する必要があり、
loss と props がそれぞれ self.loss self.get_bboxes によって取得されていることがわかります。

rpn_head.forward

forward–>forward_single したがって、次の forward_single の直接分析では、
画像の説明を追加してください
forward_single が非常に単純であることがわかります。直接畳み込み層は 2 つの –> スコアと bbox を取得します。

feat_channels のデフォルトは 256 です。以下は rpn_reg と rpn_cls の定義です。以下は私の ID
(self.feat_channels、self.num_anchors 4, 1)によってブロックされています。
画像の説明を追加してください
ここでは実際には
4 です。これは、rpn が引き続き hbb によって生成されることを意味します。オッブ。

rpn_head.loss

次の 3 つの関数を組み合わせて rpn_head.loss
self.get_anchors
self.get_targets
self.loss_singleを形成する
のも理解しやすいです。結局のところ、これはアンカーベースであり、cfg に従ってアンカーを生成し、各アンカーは gt
照合されます。
次に、bbox_preds、cls_scores を使用して損失を計算します。最初の 2 つの部分は、実際には bbox_preds、cls_scores に渡されません。

回転ボックスがないのでmmdetectionと同じはずです

rpn_head.get_bboxes


self.anchor_genertor.grid_priors(featmap_sizes,device)
get_bboxes_single
下の図からわかるように、多くのアンカーが生成されます.
アンカージェネレーター
以下は get_bboxes_single の cfg 部分を示しています.ここ
画像の説明を追加してください
では、レイヤー 0 ~ 3 が最上位を保持しますフレームに対応する 2000 スコア
そして 4 番目の層 (つまり、5 番目の層) はすべてのフレームを保持します。
この合計 8768 フレームについて、torch.cat を使用して list5 を tensor 8768,4 に取得します。

次のコードは 3 つの部分で構成されています。
torch.cat はすべてのレイヤーの props を統合します。
すべてのボックスの xyxy をデコードして表現します。
nms は 8768 個のボックスに対してスクリーニングを実行します (3000 個を超えるボックスを保持し、表示されているボックスはボックス間で繰り返されます) これは深刻です。予約ボックスのIDですが、以下のroiは実用的ではないので渡す必要はありません)
画像の説明を追加してください
ということで、どの段階でnmsが使われているか、やっと分かりました!

次に、cfg に max_per_img=2000 というキー値があるため、最初の 2000 フレームは nms の後に保持されます。これで get_bboxes は終了です

実際には、これで終わりではありません。バッチごとに各画像を個別に作成し、最後に result_list を返すことに注意してください。
画像の説明を追加してください

roi_head.forward_train()

アサイナーとサンプラー
bbox_forward_train() を呼び出した後、この関数は roi_head.forward_train() の本体になります。

bbox_forward_train

この画像は関数の入力で、下の画像は関数の本体です。bbox2roi を含む部分がボックスに ID を追加して1024, 5 を取得していること
画像の説明を追加してください
がわかります。ここで 5 の最初の値は img_id です

_bbox_forward 明らかに、この部分の内容は
get_targetersです。

画像の説明を追加してください

_bbox_forward(x, キングス)

ここで、roi_extractor は rois を使用することによってのみ取得されます。x には 5 つの層がありますが、ここでは最初の 4 つの層だけを使用して、
roi の特定の出力である 1024 256 7 7 を取得します。

したがって、256 7 7 は完全に接続された層に送信できます。はい、
with_shared_head=False
self.bbox_head(bbox_feats) が最も重要な部分であることは明らかです。

画像の説明を追加してください
次の図は bbox_head の本体を示している
画像の説明を追加してください
ため、bbox_head はフラット化された 2 つの共有全結合層を使用し、次に 2 つの並列全結合層を使用して cls_scores と bbox_pred を取得します。そのため、bbox_pred が
5 つの次元を出力したとしても、5 番目の最初の次元はは角度であるべきであり、ここでは実際には制限を設けていないことがわかります。

以下の図は、bbox_forward によって最終的に返される辞書の内容を示しています。
画像の説明を追加してください

bbox_head.get_targetes

画像の説明を追加してください

get_target_single() を呼び出して single を呼び出す前に、正の例と負の例と gt がサンプル結果から読み取られることがわかります。

以下のラベル出力では、15 が背景、0 ~ 14 が前景を意味する場合、正の例は前に配置され、負の例は後ろに配置されます。負の例には分類損失のみが発生します。
ここでの bbox_targets は 512,5 ですが、その中のすべての負の例に対応する行は 0 であり、重みも 0 であるため、計算には参加しません。

画像の説明を追加してください
実際、それほど明白ではない部分は bbox_targets ですが、肯定的な例の具体的な値は何でしょうか?
実際にはdeltaXYWHAという符号化方式で得られます。(少なくとも、最初の入力が xyxy で、gt が cxcywha、つまり、以下の pos_bboxes、pos_gt_bboxes であることを知っておく必要があります。) get_targets が何を返すかを説明すると、最後の
画像の説明を追加してください
損失ステージに入ることができます。 services 、出力が必要ないため、エンコード後にデコードする必要はありません。

bbox_head.loss

画像の説明を追加してください
ヒントは構成から見ることができます。

画像の説明を追加してください
ここでの pos_bbox_pred は、実際には前の _bbox_forward(x, rois) の出力の一部であり、
実際には特定の予測角度ではなく、エンコーダー後の結果であり、トレーニングに使用され、
bbox_targets は実際には前の bbox_head です。 .get_targets の結果。
画像の説明を追加してください

テスト

画像の説明を追加してください

おすすめ

転載: blog.csdn.net/fei_YuHuo/article/details/125649112