ナノデットの読み:(2)陽性サンプルと陰性サンプルの定義(ATSS)

I.はじめに

このブログは主に一部です, 個人的にはコアの1つだと思います. 結局, 正ATSS負のサンプルの選択は非常に重要です.ATSS論文は、パフォーマンスの違いの根本的な原因が正と負の定義にあることを確認しています.サンプル . で使用できる良いポジティブ サンプルとネガティブ サンプルの定義方法は、 モデル大幅の への依存度がこの点は、上記の「陽性サンプルと陰性サンプルの正しい定義により、より高品質の陽性サンプルを導入し、フィッティングを高速化し、モデルのパフォーマンスを向上させることができます」でも確認されています。最初によく書かれたATSS ブログをお勧めします. それを読んだ後、コードを読むことははるかに明確になります. そして、私が書いたコード コメントの ATSS 部分anchor-basedanchor-freeAnchor NumAnchor Sizeyolo v5

2. テキスト

コードに従って要約されたプロセスはATSS次のとおりです。

  1. each をトラバースしground truth、各出力レイヤーをトラバースし、各レイヤーの前の最小距離 (および中心点の距離) を見つけますtopk(ハイパーパラメーター、nanodet中間は9)です出力レイヤーの合計がある場合、それぞれが候補に一致し、配列を出力しますこれらには繰り返しがあるかもしれませんが、問題ではありません。以下にスクリーニング手段があります。L2anchorgt boxanchornanodet3gt27anchorshape=(27, gt_num)anchor
  2. gtそれに対応する27各sumanchorの値を計算しますIOU(これはsum ではなく、左上と右下の座標で行われることshape=(27, gt_num)に注意してください。まだ到着していない正と負のサンプルを分類するためのものです)。anchorioubboxanchorbbox
  3. gt列 ごとに対応する各27IOUの平均mean_IOUと標準偏差を計算しstd_IOU、2 つを加算して各gt適応しきい値を取得しますshape = (gt_num, )
  4. それらgtのそれぞれから、対応する適応しきい値よりも大きいものを除外します27anchorIOUanchor
  5. anchor次に、各中心から対応する 4 つの境界線までの距離を計算しgt、4 つの距離の中で最小値を取り、最小値が より小さいものを除外します。0.01残りanchorは選択された正のサンプルです。
  6. anchorこの時点で、複数の一致が同時に存在する可能性がありますgt.このとき、IOU最大の値を持つものをgt一致オブジェクトとして選択する必要があります。つまり、1 つはanchor1 つのみにしか一致できませんgtが、1 つは同時に複数と一致するgt可能性があります。anchcor

上記のプロセスから、anchor陽性サンプルになるための 3 つの条件を満たす必要があります:
① その中心と任意の中心との間の距離が上gtにある必要がありますtopk(昇順で);
② その値が対応するしきい値よりも大きい必要があります; ③その値が対応するしきい値よりも大きい必要があります。中心と4 つの辺の間の距離は より大きい必要がありますこれは疑問と思考につながります: 1. なぜ IOU 閾値は平均と標準偏差の合計を取るのですか? 個人的理解度: 平均は候補者と全体の一致度を表し、平均値が大きいほど全体的な一致度が高く、候補者の質が高いことを示します。標準偏差はデータの分散度を表しており、標準偏差が大きいほど、候補と一致度の差、つまり候補間の品質差が大きくなります。この 2 つを組み合わせることで、多くの低品質の候補を除外できますgtiouiou
gt0.01


anchorgtanchoranchorgtanchoranchor

anchor2.中心から四辺gtまでの距離で候補者を選別する必要があるのはなぜですかanchor?
個人的な理解:ATSSこの論文では、中心だけが内側anchorにある必要があります。コードが実装されると、より大きなものに変更され私の個人的な理解はアイデアに基づいています。次に問題は、中心が内側にある理由です。なぜなら、それは学習中心から4 つの境界までの距離であり、4 つの学習距離はすべて正の数だからです (以下のコードを参照)。中心が外側にある場合、モデルは引き戻された負の数を学習できません。第二に、センターは内部にあるため、学習する機能がさらに多くあります。gtgt00.01label smoothsoftmax 函数0
anchorgtnanodetanchorgtanchorgtanchorgtanchor

# 下面是 bbox 输出处理成 bbox 坐标的处理函数
class Integral(nn.Module):
    def __init__(self, reg_max=16):
        super(Integral, self).__init__()
        self.reg_max = reg_max  # 7
        self.register_buffer(
            "project", torch.linspace(0, self.reg_max, self.reg_max + 1)  # 返回一维 tensor = [0, 1, 2, 3, ... reg_max]
        )

    def forward(self, x):  # 输入 x 就是原始 bbox 输出
        x = F.softmax(x.reshape(-1, self.reg_max + 1), dim=1)  # softmax 之后,数据就是 (0, 1)之间了
        x = F.linear(x, self.project.type_as(x)).reshape(-1, 4)  # 与 self.project 做矩阵相乘,返回 (0, reg_max) 之间的数
        return x  # x 中每个元素都正数

gt最後にお聞きしますが、社内でセンターとしての要件を上げてもanchorよろしいでしょうか?この場合、1 つはgt各出力層の 1 つにしか対応できずanchor、高品質のポジティブ サンプルが削減されます. 前述のように、より高品質のポジティブ サンプルは、フィッティングを高速化し、モデルのパフォーマンスを向上させることができます.
3.なぜ追加するのですかgt_idx * num_bboxes
個人的な理解:

# num_gt 是一张图片中 gt 数目,num_bboxes 是 anchor 数目
# 下面是疑惑 1
for gt_idx in range(num_gt):  # (topk * 3, num_gt)
            candidate_idxs[:, gt_idx] += gt_idx * num_bboxes 
ep_bboxes_cx = (  # (num_bboxes, ) -> (1, num_bboxes) -> (num_gt, num_bboxes) -> (num_gt * num_bboxes)
            bboxes_cx.view(1, -1).expand(num_gt, num_bboxes).contiguous().view(-1)  # 注意它的长度是 num_gt * num_bboxes
        )
candidate_idxs = candidate_idxs.view(-1)  # (topk * 3 * num_gt)
l_ = ep_bboxes_cx[candidate_idxs].view(-1, num_gt) - gt_bboxes[:, 0]

candidate_idxs = candidate_idxs.view(-1)

最初はなぜこうなったのか分からなかったのですcandidate_idxs[:, gt_idx] += gt_idx * num_bboxes が、よく考えてみると、candidate_idxs初期値の値はすべて相対的なものだから、ということでしょうか。下の写真を見てください。
ここに画像の説明を挿入

candidate_idxsのデータ分布は、上の図の左側のスタイルに似ています. 列の数はground truth現在の入力画像の数であり、各列要素の意味はそれぞれground truthに最も近いインデックス値です (出力レイヤー)、つまり行インデックスであり、3つの出力レイヤーがあるため、最後の. しかし、各列のインデックス値の範囲は です。これは、相対値の意味です。最終的には次元ベクトルになるので相対位置が使えず、行数を考慮しなければならないことも足し算の理由ですしかし、奇妙なことは、行数が、コード内でどのようになっているかということです。これは、最後に処理された配列が、その、行数が正確であるためですtopkanchorshape = (topk, num_gt)nanodetcandidate_idxs.shape = (topk * 3, num_gt)[0, num_bboxes)ep_bboxes_cxview(-1)gt_idx * num_bboxescandidate_idxsnum_gtnum_bboxesep_bboxes_cxshape = (num_gt * num_bboxes)num_bboxes

おすすめ

転載: blog.csdn.net/tangshopping/article/details/125105996