|
|
@@ -12,269 +12,18 @@
|
|
|
# See the License for the specific language governing permissions and
|
|
|
# limitations under the License.
|
|
|
|
|
|
-import copy
|
|
|
from . import cv
|
|
|
from .cv.models.utils.visualize import visualize_detection, draw_pr_curve
|
|
|
-from paddlex.cv.transforms.operators import _NormalizeBox, _PadBox, _BboxXYXY2XYWH
|
|
|
-from paddlex.cv.transforms.batch_operators import BatchCompose, BatchRandomResize, BatchRandomResizeByShort, \
|
|
|
- _BatchPadding, _Gt2YoloTarget
|
|
|
-import paddlex.utils.logging as logging
|
|
|
|
|
|
visualize = visualize_detection
|
|
|
draw_pr_curve = draw_pr_curve
|
|
|
|
|
|
+# detection
|
|
|
+YOLOv3 = cv.models.YOLOv3
|
|
|
+FasterRCNN = cv.models.FasterRCNN
|
|
|
+PPYOLO = cv.models.PPYOLO
|
|
|
+PPYOLOTiny = cv.models.PPYOLOTiny
|
|
|
+PPYOLOv2 = cv.models.PPYOLOv2
|
|
|
|
|
|
-class FasterRCNN(cv.models.FasterRCNN):
|
|
|
- def __init__(self,
|
|
|
- num_classes=81,
|
|
|
- backbone='ResNet50',
|
|
|
- with_fpn=True,
|
|
|
- aspect_ratios=[0.5, 1.0, 2.0],
|
|
|
- anchor_sizes=[32, 64, 128, 256, 512],
|
|
|
- with_dcn=None,
|
|
|
- rpn_cls_loss=None,
|
|
|
- rpn_focal_loss_alpha=None,
|
|
|
- rpn_focal_loss_gamma=None,
|
|
|
- rcnn_bbox_loss=None,
|
|
|
- rcnn_nms=None,
|
|
|
- keep_top_k=100,
|
|
|
- nms_threshold=0.5,
|
|
|
- score_threshold=0.05,
|
|
|
- softnms_sigma=None,
|
|
|
- bbox_assigner=None,
|
|
|
- fpn_num_channels=256,
|
|
|
- input_channel=None,
|
|
|
- rpn_batch_size_per_im=256,
|
|
|
- rpn_fg_fraction=0.5,
|
|
|
- test_pre_nms_top_n=None,
|
|
|
- test_post_nms_top_n=1000):
|
|
|
- if with_dcn is not None:
|
|
|
- logging.warning(
|
|
|
- "`with_dcn` is deprecated in PaddleX 2.0 and won't take effect. Defaults to False."
|
|
|
- )
|
|
|
- if rpn_cls_loss is not None:
|
|
|
- logging.warning(
|
|
|
- "`rpn_cls_loss` is deprecated in PaddleX 2.0 and won't take effect. "
|
|
|
- "Defaults to 'SigmoidCrossEntropy'.")
|
|
|
- if rpn_focal_loss_alpha is not None or rpn_focal_loss_gamma is not None:
|
|
|
- logging.warning(
|
|
|
- "Focal loss is deprecated in PaddleX 2.0."
|
|
|
- " `rpn_focal_loss_alpha` and `rpn_focal_loss_gamma` won't take effect."
|
|
|
- )
|
|
|
- if rcnn_bbox_loss is not None:
|
|
|
- logging.warning(
|
|
|
- "`rcnn_bbox_loss` is deprecated in PaddleX 2.0 and won't take effect. "
|
|
|
- "Defaults to 'SmoothL1Loss'")
|
|
|
- if rcnn_nms is not None:
|
|
|
- logging.warning(
|
|
|
- "MultiClassSoftNMS is deprecated in PaddleX 2.0. "
|
|
|
- "`rcnn_nms` and `softnms_sigma` won't take effect. MultiClassNMS will be used by default"
|
|
|
- )
|
|
|
- if bbox_assigner is not None:
|
|
|
- logging.warning(
|
|
|
- "`bbox_assigner` is deprecated in PaddleX 2.0 and won't take effect. "
|
|
|
- "Defaults to 'BBoxAssigner'")
|
|
|
- if input_channel is not None:
|
|
|
- logging.warning(
|
|
|
- "`input_channel` is deprecated in PaddleX 2.0 and won't take effect. Defaults to 3."
|
|
|
- )
|
|
|
- if isinstance(anchor_sizes[0], int):
|
|
|
- anchor_sizes = [[size] for size in anchor_sizes]
|
|
|
- super(FasterRCNN, self).__init__(
|
|
|
- num_classes=num_classes - 1,
|
|
|
- backbone=backbone,
|
|
|
- with_fpn=with_fpn,
|
|
|
- aspect_ratios=aspect_ratios,
|
|
|
- anchor_sizes=anchor_sizes,
|
|
|
- keep_top_k=keep_top_k,
|
|
|
- nms_threshold=nms_threshold,
|
|
|
- score_threshold=score_threshold,
|
|
|
- fpn_num_channels=fpn_num_channels,
|
|
|
- rpn_batch_size_per_im=rpn_batch_size_per_im,
|
|
|
- rpn_fg_fraction=rpn_fg_fraction,
|
|
|
- test_pre_nms_top_n=test_pre_nms_top_n,
|
|
|
- test_post_nms_top_n=test_post_nms_top_n)
|
|
|
-
|
|
|
-
|
|
|
-class YOLOv3(cv.models.YOLOv3):
|
|
|
- def __init__(self,
|
|
|
- num_classes=80,
|
|
|
- backbone='MobileNetV1',
|
|
|
- anchors=None,
|
|
|
- anchor_masks=None,
|
|
|
- ignore_threshold=0.7,
|
|
|
- nms_score_threshold=0.01,
|
|
|
- nms_topk=1000,
|
|
|
- nms_keep_topk=100,
|
|
|
- nms_iou_threshold=0.45,
|
|
|
- label_smooth=False,
|
|
|
- train_random_shapes=[
|
|
|
- 320, 352, 384, 416, 448, 480, 512, 544, 576, 608
|
|
|
- ],
|
|
|
- input_channel=None):
|
|
|
- if input_channel is not None:
|
|
|
- logging.warning(
|
|
|
- "`input_channel` is deprecated in PaddleX 2.0 and won't take effect. Defaults to 3."
|
|
|
- )
|
|
|
- if anchors is None:
|
|
|
- anchors = [[10, 13], [16, 30], [33, 23], [30, 61], [62, 45],
|
|
|
- [59, 119], [116, 90], [156, 198], [373, 326]]
|
|
|
- if anchor_masks is None:
|
|
|
- anchor_masks = [[6, 7, 8], [3, 4, 5], [0, 1, 2]]
|
|
|
- super(YOLOv3, self).__init__(
|
|
|
- num_classes=num_classes,
|
|
|
- backbone=backbone,
|
|
|
- anchors=anchors,
|
|
|
- anchor_masks=anchor_masks,
|
|
|
- ignore_threshold=ignore_threshold,
|
|
|
- nms_score_threshold=nms_score_threshold,
|
|
|
- nms_topk=nms_topk,
|
|
|
- nms_keep_topk=nms_keep_topk,
|
|
|
- nms_iou_threshold=nms_iou_threshold,
|
|
|
- label_smooth=label_smooth)
|
|
|
- self.train_random_shapes = train_random_shapes
|
|
|
-
|
|
|
- def _compose_batch_transform(self, transforms, mode='train'):
|
|
|
- if mode == 'train':
|
|
|
- default_batch_transforms = [
|
|
|
- _BatchPadding(pad_to_stride=-1), _NormalizeBox(),
|
|
|
- _PadBox(getattr(self, 'num_max_boxes', 50)), _BboxXYXY2XYWH(),
|
|
|
- _Gt2YoloTarget(
|
|
|
- anchor_masks=self.anchor_masks,
|
|
|
- anchors=self.anchors,
|
|
|
- downsample_ratios=getattr(self, 'downsample_ratios',
|
|
|
- [32, 16, 8]),
|
|
|
- num_classes=self.num_classes)
|
|
|
- ]
|
|
|
- else:
|
|
|
- default_batch_transforms = [_BatchPadding(pad_to_stride=-1)]
|
|
|
- if mode == 'eval' and self.metric == 'voc':
|
|
|
- collate_batch = False
|
|
|
- else:
|
|
|
- collate_batch = True
|
|
|
-
|
|
|
- custom_batch_transforms = []
|
|
|
- random_shape_defined = False
|
|
|
- for i, op in enumerate(transforms.transforms):
|
|
|
- if isinstance(op, (BatchRandomResize, BatchRandomResizeByShort)):
|
|
|
- if mode != 'train':
|
|
|
- raise Exception(
|
|
|
- "{} cannot be present in the {} transforms. ".format(
|
|
|
- op.__class__.__name__, mode) +
|
|
|
- "Please check the {} transforms.".format(mode))
|
|
|
- custom_batch_transforms.insert(0, copy.deepcopy(op))
|
|
|
- random_shape_defined = True
|
|
|
- if not random_shape_defined:
|
|
|
- default_batch_transforms.insert(
|
|
|
- 0,
|
|
|
- BatchRandomResize(
|
|
|
- target_sizes=self.train_random_shapes, interp='RANDOM'))
|
|
|
-
|
|
|
- batch_transforms = BatchCompose(
|
|
|
- custom_batch_transforms + default_batch_transforms,
|
|
|
- collate_batch=collate_batch)
|
|
|
-
|
|
|
- return batch_transforms
|
|
|
-
|
|
|
-
|
|
|
-class PPYOLO(cv.models.PPYOLO):
|
|
|
- def __init__(
|
|
|
- self,
|
|
|
- num_classes=80,
|
|
|
- backbone='ResNet50_vd_ssld',
|
|
|
- with_dcn_v2=None,
|
|
|
- # YOLO Head
|
|
|
- anchors=None,
|
|
|
- anchor_masks=None,
|
|
|
- use_coord_conv=True,
|
|
|
- use_iou_aware=True,
|
|
|
- use_spp=True,
|
|
|
- use_drop_block=True,
|
|
|
- scale_x_y=1.05,
|
|
|
- # PPYOLO Loss
|
|
|
- ignore_threshold=0.7,
|
|
|
- label_smooth=False,
|
|
|
- use_iou_loss=True,
|
|
|
- # NMS
|
|
|
- use_matrix_nms=True,
|
|
|
- nms_score_threshold=0.01,
|
|
|
- nms_topk=1000,
|
|
|
- nms_keep_topk=100,
|
|
|
- nms_iou_threshold=0.45,
|
|
|
- train_random_shapes=[
|
|
|
- 320, 352, 384, 416, 448, 480, 512, 544, 576, 608
|
|
|
- ],
|
|
|
- input_channel=None):
|
|
|
- if backbone == 'ResNet50_vd_ssld':
|
|
|
- backbone = 'ResNet50_vd_dcn'
|
|
|
- if with_dcn_v2 is not None:
|
|
|
- logging.warning(
|
|
|
- "`with_dcn_v2` is deprecated in PaddleX 2.0 and will not take effect. "
|
|
|
- "To use backbone with deformable convolutional networks, "
|
|
|
- "please specify in `backbone_name`. "
|
|
|
- "Currently the only backbone with dcn is 'ResNet50_vd_dcn'.")
|
|
|
- if input_channel is not None:
|
|
|
- logging.warning(
|
|
|
- "`input_channel` is deprecated in PaddleX 2.0 and won't take effect. Defaults to 3."
|
|
|
- )
|
|
|
- super(PPYOLO, self).__init__(
|
|
|
- num_classes=num_classes,
|
|
|
- backbone=backbone,
|
|
|
- anchors=anchors,
|
|
|
- anchor_masks=anchor_masks,
|
|
|
- use_coord_conv=use_coord_conv,
|
|
|
- use_iou_aware=use_iou_aware,
|
|
|
- use_spp=use_spp,
|
|
|
- use_drop_block=use_drop_block,
|
|
|
- scale_x_y=scale_x_y,
|
|
|
- ignore_threshold=ignore_threshold,
|
|
|
- label_smooth=label_smooth,
|
|
|
- use_iou_loss=use_iou_loss,
|
|
|
- use_matrix_nms=use_matrix_nms,
|
|
|
- nms_score_threshold=nms_score_threshold,
|
|
|
- nms_topk=nms_topk,
|
|
|
- nms_keep_topk=nms_keep_topk,
|
|
|
- nms_iou_threshold=nms_iou_threshold)
|
|
|
- self.train_random_shapes = train_random_shapes
|
|
|
-
|
|
|
- def _compose_batch_transform(self, transforms, mode='train'):
|
|
|
- if mode == 'train':
|
|
|
- default_batch_transforms = [
|
|
|
- _BatchPadding(pad_to_stride=-1), _NormalizeBox(),
|
|
|
- _PadBox(getattr(self, 'num_max_boxes', 50)), _BboxXYXY2XYWH(),
|
|
|
- _Gt2YoloTarget(
|
|
|
- anchor_masks=self.anchor_masks,
|
|
|
- anchors=self.anchors,
|
|
|
- downsample_ratios=getattr(self, 'downsample_ratios',
|
|
|
- [32, 16, 8]),
|
|
|
- num_classes=self.num_classes)
|
|
|
- ]
|
|
|
- else:
|
|
|
- default_batch_transforms = [_BatchPadding(pad_to_stride=-1)]
|
|
|
- if mode == 'eval' and self.metric == 'voc':
|
|
|
- collate_batch = False
|
|
|
- else:
|
|
|
- collate_batch = True
|
|
|
-
|
|
|
- custom_batch_transforms = []
|
|
|
- random_shape_defined = False
|
|
|
- for i, op in enumerate(transforms.transforms):
|
|
|
- if isinstance(op, (BatchRandomResize, BatchRandomResizeByShort)):
|
|
|
- if mode != 'train':
|
|
|
- raise Exception(
|
|
|
- "{} cannot be present in the {} transforms. ".format(
|
|
|
- op.__class__.__name__, mode) +
|
|
|
- "Please check the {} transforms.".format(mode))
|
|
|
- custom_batch_transforms.insert(0, copy.deepcopy(op))
|
|
|
- random_shape_defined = True
|
|
|
- if not random_shape_defined:
|
|
|
- default_batch_transforms.insert(
|
|
|
- 0,
|
|
|
- BatchRandomResize(
|
|
|
- target_sizes=self.train_random_shapes, interp='RANDOM'))
|
|
|
-
|
|
|
- batch_transforms = BatchCompose(
|
|
|
- custom_batch_transforms + default_batch_transforms,
|
|
|
- collate_batch=collate_batch)
|
|
|
-
|
|
|
- return batch_transforms
|
|
|
+# instance segmentation
|
|
|
+MaskRCNN = cv.models.MaskRCNN
|