You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
111 lines
4.0 KiB
111 lines
4.0 KiB
# 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 |
|
from paddlers.models.ppdet.core.workspace import register |
|
from paddlers.models.ppdet.modeling import ops |
|
|
|
|
|
def _to_list(v): |
|
if not isinstance(v, (list, tuple)): |
|
return [v] |
|
return v |
|
|
|
|
|
@register |
|
class RoIAlign(object): |
|
""" |
|
RoI Align module |
|
|
|
For more details, please refer to the document of roi_align in |
|
in ppdet/modeing/ops.py |
|
|
|
Args: |
|
resolution (int): The output size, default 14 |
|
spatial_scale (float): Multiplicative spatial scale factor to translate |
|
ROI coords from their input scale to the scale used when pooling. |
|
default 0.0625 |
|
sampling_ratio (int): The number of sampling points in the interpolation |
|
grid, default 0 |
|
canconical_level (int): The referring level of FPN layer with |
|
specified level. default 4 |
|
canonical_size (int): The referring scale of FPN layer with |
|
specified scale. default 224 |
|
start_level (int): The start level of FPN layer to extract RoI feature, |
|
default 0 |
|
end_level (int): The end level of FPN layer to extract RoI feature, |
|
default 3 |
|
aligned (bool): Whether to add offset to rois' coord in roi_align. |
|
default false |
|
""" |
|
|
|
def __init__(self, |
|
resolution=14, |
|
spatial_scale=0.0625, |
|
sampling_ratio=0, |
|
canconical_level=4, |
|
canonical_size=224, |
|
start_level=0, |
|
end_level=3, |
|
aligned=False): |
|
super(RoIAlign, self).__init__() |
|
self.resolution = resolution |
|
self.spatial_scale = _to_list(spatial_scale) |
|
self.sampling_ratio = sampling_ratio |
|
self.canconical_level = canconical_level |
|
self.canonical_size = canonical_size |
|
self.start_level = start_level |
|
self.end_level = end_level |
|
self.aligned = aligned |
|
|
|
@classmethod |
|
def from_config(cls, cfg, input_shape): |
|
return {'spatial_scale': [1. / i.stride for i in input_shape]} |
|
|
|
def __call__(self, feats, roi, rois_num): |
|
roi = paddle.concat(roi) if len(roi) > 1 else roi[0] |
|
if len(feats) == 1: |
|
rois_feat = ops.roi_align( |
|
feats[self.start_level], |
|
roi, |
|
self.resolution, |
|
self.spatial_scale[0], |
|
rois_num=rois_num, |
|
aligned=self.aligned) |
|
else: |
|
offset = 2 |
|
k_min = self.start_level + offset |
|
k_max = self.end_level + offset |
|
rois_dist, restore_index, rois_num_dist = ops.distribute_fpn_proposals( |
|
roi, |
|
k_min, |
|
k_max, |
|
self.canconical_level, |
|
self.canonical_size, |
|
rois_num=rois_num) |
|
rois_feat_list = [] |
|
for lvl in range(self.start_level, self.end_level + 1): |
|
roi_feat = ops.roi_align( |
|
feats[lvl], |
|
rois_dist[lvl], |
|
self.resolution, |
|
self.spatial_scale[lvl], |
|
sampling_ratio=self.sampling_ratio, |
|
rois_num=rois_num_dist[lvl], |
|
aligned=self.aligned) |
|
rois_feat_list.append(roi_feat) |
|
rois_feat_shuffle = paddle.concat(rois_feat_list) |
|
rois_feat = paddle.gather(rois_feat_shuffle, restore_index) |
|
|
|
return rois_feat
|
|
|