SUM010's picture
Upload 2120 files
7b7527a
# Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
import paddle.nn as nn
import paddle.nn.functional as F
from ppdet.core.workspace import register
from ppdet.modeling.bbox_utils import batch_bbox_overlaps
from ppdet.modeling.transformers import bbox_xyxy_to_cxcywh
__all__ = ['UniformAssigner']
def batch_p_dist(x, y, p=2):
"""
calculate pairwise p_dist, the first index of x and y are batch
return [x.shape[0], y.shape[0]]
"""
x = x.unsqueeze(1)
diff = x - y
return paddle.norm(diff, p=p, axis=list(range(2, diff.dim())))
@register
class UniformAssigner(nn.Layer):
def __init__(self, pos_ignore_thr, neg_ignore_thr, match_times=4):
super(UniformAssigner, self).__init__()
self.pos_ignore_thr = pos_ignore_thr
self.neg_ignore_thr = neg_ignore_thr
self.match_times = match_times
def forward(self, bbox_pred, anchor, gt_bboxes, gt_labels=None):
num_bboxes = bbox_pred.shape[0]
num_gts = gt_bboxes.shape[0]
match_labels = paddle.full([num_bboxes], -1, dtype=paddle.int32)
pred_ious = batch_bbox_overlaps(bbox_pred, gt_bboxes)
pred_max_iou = pred_ious.max(axis=1)
neg_ignore = pred_max_iou > self.neg_ignore_thr
# exclude potential ignored neg samples first, deal with pos samples later
#match_labels: -2(ignore), -1(neg) or >=0(pos_inds)
match_labels = paddle.where(neg_ignore,
paddle.full_like(match_labels, -2),
match_labels)
bbox_pred_c = bbox_xyxy_to_cxcywh(bbox_pred)
anchor_c = bbox_xyxy_to_cxcywh(anchor)
gt_bboxes_c = bbox_xyxy_to_cxcywh(gt_bboxes)
bbox_pred_dist = batch_p_dist(bbox_pred_c, gt_bboxes_c, p=1)
anchor_dist = batch_p_dist(anchor_c, gt_bboxes_c, p=1)
top_pred = bbox_pred_dist.topk(
k=self.match_times, axis=0, largest=False)[1]
top_anchor = anchor_dist.topk(
k=self.match_times, axis=0, largest=False)[1]
tar_pred = paddle.arange(num_gts).expand([self.match_times, num_gts])
tar_anchor = paddle.arange(num_gts).expand([self.match_times, num_gts])
pos_places = paddle.concat([top_pred, top_anchor]).reshape([-1])
pos_inds = paddle.concat([tar_pred, tar_anchor]).reshape([-1])
pos_anchor = anchor[pos_places]
pos_tar_bbox = gt_bboxes[pos_inds]
pos_ious = batch_bbox_overlaps(
pos_anchor, pos_tar_bbox, is_aligned=True)
pos_ignore = pos_ious < self.pos_ignore_thr
pos_inds = paddle.where(pos_ignore,
paddle.full_like(pos_inds, -2), pos_inds)
match_labels[pos_places] = pos_inds
match_labels.stop_gradient = True
pos_keep = ~pos_ignore
if pos_keep.sum() > 0:
pos_places_keep = pos_places[pos_keep]
pos_bbox_pred = bbox_pred[pos_places_keep].reshape([-1, 4])
pos_bbox_tar = pos_tar_bbox[pos_keep].reshape([-1, 4]).detach()
else:
pos_bbox_pred = None
pos_bbox_tar = None
return match_labels, pos_bbox_pred, pos_bbox_tar