mirror of
https://github.com/modelscope/modelscope.git
synced 2026-09-01 19:49:03 +02:00
remove easycv codes, plugin access
Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/11965727 * remove easycv codes * fix custome msdatasets import and remove metainfo * fix pipeline imports * fix pre-check * fix models import * fix pre-check * merge master
This commit is contained in:
committed by
wenmeng.zwm
parent
038c5fea48
commit
46072898da
@@ -118,13 +118,6 @@ class Models(object):
|
||||
longshortnet = 'longshortnet'
|
||||
pedestrian_attribute_recognition = 'pedestrian-attribute-recognition'
|
||||
|
||||
# EasyCV models
|
||||
yolox = 'YOLOX'
|
||||
segformer = 'Segformer'
|
||||
hand_2d_keypoints = 'HRNet-Hand2D-Keypoints'
|
||||
image_object_detection_auto = 'image-object-detection-auto'
|
||||
dino = 'DINO'
|
||||
|
||||
# nlp models
|
||||
bert = 'bert'
|
||||
palm = 'palm-v2'
|
||||
@@ -279,8 +272,6 @@ class Pipelines(object):
|
||||
tbs_detection = 'tbs-detection'
|
||||
object_detection = 'vit-object-detection'
|
||||
abnormal_object_detection = 'abnormal-object-detection'
|
||||
easycv_detection = 'easycv-detection'
|
||||
easycv_segmentation = 'easycv-segmentation'
|
||||
face_2d_keypoints = 'mobilenet_face-2d-keypoints_alignment'
|
||||
salient_detection = 'u2net-salient-detection'
|
||||
salient_boudary_detection = 'res2net-salient-detection'
|
||||
@@ -349,7 +340,6 @@ class Pipelines(object):
|
||||
video_single_object_tracking_procontext = 'procontext-vitb-video-single-object-tracking'
|
||||
video_multi_object_tracking = 'video-multi-object-tracking'
|
||||
image_panoptic_segmentation = 'image-panoptic-segmentation'
|
||||
image_panoptic_segmentation_easycv = 'image-panoptic-segmentation-easycv'
|
||||
video_summarization = 'googlenet_pgl_video_summarization'
|
||||
language_guided_video_summarization = 'clip-it-video-summarization'
|
||||
image_semantic_segmentation = 'image-semantic-segmentation'
|
||||
@@ -914,7 +904,6 @@ class Trainers(CVTrainers, NLPTrainers, MultiModalTrainers, AudioTrainers):
|
||||
"""
|
||||
|
||||
default = 'trainer'
|
||||
easycv = 'easycv'
|
||||
tinynas_damoyolo = 'tinynas-damoyolo'
|
||||
|
||||
@staticmethod
|
||||
@@ -936,8 +925,6 @@ class Trainers(CVTrainers, NLPTrainers, MultiModalTrainers, AudioTrainers):
|
||||
return Fields.multi_modal
|
||||
elif attribute_or_value == Trainers.default:
|
||||
return Trainers.default
|
||||
elif attribute_or_value == Trainers.easycv:
|
||||
return Trainers.easycv
|
||||
else:
|
||||
return 'unknown'
|
||||
|
||||
@@ -1168,14 +1155,6 @@ class LR_Schedulers(object):
|
||||
class CustomDatasets(object):
|
||||
""" Names for different datasets.
|
||||
"""
|
||||
ClsDataset = 'ClsDataset'
|
||||
Face2dKeypointsDataset = 'FaceKeypointDataset'
|
||||
HandCocoWholeBodyDataset = 'HandCocoWholeBodyDataset'
|
||||
HumanWholeBodyKeypointDataset = 'WholeBodyCocoTopDownDataset'
|
||||
SegDataset = 'SegDataset'
|
||||
DetDataset = 'DetDataset'
|
||||
DetImagesMixDataset = 'DetImagesMixDataset'
|
||||
PanopticDataset = 'PanopticDataset'
|
||||
PairedDataset = 'PairedDataset'
|
||||
SiddDataset = 'SiddDataset'
|
||||
GoproDataset = 'GoproDataset'
|
||||
|
||||
@@ -4,9 +4,8 @@
|
||||
from . import (action_recognition, animal_recognition, bad_image_detecting,
|
||||
body_2d_keypoints, body_3d_keypoints, cartoon,
|
||||
cmdssl_video_embedding, controllable_image_generation,
|
||||
crowd_counting, face_2d_keypoints, face_detection,
|
||||
face_generation, face_reconstruction, human_reconstruction,
|
||||
human_wholebody_keypoint, image_classification,
|
||||
crowd_counting, face_detection, face_generation,
|
||||
face_reconstruction, human_reconstruction, image_classification,
|
||||
image_color_enhance, image_colorization, image_defrcn_fewshot,
|
||||
image_denoise, image_inpainting, image_instance_segmentation,
|
||||
image_matching, image_mvs_depth_estimation,
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.base import BaseModel
|
||||
from easycv.utils.ms_utils import EasyCVMeta
|
||||
|
||||
from modelscope.models.base import TorchModel
|
||||
|
||||
|
||||
class EasyCVBaseModel(BaseModel, TorchModel):
|
||||
"""Base model for EasyCV."""
|
||||
|
||||
def __init__(self, model_dir=None, args=(), kwargs={}):
|
||||
kwargs.pop(EasyCVMeta.ARCH, None) # pop useless keys
|
||||
BaseModel.__init__(self)
|
||||
TorchModel.__init__(self, model_dir=model_dir)
|
||||
|
||||
def forward(self, img, mode='train', **kwargs):
|
||||
if self.training:
|
||||
losses = self.forward_train(img, **kwargs)
|
||||
loss, log_vars = self._parse_losses(losses)
|
||||
return dict(loss=loss, log_vars=log_vars)
|
||||
else:
|
||||
return self.forward_test(img, **kwargs)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.forward(*args, **kwargs)
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .face_2d_keypoints_align import Face2DKeypoints
|
||||
|
||||
else:
|
||||
_import_structure = {'face_2d_keypoints_align': ['Face2DKeypoints']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,16 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.face.face_keypoint import FaceKeypoint
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.face_2d_keypoints, module_name=Models.face_2d_keypoints)
|
||||
class Face2DKeypoints(EasyCVBaseModel, FaceKeypoint):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
FaceKeypoint.__init__(self, *args, **kwargs)
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .hand_2d_keypoints import Hand2dKeyPoints
|
||||
|
||||
else:
|
||||
_import_structure = {'hand_2d_keypoints': ['Hand2dKeyPoints']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,16 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.pose import TopDown
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.hand_2d_keypoints, module_name=Models.hand_2d_keypoints)
|
||||
class Hand2dKeyPoints(EasyCVBaseModel, TopDown):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
TopDown.__init__(self, *args, **kwargs)
|
||||
@@ -1,22 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .human_wholebody_keypoint import HumanWholeBodyKeypoint
|
||||
|
||||
else:
|
||||
_import_structure = {
|
||||
'human_wholebody_keypoint': ['HumanWholeBodyKeypoint']
|
||||
}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,17 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.pose.top_down import TopDown
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.human_wholebody_keypoint,
|
||||
module_name=Models.human_wholebody_keypoint)
|
||||
class HumanWholeBodyKeypoint(EasyCVBaseModel, TopDown):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
TopDown.__init__(self, *args, **kwargs)
|
||||
@@ -5,7 +5,6 @@ from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .panseg_model import SwinLPanopticSegmentation
|
||||
from .r50_panseg_model import R50PanopticSegmentation
|
||||
|
||||
else:
|
||||
_import_structure = {
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
|
||||
from easycv.models.segmentation import Mask2Former
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.image_segmentation,
|
||||
module_name=Models.r50_panoptic_segmentation)
|
||||
class R50PanopticSegmentation(EasyCVBaseModel, Mask2Former):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
Mask2Former.__init__(self, *args, **kwargs)
|
||||
@@ -1,16 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.segmentation import EncoderDecoder
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.image_segmentation, module_name=Models.segformer)
|
||||
class Segformer(EasyCVBaseModel, EncoderDecoder):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
EncoderDecoder.__init__(self, *args, **kwargs)
|
||||
@@ -1,16 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.detection.detectors import Detection as _Detection
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.image_object_detection, module_name=Models.dino)
|
||||
class DINO(EasyCVBaseModel, _Detection):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
_Detection.__init__(self, *args, **kwargs)
|
||||
@@ -1,21 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.models.detection.detectors import YOLOX as _YOLOX
|
||||
|
||||
from modelscope.metainfo import Models
|
||||
from modelscope.models.builder import MODELS
|
||||
from modelscope.models.cv.easycv_base import EasyCVBaseModel
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.image_object_detection, module_name=Models.yolox)
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.image_object_detection,
|
||||
module_name=Models.image_object_detection_auto)
|
||||
@MODELS.register_module(
|
||||
group_key=Tasks.domain_specific_object_detection, module_name=Models.yolox)
|
||||
class YOLOX(EasyCVBaseModel, _YOLOX):
|
||||
|
||||
def __init__(self, model_dir=None, *args, **kwargs):
|
||||
EasyCVBaseModel.__init__(self, model_dir, args, kwargs)
|
||||
_YOLOX.__init__(self, *args, **kwargs)
|
||||
@@ -27,12 +27,6 @@ if TYPE_CHECKING:
|
||||
from .video_frame_interpolation import VideoFrameInterpolationDataset
|
||||
from .video_stabilization import VideoStabilizationDataset
|
||||
from .video_super_resolution import VideoSuperResolutionDataset
|
||||
from .image_semantic_segmentation import SegDataset
|
||||
from .face_2d_keypoins import FaceKeypointDataset
|
||||
from .hand_2d_keypoints import HandCocoWholeBodyDataset
|
||||
from .human_wholebody_keypoint import WholeBodyCocoTopDownDataset
|
||||
from .image_classification import ClsDataset
|
||||
from .object_detection import DetDataset, DetImagesMixDataset
|
||||
from .ocr_detection import DataLoader, ImageDataset, QuadMeasurer
|
||||
from .ocr_recognition_dataset import OCRRecognitionDataset
|
||||
from .image_colorization import ImageColorizationDataset
|
||||
@@ -66,12 +60,6 @@ else:
|
||||
'video_frame_interpolation': ['VideoFrameInterpolationDataset'],
|
||||
'video_stabilization': ['VideoStabilizationDataset'],
|
||||
'video_super_resolution': ['VideoSuperResolutionDataset'],
|
||||
'image_semantic_segmentation': ['SegDataset'],
|
||||
'face_2d_keypoins': ['FaceKeypointDataset'],
|
||||
'hand_2d_keypoints': ['HandCocoWholeBodyDataset'],
|
||||
'human_wholebody_keypoint': ['WholeBodyCocoTopDownDataset'],
|
||||
'image_classification': ['ClsDataset'],
|
||||
'object_detection': ['DetDataset', 'DetImagesMixDataset'],
|
||||
'ocr_detection': ['DataLoader', 'ImageDataset', 'QuadMeasurer'],
|
||||
'ocr_recognition_dataset': ['OCRRecognitionDataset'],
|
||||
'image_colorization': ['ImageColorizationDataset'],
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .face_2d_keypoints_dataset import FaceKeypointDataset
|
||||
|
||||
else:
|
||||
_import_structure = {'face_2d_keypoints_dataset': ['FaceKeypointDataset']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,38 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.datasets.face import FaceKeypointDataset as _FaceKeypointDataset
|
||||
|
||||
from modelscope.metainfo import CustomDatasets
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \
|
||||
EasyCVBaseDataset
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.face_2d_keypoints,
|
||||
module_name=CustomDatasets.Face2dKeypointsDataset)
|
||||
class FaceKeypointDataset(EasyCVBaseDataset, _FaceKeypointDataset):
|
||||
"""EasyCV dataset for face 2d keypoints.
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_FaceKeypointDataset.__init__(self, *args, **kwargs)
|
||||
@@ -1,22 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .hand_2d_keypoints_dataset import HandCocoWholeBodyDataset
|
||||
|
||||
else:
|
||||
_import_structure = {
|
||||
'hand_2d_keypoints_dataset': ['HandCocoWholeBodyDataset']
|
||||
}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,39 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.datasets.pose import \
|
||||
HandCocoWholeBodyDataset as _HandCocoWholeBodyDataset
|
||||
|
||||
from modelscope.metainfo import CustomDatasets
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \
|
||||
EasyCVBaseDataset
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.hand_2d_keypoints,
|
||||
module_name=CustomDatasets.HandCocoWholeBodyDataset)
|
||||
class HandCocoWholeBodyDataset(EasyCVBaseDataset, _HandCocoWholeBodyDataset):
|
||||
"""EasyCV dataset for human hand 2d keypoints.
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_HandCocoWholeBodyDataset.__init__(self, *args, **kwargs)
|
||||
@@ -1,22 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .human_wholebody_keypoint_dataset import WholeBodyCocoTopDownDataset
|
||||
|
||||
else:
|
||||
_import_structure = {
|
||||
'human_wholebody_keypoint_dataset': ['WholeBodyCocoTopDownDataset']
|
||||
}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,40 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.datasets.pose import \
|
||||
WholeBodyCocoTopDownDataset as _WholeBodyCocoTopDownDataset
|
||||
|
||||
from modelscope.metainfo import CustomDatasets
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \
|
||||
EasyCVBaseDataset
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.human_wholebody_keypoint,
|
||||
module_name=CustomDatasets.HumanWholeBodyKeypointDataset)
|
||||
class WholeBodyCocoTopDownDataset(EasyCVBaseDataset,
|
||||
_WholeBodyCocoTopDownDataset):
|
||||
"""EasyCV dataset for human whole body 2d keypoints.
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_WholeBodyCocoTopDownDataset.__init__(self, *args, **kwargs)
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .classification_dataset import ClsDataset
|
||||
|
||||
else:
|
||||
_import_structure = {'classification_dataset': ['ClsDataset']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,38 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.datasets.classification import ClsDataset as _ClsDataset
|
||||
|
||||
from modelscope.metainfo import CustomDatasets
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \
|
||||
EasyCVBaseDataset
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.image_classification,
|
||||
module_name=CustomDatasets.ClsDataset)
|
||||
class ClsDataset(_ClsDataset):
|
||||
"""EasyCV dataset for classification.
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_ClsDataset.__init__(self, *args, **kwargs)
|
||||
@@ -1,20 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .segmentation_dataset import SegDataset
|
||||
|
||||
else:
|
||||
_import_structure = {'easycv_segmentation': ['SegDataset']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,43 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from easycv.datasets.segmentation import SegDataset as _SegDataset
|
||||
|
||||
from modelscope.metainfo import CustomDatasets
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \
|
||||
EasyCVBaseDataset
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.image_segmentation, module_name=CustomDatasets.SegDataset)
|
||||
class SegDataset(EasyCVBaseDataset, _SegDataset):
|
||||
"""EasyCV dataset for Sementic segmentation.
|
||||
For more details, please refer to :
|
||||
https://github.com/alibaba/EasyCV/blob/master/easycv/datasets/segmentation/raw.py .
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
data_source: Data source config to parse input data.
|
||||
pipeline: Sequence of transform object or config dict to be composed.
|
||||
ignore_index (int): Label index to be ignored.
|
||||
profiling: If set True, will print transform time.
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_SegDataset.__init__(self, *args, **kwargs)
|
||||
@@ -1,22 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .detection_dataset import DetDataset, DetImagesMixDataset
|
||||
|
||||
else:
|
||||
_import_structure = {
|
||||
'detection_dataset': ['DetDataset', 'DetImagesMixDataset']
|
||||
}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,98 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
|
||||
from easycv.datasets.detection import DetDataset as _DetDataset
|
||||
from easycv.datasets.detection import \
|
||||
DetImagesMixDataset as _DetImagesMixDataset
|
||||
|
||||
from modelscope.metainfo import CustomDatasets
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets import CUSTOM_DATASETS
|
||||
from modelscope.msdatasets.dataset_cls.custom_datasets.easycv_base import \
|
||||
EasyCVBaseDataset
|
||||
from modelscope.utils.constant import Tasks
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.image_object_detection,
|
||||
module_name=CustomDatasets.DetDataset)
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.image_segmentation, module_name=CustomDatasets.DetDataset)
|
||||
class DetDataset(EasyCVBaseDataset, _DetDataset):
|
||||
"""EasyCV dataset for object detection.
|
||||
For more details, please refer to https://github.com/alibaba/EasyCV/blob/master/easycv/datasets/detection/raw.py .
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
data_source: Data source config to parse input data.
|
||||
pipeline: Transform config list
|
||||
profiling: If set True, will print pipeline time
|
||||
classes: A list of class names, used in evaluation for result and groundtruth visualization
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_DetDataset.__init__(self, *args, **kwargs)
|
||||
|
||||
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.image_object_detection,
|
||||
module_name=CustomDatasets.DetImagesMixDataset)
|
||||
@CUSTOM_DATASETS.register_module(
|
||||
group_key=Tasks.domain_specific_object_detection,
|
||||
module_name=CustomDatasets.DetImagesMixDataset)
|
||||
class DetImagesMixDataset(EasyCVBaseDataset, _DetImagesMixDataset):
|
||||
"""EasyCV dataset for object detection, a wrapper of multiple images mixed dataset.
|
||||
Suitable for training on multiple images mixed data augmentation like
|
||||
mosaic and mixup. For the augmentation pipeline of mixed image data,
|
||||
the `get_indexes` method needs to be provided to obtain the image
|
||||
indexes, and you can set `skip_flags` to change the pipeline running
|
||||
process. At the same time, we provide the `dynamic_scale` parameter
|
||||
to dynamically change the output image size.
|
||||
output boxes format: cx, cy, w, h
|
||||
|
||||
For more details, please refer to https://github.com/alibaba/EasyCV/blob/master/easycv/datasets/detection/mix.py .
|
||||
|
||||
Args:
|
||||
split_config (dict): Dataset root path from MSDataset, e.g.
|
||||
{"train":"local cache path"} or {"evaluation":"local cache path"}.
|
||||
preprocessor (Preprocessor): An optional preprocessor instance, please make sure the preprocessor fits for
|
||||
the model if supplied. Not support yet.
|
||||
mode: Training or Evaluation.
|
||||
data_source (:obj:`DetSourceCoco`): Data source config to parse input data.
|
||||
pipeline (Sequence[dict]): Sequence of transform object or
|
||||
config dict to be composed.
|
||||
dynamic_scale (tuple[int], optional): The image scale can be changed
|
||||
dynamically. Default to None.
|
||||
skip_type_keys (list[str], optional): Sequence of type string to
|
||||
be skip pipeline. Default to None.
|
||||
label_padding: out labeling padding [N, 120, 5]
|
||||
"""
|
||||
|
||||
def __init__(self,
|
||||
split_config=None,
|
||||
preprocessor=None,
|
||||
mode=None,
|
||||
*args,
|
||||
**kwargs) -> None:
|
||||
EasyCVBaseDataset.__init__(
|
||||
self,
|
||||
split_config=split_config,
|
||||
preprocessor=preprocessor,
|
||||
mode=mode,
|
||||
args=args,
|
||||
kwargs=kwargs)
|
||||
_DetImagesMixDataset.__init__(self, *args, **kwargs)
|
||||
@@ -9,7 +9,6 @@ if TYPE_CHECKING:
|
||||
from .animal_recognition_pipeline import AnimalRecognitionPipeline
|
||||
from .body_2d_keypoints_pipeline import Body2DKeypointsPipeline
|
||||
from .body_3d_keypoints_pipeline import Body3DKeypointsPipeline
|
||||
from .hand_2d_keypoints_pipeline import Hand2DKeypointsPipeline
|
||||
from .cmdssl_video_embedding_pipeline import CMDSSLVideoEmbeddingPipeline
|
||||
from .card_detection_pipeline import CardDetectionPipeline
|
||||
from .hicossl_video_embedding_pipeline import HICOSSLVideoEmbeddingPipeline
|
||||
@@ -29,13 +28,10 @@ if TYPE_CHECKING:
|
||||
from .image_classification_pipeline import GeneralImageClassificationPipeline
|
||||
from .image_color_enhance_pipeline import ImageColorEnhancePipeline
|
||||
from .image_colorization_pipeline import ImageColorizationPipeline
|
||||
from .image_classification_pipeline import ImageClassificationPipeline
|
||||
from .image_denoise_pipeline import ImageDenoisePipeline
|
||||
from .image_deblur_pipeline import ImageDeblurPipeline
|
||||
from .image_instance_segmentation_pipeline import ImageInstanceSegmentationPipeline
|
||||
from .image_matting_pipeline import ImageMattingPipeline
|
||||
from .image_panoptic_segmentation_pipeline import ImagePanopticSegmentationPipeline
|
||||
from .image_semantic_segmentation_pipeline import ImagePanopticSegmentationEasyCVPipeline
|
||||
from .image_portrait_enhancement_pipeline import ImagePortraitEnhancementPipeline
|
||||
from .image_reid_person_pipeline import ImageReidPersonPipeline
|
||||
from .image_semantic_segmentation_pipeline import ImageSemanticSegmentationPipeline
|
||||
@@ -46,7 +42,6 @@ if TYPE_CHECKING:
|
||||
from .image_inpainting_pipeline import ImageInpaintingPipeline
|
||||
from .image_paintbyexample_pipeline import ImagePaintbyexamplePipeline
|
||||
from .product_retrieval_embedding_pipeline import ProductRetrievalEmbeddingPipeline
|
||||
from .realtime_object_detection_pipeline import RealtimeObjectDetectionPipeline
|
||||
from .live_category_pipeline import LiveCategoryPipeline
|
||||
from .ocr_detection_pipeline import OCRDetectionPipeline
|
||||
from .ocr_recognition_pipeline import OCRRecognitionPipeline
|
||||
@@ -59,10 +54,6 @@ if TYPE_CHECKING:
|
||||
from .video_category_pipeline import VideoCategoryPipeline
|
||||
from .virtual_try_on_pipeline import VirtualTryonPipeline
|
||||
from .shop_segmentation_pipleline import ShopSegmentationPipeline
|
||||
from .easycv_pipelines import (EasyCVDetectionPipeline,
|
||||
EasyCVSegmentationPipeline,
|
||||
Face2DKeypointsPipeline,
|
||||
HumanWholebodyKeypointsPipeline)
|
||||
from .text_driven_segmentation_pipleline import TextDrivenSegmentationPipeline
|
||||
from .movie_scene_segmentation_pipeline import MovieSceneSegmentationPipeline
|
||||
from .mog_face_detection_pipeline import MogFaceDetectionPipeline
|
||||
@@ -123,7 +114,6 @@ else:
|
||||
'animal_recognition_pipeline': ['AnimalRecognitionPipeline'],
|
||||
'body_2d_keypoints_pipeline': ['Body2DKeypointsPipeline'],
|
||||
'body_3d_keypoints_pipeline': ['Body3DKeypointsPipeline'],
|
||||
'hand_2d_keypoints_pipeline': ['Hand2DKeypointsPipeline'],
|
||||
'card_detection_pipeline': ['CardDetectionPipeline'],
|
||||
'cmdssl_video_embedding_pipeline': ['CMDSSLVideoEmbeddingPipeline'],
|
||||
'hicossl_video_embedding_pipeline': ['HICOSSLVideoEmbeddingPipeline'],
|
||||
@@ -140,7 +130,7 @@ else:
|
||||
'face_recognition_onnx_fm_pipeline': ['FaceRecognitionOnnxFmPipeline'],
|
||||
'general_recognition_pipeline': ['GeneralRecognitionPipeline'],
|
||||
'image_classification_pipeline':
|
||||
['GeneralImageClassificationPipeline', 'ImageClassificationPipeline'],
|
||||
['GeneralImageClassificationPipeline'],
|
||||
'image_cartoon_pipeline': ['ImageCartoonPipeline'],
|
||||
'image_denoise_pipeline': ['ImageDenoisePipeline'],
|
||||
'image_deblur_pipeline': ['ImageDeblurPipeline'],
|
||||
@@ -149,10 +139,6 @@ else:
|
||||
'image_instance_segmentation_pipeline':
|
||||
['ImageInstanceSegmentationPipeline'],
|
||||
'image_matting_pipeline': ['ImageMattingPipeline'],
|
||||
'image_panoptic_segmentation_pipeline': [
|
||||
'ImagePanopticSegmentationPipeline',
|
||||
'ImagePanopticSegmentationEasyCVPipeline'
|
||||
],
|
||||
'image_portrait_enhancement_pipeline':
|
||||
['ImagePortraitEnhancementPipeline'],
|
||||
'image_reid_person_pipeline': ['ImageReidPersonPipeline'],
|
||||
@@ -164,8 +150,6 @@ else:
|
||||
['Image2ImageTranslationPipeline'],
|
||||
'product_retrieval_embedding_pipeline':
|
||||
['ProductRetrievalEmbeddingPipeline'],
|
||||
'realtime_object_detection_pipeline':
|
||||
['RealtimeObjectDetectionPipeline'],
|
||||
'live_category_pipeline': ['LiveCategoryPipeline'],
|
||||
'image_to_image_generate_pipeline': ['Image2ImageGenerationPipeline'],
|
||||
'image_inpainting_pipeline': ['ImageInpaintingPipeline'],
|
||||
@@ -180,12 +164,6 @@ else:
|
||||
'video_category_pipeline': ['VideoCategoryPipeline'],
|
||||
'virtual_try_on_pipeline': ['VirtualTryonPipeline'],
|
||||
'shop_segmentation_pipleline': ['ShopSegmentationPipeline'],
|
||||
'easycv_pipelines': [
|
||||
'EasyCVDetectionPipeline',
|
||||
'EasyCVSegmentationPipeline',
|
||||
'Face2DKeypointsPipeline',
|
||||
'HumanWholebodyKeypointsPipeline',
|
||||
],
|
||||
'text_driven_segmentation_pipleline':
|
||||
['TextDrivenSegmentationPipeline'],
|
||||
'movie_scene_segmentation_pipeline':
|
||||
@@ -202,9 +180,8 @@ else:
|
||||
['FaceAttributeRecognitionPipeline'],
|
||||
'mtcnn_face_detection_pipeline': ['MtcnnFaceDetectionPipeline'],
|
||||
'hand_static_pipeline': ['HandStaticPipeline'],
|
||||
'referring_video_object_segmentation_pipeline': [
|
||||
'ReferringVideoObjectSegmentationPipeline'
|
||||
],
|
||||
'referring_video_object_segmentation_pipeline':
|
||||
['ReferringVideoObjectSegmentationPipeline'],
|
||||
'language_guided_video_summarization_pipeline': [
|
||||
'LanguageGuidedVideoSummarizationPipeline'
|
||||
],
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .detection_pipeline import EasyCVDetectionPipeline
|
||||
from .segmentation_pipeline import EasyCVSegmentationPipeline
|
||||
from .face_2d_keypoints_pipeline import Face2DKeypointsPipeline
|
||||
from .human_wholebody_keypoint_pipeline import HumanWholebodyKeypointsPipeline
|
||||
else:
|
||||
_import_structure = {
|
||||
'detection_pipeline': ['EasyCVDetectionPipeline'],
|
||||
'segmentation_pipeline': ['EasyCVSegmentationPipeline'],
|
||||
'face_2d_keypoints_pipeline': ['Face2DKeypointsPipeline'],
|
||||
'human_wholebody_keypoint_pipeline':
|
||||
['HumanWholebodyKeypointsPipeline'],
|
||||
}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,123 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import os.path as osp
|
||||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
from easycv.utils.ms_utils import EasyCVMeta
|
||||
from PIL import ImageFile
|
||||
|
||||
from modelscope.hub.snapshot_download import snapshot_download
|
||||
from modelscope.pipelines.util import is_official_hub_path
|
||||
from modelscope.utils.config import Config
|
||||
from modelscope.utils.constant import (DEFAULT_MODEL_REVISION, Invoke,
|
||||
ModelFile, ThirdParty)
|
||||
from modelscope.utils.device import create_device
|
||||
|
||||
|
||||
class EasyCVPipeline(object):
|
||||
"""Base pipeline for EasyCV.
|
||||
Loading configuration file of modelscope style by default,
|
||||
but it is actually use the predictor api of easycv to predict.
|
||||
So here we do some adaptation work for configuration and predict api.
|
||||
"""
|
||||
|
||||
def __init__(self, model: str, model_file_pattern='*.pt', *args, **kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
|
||||
"""
|
||||
self.model_file_pattern = model_file_pattern
|
||||
|
||||
assert isinstance(model, str)
|
||||
if osp.exists(model):
|
||||
model_dir = model
|
||||
else:
|
||||
assert is_official_hub_path(
|
||||
model), 'Only support local model path and official hub path!'
|
||||
model_dir = snapshot_download(
|
||||
model_id=model,
|
||||
revision=DEFAULT_MODEL_REVISION,
|
||||
user_agent={
|
||||
Invoke.KEY: Invoke.PIPELINE,
|
||||
ThirdParty.KEY: ThirdParty.EASYCV
|
||||
})
|
||||
|
||||
assert osp.isdir(model_dir)
|
||||
model_files = glob.glob(
|
||||
os.path.join(model_dir, self.model_file_pattern))
|
||||
assert len(
|
||||
model_files
|
||||
) == 1, f'Need one model file, but find {len(model_files)}: {model_files}'
|
||||
|
||||
model_path = model_files[0]
|
||||
self.model_path = model_path
|
||||
self.model_dir = model_dir
|
||||
|
||||
# get configuration file from source model dir
|
||||
self.config_file = os.path.join(model_dir, ModelFile.CONFIGURATION)
|
||||
assert os.path.exists(
|
||||
self.config_file
|
||||
), f'Not find "{ModelFile.CONFIGURATION}" in model directory!'
|
||||
|
||||
self.cfg = Config.from_file(self.config_file)
|
||||
if 'device' in kwargs:
|
||||
kwargs['device'] = create_device(kwargs['device'])
|
||||
if 'predictor_config' in kwargs:
|
||||
kwargs.pop('predictor_config')
|
||||
self.predict_op = self._build_predict_op(**kwargs)
|
||||
|
||||
def _build_predict_op(self, **kwargs):
|
||||
"""Build EasyCV predictor."""
|
||||
from easycv.predictors.builder import build_predictor
|
||||
|
||||
easycv_config = self._to_easycv_config()
|
||||
pipeline_op = build_predictor(self.cfg.pipeline.predictor_config, {
|
||||
'model_path': self.model_path,
|
||||
'config_file': easycv_config,
|
||||
**kwargs
|
||||
})
|
||||
return pipeline_op
|
||||
|
||||
def _to_easycv_config(self):
|
||||
"""Adapt to EasyCV predictor."""
|
||||
# TODO: refine config compatibility problems
|
||||
|
||||
easycv_arch = self.cfg.model.pop(EasyCVMeta.ARCH, None)
|
||||
model_cfg = self.cfg.model
|
||||
# Revert to the configuration of easycv
|
||||
if easycv_arch is not None:
|
||||
model_cfg.update(easycv_arch)
|
||||
|
||||
easycv_config = Config(dict(model=model_cfg))
|
||||
|
||||
reserved_keys = []
|
||||
if hasattr(self.cfg, EasyCVMeta.META):
|
||||
easycv_meta_cfg = getattr(self.cfg, EasyCVMeta.META)
|
||||
reserved_keys = easycv_meta_cfg.get(EasyCVMeta.RESERVED_KEYS, [])
|
||||
for key in reserved_keys:
|
||||
easycv_config.merge_from_dict({key: getattr(self.cfg, key)})
|
||||
if 'test_pipeline' not in reserved_keys:
|
||||
easycv_config.merge_from_dict(
|
||||
{'test_pipeline': self.cfg.dataset.val.get('pipeline', [])})
|
||||
|
||||
return easycv_config
|
||||
|
||||
def _is_single_inputs(self, inputs):
|
||||
if isinstance(inputs, str) or (isinstance(inputs, list)
|
||||
and len(inputs) == 1) or isinstance(
|
||||
inputs, np.ndarray) or isinstance(
|
||||
inputs, ImageFile.ImageFile):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def __call__(self, inputs) -> Any:
|
||||
outputs = self.predict_op(inputs)
|
||||
|
||||
if self._is_single_inputs(inputs):
|
||||
outputs = outputs[0]
|
||||
|
||||
return outputs
|
||||
@@ -1,66 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import Any
|
||||
|
||||
from modelscope.metainfo import Pipelines
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines.builder import PIPELINES
|
||||
from modelscope.utils.constant import ModelFile, Tasks
|
||||
from modelscope.utils.cv.image_utils import \
|
||||
show_image_object_detection_auto_result
|
||||
from .base import EasyCVPipeline
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.image_object_detection, module_name=Pipelines.easycv_detection)
|
||||
@PIPELINES.register_module(
|
||||
Tasks.image_object_detection,
|
||||
module_name=Pipelines.image_object_detection_auto)
|
||||
@PIPELINES.register_module(
|
||||
Tasks.domain_specific_object_detection,
|
||||
module_name=Pipelines.hand_detection)
|
||||
class EasyCVDetectionPipeline(EasyCVPipeline):
|
||||
"""Pipeline for easycv detection task."""
|
||||
|
||||
def __init__(self,
|
||||
model: str,
|
||||
model_file_pattern=ModelFile.TORCH_MODEL_FILE,
|
||||
*args,
|
||||
**kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
"""
|
||||
|
||||
super(EasyCVDetectionPipeline, self).__init__(
|
||||
model=model,
|
||||
model_file_pattern=model_file_pattern,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
def show_result(self, img_path, result, save_path=None):
|
||||
show_image_object_detection_auto_result(img_path, result, save_path)
|
||||
|
||||
def __call__(self, inputs) -> Any:
|
||||
outputs = self.predict_op(inputs)
|
||||
|
||||
scores = []
|
||||
labels = []
|
||||
boxes = []
|
||||
for output in outputs:
|
||||
for score, label, box in zip(output['detection_scores'],
|
||||
output['detection_classes'],
|
||||
output['detection_boxes']):
|
||||
scores.append(score)
|
||||
labels.append(self.cfg.CLASSES[label])
|
||||
boxes.append([b for b in box])
|
||||
|
||||
results = [{
|
||||
OutputKeys.SCORES: scores,
|
||||
OutputKeys.LABELS: labels,
|
||||
OutputKeys.BOXES: boxes
|
||||
} for output in outputs]
|
||||
|
||||
if self._is_single_inputs(inputs):
|
||||
results = results[0]
|
||||
|
||||
return results
|
||||
@@ -1,244 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import copy
|
||||
import math
|
||||
from typing import Any
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
from modelscope.metainfo import Pipelines
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines import pipeline
|
||||
from modelscope.pipelines.builder import PIPELINES
|
||||
from modelscope.preprocessors import LoadImage
|
||||
from modelscope.utils.constant import ModelFile, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from .base import EasyCVPipeline
|
||||
|
||||
logger = get_logger()
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.face_2d_keypoints, module_name=Pipelines.face_2d_keypoints)
|
||||
class Face2DKeypointsPipeline(EasyCVPipeline):
|
||||
"""Pipeline for face 2d keypoints detection."""
|
||||
|
||||
def __init__(self,
|
||||
model: str,
|
||||
model_file_pattern=ModelFile.TORCH_MODEL_FILE,
|
||||
*args,
|
||||
**kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
"""
|
||||
|
||||
super(Face2DKeypointsPipeline, self).__init__(
|
||||
model=model,
|
||||
model_file_pattern=model_file_pattern,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
# face detect pipeline
|
||||
det_model_id = 'damo/cv_resnet_facedetection_scrfd10gkps'
|
||||
self.face_detection = pipeline(
|
||||
Tasks.face_detection, model=det_model_id)
|
||||
|
||||
def show_result(self, img, points, scale=2, save_path=None):
|
||||
return self.predict_op.show_result(img, points, scale, save_path)
|
||||
|
||||
def _choose_face(self, det_result, min_face=10):
|
||||
"""
|
||||
choose face with maximum area
|
||||
Args:
|
||||
det_result: output of face detection pipeline
|
||||
min_face: minimum size of valid face w/h
|
||||
"""
|
||||
bboxes = np.array(det_result[OutputKeys.BOXES])
|
||||
landmarks = np.array(det_result[OutputKeys.KEYPOINTS])
|
||||
if bboxes.shape[0] == 0:
|
||||
logger.warning('No face detected!')
|
||||
return None
|
||||
# face idx with enough size
|
||||
face_idx = []
|
||||
for i in range(bboxes.shape[0]):
|
||||
box = bboxes[i]
|
||||
if (box[2] - box[0]) >= min_face and (box[3] - box[1]) >= min_face:
|
||||
face_idx += [i]
|
||||
if len(face_idx) == 0:
|
||||
logger.warning(
|
||||
f'Face size not enough, less than {min_face}x{min_face}!')
|
||||
return None
|
||||
bboxes = bboxes[face_idx]
|
||||
landmarks = landmarks[face_idx]
|
||||
|
||||
return bboxes, landmarks
|
||||
|
||||
def expend_box(self, box, w, h, scalex=0.3, scaley=0.5):
|
||||
x1 = box[0]
|
||||
y1 = box[1]
|
||||
wb = box[2] - x1
|
||||
hb = box[3] - y1
|
||||
deltax = int(wb * scalex)
|
||||
deltay1 = int(hb * scaley)
|
||||
deltay2 = int(hb * scalex)
|
||||
x1 = x1 - deltax
|
||||
y1 = y1 - deltay1
|
||||
if x1 < 0:
|
||||
deltax = deltax + x1
|
||||
x1 = 0
|
||||
if y1 < 0:
|
||||
deltay1 = deltay1 + y1
|
||||
y1 = 0
|
||||
x2 = x1 + wb + 2 * deltax
|
||||
y2 = y1 + hb + deltay1 + deltay2
|
||||
x2 = np.clip(x2, 0, w - 1)
|
||||
y2 = np.clip(y2, 0, h - 1)
|
||||
return [x1, y1, x2, y2]
|
||||
|
||||
def rotate_point(self, angle, center, landmark):
|
||||
rad = angle * np.pi / 180.0
|
||||
alpha = np.cos(rad)
|
||||
beta = np.sin(rad)
|
||||
M = np.zeros((2, 3), dtype=np.float32)
|
||||
M[0, 0] = alpha
|
||||
M[0, 1] = beta
|
||||
M[0, 2] = (1 - alpha) * center[0] - beta * center[1]
|
||||
M[1, 0] = -beta
|
||||
M[1, 1] = alpha
|
||||
M[1, 2] = beta * center[0] + (1 - alpha) * center[1]
|
||||
|
||||
landmark_ = np.asarray([(M[0, 0] * x + M[0, 1] * y + M[0, 2],
|
||||
M[1, 0] * x + M[1, 1] * y + M[1, 2])
|
||||
for (x, y) in landmark])
|
||||
return M, landmark_
|
||||
|
||||
def rotate_crop_img(self, img, pts, M):
|
||||
imgT = cv2.warpAffine(img, M, (int(img.shape[1]), int(img.shape[0])))
|
||||
|
||||
x1 = pts[5][0]
|
||||
x2 = pts[5][0]
|
||||
y1 = pts[5][1]
|
||||
y2 = pts[5][1]
|
||||
for i in range(0, 9):
|
||||
x1 = min(x1, pts[i][0])
|
||||
x2 = max(x2, pts[i][0])
|
||||
y1 = min(y1, pts[i][1])
|
||||
y2 = max(y2, pts[i][1])
|
||||
|
||||
height, width, _ = imgT.shape
|
||||
x1 = min(max(0, int(x1)), width)
|
||||
y1 = min(max(0, int(y1)), height)
|
||||
x2 = min(max(0, int(x2)), width)
|
||||
y2 = min(max(0, int(y2)), height)
|
||||
sub_imgT = imgT[y1:y2, x1:x2]
|
||||
|
||||
return sub_imgT, imgT, [x1, y1, x2, y2]
|
||||
|
||||
def crop_img(self, imgT, pts):
|
||||
enlarge_ratio = 1.1
|
||||
|
||||
x1 = np.min(pts[:, 0])
|
||||
x2 = np.max(pts[:, 0])
|
||||
y1 = np.min(pts[:, 1])
|
||||
y2 = np.max(pts[:, 1])
|
||||
w = x2 - x1 + 1
|
||||
h = y2 - y1 + 1
|
||||
x1 = int(x1 - (enlarge_ratio - 1.0) / 2.0 * w)
|
||||
y1 = int(y1 - (enlarge_ratio - 1.0) / 2.0 * h)
|
||||
x1 = max(0, x1)
|
||||
y1 = max(0, y1)
|
||||
|
||||
new_w = int(enlarge_ratio * w)
|
||||
new_h = int(enlarge_ratio * h)
|
||||
new_x1 = x1
|
||||
new_y1 = y1
|
||||
new_x2 = new_x1 + new_w
|
||||
new_y2 = new_y1 + new_h
|
||||
|
||||
height, width, _ = imgT.shape
|
||||
|
||||
new_x1 = min(max(0, new_x1), width)
|
||||
new_y1 = min(max(0, new_y1), height)
|
||||
new_x2 = max(min(width, new_x2), 0)
|
||||
new_y2 = max(min(height, new_y2), 0)
|
||||
|
||||
sub_imgT = imgT[new_y1:new_y2, new_x1:new_x2]
|
||||
|
||||
return sub_imgT, [new_x1, new_y1, new_x2, new_y2]
|
||||
|
||||
def __call__(self, inputs) -> Any:
|
||||
img = LoadImage.convert_to_ndarray(inputs)
|
||||
h, w, c = img.shape
|
||||
img_rgb = copy.deepcopy(img)
|
||||
img_rgb = img_rgb[:, :, ::-1]
|
||||
det_result = self.face_detection(img_rgb)
|
||||
|
||||
bboxes = np.array(det_result[OutputKeys.BOXES])
|
||||
if bboxes.shape[0] == 0:
|
||||
logger.warning('No face detected!')
|
||||
results = {
|
||||
OutputKeys.KEYPOINTS: [],
|
||||
OutputKeys.POSES: [],
|
||||
OutputKeys.BOXES: []
|
||||
}
|
||||
return results
|
||||
|
||||
boxes, keypoints = self._choose_face(det_result)
|
||||
|
||||
output_boxes = []
|
||||
output_keypoints = []
|
||||
output_poses = []
|
||||
for index, box_ori in enumerate(boxes):
|
||||
box = self.expend_box(box_ori, w, h, scalex=0.1, scaley=0.1)
|
||||
y0 = int(box[1])
|
||||
y1 = int(box[3])
|
||||
x0 = int(box[0])
|
||||
x1 = int(box[2])
|
||||
sub_img = img[y0:y1, x0:x1]
|
||||
|
||||
keypoint = keypoints[index]
|
||||
pts = [[keypoint[0], keypoint[1]], [keypoint[2], keypoint[3]],
|
||||
[keypoint[4], keypoint[5]], [keypoint[6], keypoint[7]],
|
||||
[keypoint[8], keypoint[9]], [box[0], box[1]],
|
||||
[box[2], box[1]], [box[0], box[3]], [box[2], box[3]]]
|
||||
# radian
|
||||
angle = math.atan2((pts[1][1] - pts[0][1]),
|
||||
(pts[1][0] - pts[0][0]))
|
||||
# angle
|
||||
theta = angle * (180 / np.pi)
|
||||
|
||||
center = [w // 2, h // 2]
|
||||
cx, cy = center
|
||||
M, landmark_ = self.rotate_point(theta, (cx, cy), pts)
|
||||
sub_imgT, imgT, bbox = self.rotate_crop_img(img, landmark_, M)
|
||||
|
||||
outputs = self.predict_op([sub_imgT])[0]
|
||||
tmp_keypoints = outputs['point']
|
||||
|
||||
for idx in range(0, len(tmp_keypoints)):
|
||||
tmp_keypoints[idx][0] += bbox[0]
|
||||
tmp_keypoints[idx][1] += bbox[1]
|
||||
|
||||
for idx in range(0, 6):
|
||||
sub_img, bbox = self.crop_img(imgT, tmp_keypoints)
|
||||
outputs = self.predict_op([sub_img])[0]
|
||||
tmp_keypoints = outputs['point']
|
||||
for idx in range(0, len(tmp_keypoints)):
|
||||
tmp_keypoints[idx][0] += bbox[0]
|
||||
tmp_keypoints[idx][1] += bbox[1]
|
||||
|
||||
M2, tmp_keypoints = self.rotate_point(-theta, (cx, cy),
|
||||
tmp_keypoints)
|
||||
|
||||
output_keypoints.append(np.array(tmp_keypoints))
|
||||
output_poses.append(np.array(outputs['pose']))
|
||||
output_boxes.append(np.array(box_ori))
|
||||
|
||||
results = {
|
||||
OutputKeys.KEYPOINTS: output_keypoints,
|
||||
OutputKeys.POSES: output_poses,
|
||||
OutputKeys.BOXES: output_boxes
|
||||
}
|
||||
|
||||
return results
|
||||
@@ -1,67 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import os.path
|
||||
from typing import Any
|
||||
|
||||
from modelscope.metainfo import Pipelines
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines.builder import PIPELINES
|
||||
from modelscope.utils.constant import ModelFile, Tasks
|
||||
from .base import EasyCVPipeline
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.human_wholebody_keypoint,
|
||||
module_name=Pipelines.human_wholebody_keypoint)
|
||||
class HumanWholebodyKeypointsPipeline(EasyCVPipeline):
|
||||
"""Pipeline for human wholebody 2d keypoints detection."""
|
||||
|
||||
def __init__(self,
|
||||
model: str,
|
||||
model_file_pattern=ModelFile.TORCH_MODEL_FILE,
|
||||
*args,
|
||||
**kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
"""
|
||||
super(HumanWholebodyKeypointsPipeline, self).__init__(
|
||||
model=model,
|
||||
model_file_pattern=model_file_pattern,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
def _build_predict_op(self, **kwargs):
|
||||
"""Build EasyCV predictor."""
|
||||
from easycv.predictors.builder import build_predictor
|
||||
detection_predictor_type = self.cfg['DETECTION']['type']
|
||||
detection_model_path = os.path.join(
|
||||
self.model_dir, self.cfg['DETECTION']['model_path'])
|
||||
detection_cfg_file = os.path.join(self.model_dir,
|
||||
self.cfg['DETECTION']['config_file'])
|
||||
detection_score_threshold = self.cfg['DETECTION']['score_threshold']
|
||||
self.cfg.pipeline.predictor_config[
|
||||
'detection_predictor_config'] = dict(
|
||||
type=detection_predictor_type,
|
||||
model_path=detection_model_path,
|
||||
config_file=detection_cfg_file,
|
||||
score_threshold=detection_score_threshold)
|
||||
easycv_config = self._to_easycv_config()
|
||||
pipeline_op = build_predictor(self.cfg.pipeline.predictor_config, {
|
||||
'model_path': self.model_path,
|
||||
'config_file': easycv_config,
|
||||
**kwargs
|
||||
})
|
||||
return pipeline_op
|
||||
|
||||
def __call__(self, inputs) -> Any:
|
||||
outputs = self.predict_op(inputs)
|
||||
|
||||
results = [{
|
||||
OutputKeys.KEYPOINTS: output['keypoints'],
|
||||
OutputKeys.BOXES: output['boxes']
|
||||
} for output in outputs]
|
||||
|
||||
if self._is_single_inputs(inputs):
|
||||
results = results[0]
|
||||
|
||||
return results
|
||||
@@ -1,47 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import Any
|
||||
|
||||
import numpy as np
|
||||
|
||||
from modelscope.metainfo import Pipelines
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines.builder import PIPELINES
|
||||
from modelscope.utils.constant import Tasks
|
||||
from .base import EasyCVPipeline
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.image_segmentation, module_name=Pipelines.easycv_segmentation)
|
||||
class EasyCVSegmentationPipeline(EasyCVPipeline):
|
||||
"""Pipeline for easycv segmentation task."""
|
||||
|
||||
def __init__(self, model: str, model_file_pattern='*.pt', *args, **kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
"""
|
||||
|
||||
super(EasyCVSegmentationPipeline, self).__init__(
|
||||
model=model,
|
||||
model_file_pattern=model_file_pattern,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
def __call__(self, inputs) -> Any:
|
||||
outputs = self.predict_op(inputs)
|
||||
|
||||
semantic_result = outputs[0]['seg_pred']
|
||||
|
||||
ids = np.unique(semantic_result)[::-1]
|
||||
legal_indices = ids != len(self.predict_op.CLASSES) # for VOID label
|
||||
ids = ids[legal_indices]
|
||||
segms = (semantic_result[None] == ids[:, None, None])
|
||||
masks = [it.astype(np.int) for it in segms]
|
||||
labels_txt = np.array(self.predict_op.CLASSES)[ids].tolist()
|
||||
|
||||
results = {
|
||||
OutputKeys.MASKS: masks,
|
||||
OutputKeys.LABELS: labels_txt,
|
||||
OutputKeys.SCORES: [0.999 for _ in range(len(labels_txt))]
|
||||
}
|
||||
return results
|
||||
@@ -1,51 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import os.path
|
||||
|
||||
from modelscope.metainfo import Pipelines
|
||||
from modelscope.pipelines.builder import PIPELINES
|
||||
from modelscope.utils.constant import ModelFile, Tasks
|
||||
from .easycv_pipelines.base import EasyCVPipeline
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.hand_2d_keypoints, module_name=Pipelines.hand_2d_keypoints)
|
||||
class Hand2DKeypointsPipeline(EasyCVPipeline):
|
||||
"""Pipeline for hand pose keypoint task."""
|
||||
|
||||
def __init__(self,
|
||||
model: str,
|
||||
model_file_pattern=ModelFile.TORCH_MODEL_FILE,
|
||||
*args,
|
||||
**kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
"""
|
||||
super(Hand2DKeypointsPipeline, self).__init__(
|
||||
model=model,
|
||||
model_file_pattern=model_file_pattern,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
def _build_predict_op(self, **kwargs):
|
||||
"""Build EasyCV predictor."""
|
||||
from easycv.predictors.builder import build_predictor
|
||||
detection_predictor_type = self.cfg['DETECTION']['type']
|
||||
detection_model_path = os.path.join(
|
||||
self.model_dir, self.cfg['DETECTION']['model_path'])
|
||||
detection_cfg_file = os.path.join(self.model_dir,
|
||||
self.cfg['DETECTION']['config_file'])
|
||||
detection_score_threshold = self.cfg['DETECTION']['score_threshold']
|
||||
self.cfg.pipeline.predictor_config[
|
||||
'detection_predictor_config'] = dict(
|
||||
type=detection_predictor_type,
|
||||
model_path=detection_model_path,
|
||||
config_file=detection_cfg_file,
|
||||
score_threshold=detection_score_threshold)
|
||||
easycv_config = self._to_easycv_config()
|
||||
pipeline_op = build_predictor(self.cfg.pipeline.predictor_config, {
|
||||
'model_path': self.model_path,
|
||||
'config_file': easycv_config,
|
||||
**kwargs
|
||||
})
|
||||
return pipeline_op
|
||||
@@ -1,135 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import Any, Dict, Union
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
import PIL
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Pipelines
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines.base import Input, Pipeline
|
||||
from modelscope.pipelines.builder import PIPELINES
|
||||
from modelscope.pipelines.cv.easycv_pipelines.base import EasyCVPipeline
|
||||
from modelscope.preprocessors import load_image
|
||||
from modelscope.utils.constant import Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
|
||||
logger = get_logger()
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.image_segmentation,
|
||||
module_name=Pipelines.image_panoptic_segmentation)
|
||||
class ImagePanopticSegmentationPipeline(Pipeline):
|
||||
|
||||
def __init__(self, model: str, **kwargs):
|
||||
"""
|
||||
use `model` to create a image panoptic segmentation pipeline for prediction
|
||||
Args:
|
||||
model: model id on modelscope hub.
|
||||
"""
|
||||
super().__init__(model=model, **kwargs)
|
||||
|
||||
logger.info('panoptic segmentation model, pipeline init')
|
||||
|
||||
def preprocess(self, input: Input) -> Dict[str, Any]:
|
||||
from mmdet.datasets.pipelines import Compose
|
||||
from mmcv.parallel import collate, scatter
|
||||
from mmdet.datasets import replace_ImageToTensor
|
||||
|
||||
cfg = self.model.cfg
|
||||
# build the data pipeline
|
||||
|
||||
if isinstance(input, str):
|
||||
cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam'
|
||||
img = np.array(load_image(input))
|
||||
img = img[:, :, ::-1] # convert to bgr
|
||||
elif isinstance(input, PIL.Image.Image):
|
||||
cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam'
|
||||
img = np.array(input.convert('RGB'))
|
||||
elif isinstance(input, np.ndarray):
|
||||
cfg.data.test.pipeline[0].type = 'LoadImageFromWebcam'
|
||||
if len(input.shape) == 2:
|
||||
img = cv2.cvtColor(input, cv2.COLOR_GRAY2BGR)
|
||||
else:
|
||||
img = input
|
||||
else:
|
||||
raise TypeError(f'input should be either str, PIL.Image,'
|
||||
f' np.array, but got {type(input)}')
|
||||
|
||||
# collect data
|
||||
data = dict(img=img)
|
||||
cfg.data.test.pipeline = replace_ImageToTensor(cfg.data.test.pipeline)
|
||||
test_pipeline = Compose(cfg.data.test.pipeline)
|
||||
|
||||
data = test_pipeline(data)
|
||||
# copy from mmdet_model collect data
|
||||
data = collate([data], samples_per_gpu=1)
|
||||
data['img_metas'] = [
|
||||
img_metas.data[0] for img_metas in data['img_metas']
|
||||
]
|
||||
data['img'] = [img.data[0] for img in data['img']]
|
||||
if next(self.model.parameters()).is_cuda:
|
||||
# scatter to specified GPU
|
||||
data = scatter(data, [next(self.model.parameters()).device])[0]
|
||||
|
||||
return data
|
||||
|
||||
def forward(self, input: Dict[str, Any]) -> Dict[str, Any]:
|
||||
results = self.model.inference(input)
|
||||
|
||||
return results
|
||||
|
||||
def postprocess(self, inputs: Dict[str, Any]) -> Dict[str, Any]:
|
||||
# bz=1, tcguo
|
||||
pan_results = inputs[0]['pan_results']
|
||||
INSTANCE_OFFSET = 1000
|
||||
|
||||
ids = np.unique(pan_results)[::-1]
|
||||
legal_indices = ids != self.model.num_classes # for VOID label
|
||||
ids = ids[legal_indices]
|
||||
labels = np.array([id % INSTANCE_OFFSET for id in ids], dtype=np.int64)
|
||||
segms = (pan_results[None] == ids[:, None, None])
|
||||
masks = [it.astype(np.int) for it in segms]
|
||||
labels_txt = np.array(self.model.CLASSES)[labels].tolist()
|
||||
|
||||
outputs = {
|
||||
OutputKeys.MASKS: masks,
|
||||
OutputKeys.LABELS: labels_txt,
|
||||
OutputKeys.SCORES: [0.999 for _ in range(len(labels_txt))]
|
||||
}
|
||||
return outputs
|
||||
|
||||
|
||||
@PIPELINES.register_module(
|
||||
Tasks.image_segmentation,
|
||||
module_name=Pipelines.image_panoptic_segmentation_easycv)
|
||||
class ImagePanopticSegmentationEasyCVPipeline(EasyCVPipeline):
|
||||
"""Pipeline built upon easycv for image segmentation."""
|
||||
|
||||
def __init__(self, model: str, model_file_pattern='*.pt', *args, **kwargs):
|
||||
"""
|
||||
model (str): model id on modelscope hub or local model path.
|
||||
model_file_pattern (str): model file pattern.
|
||||
"""
|
||||
super(ImagePanopticSegmentationEasyCVPipeline, self).__init__(
|
||||
model=model,
|
||||
model_file_pattern=model_file_pattern,
|
||||
*args,
|
||||
**kwargs)
|
||||
|
||||
def __call__(self, inputs) -> Any:
|
||||
outputs = self.predict_op(inputs)
|
||||
easycv_results = outputs[0]
|
||||
|
||||
results = {
|
||||
OutputKeys.MASKS:
|
||||
easycv_results[OutputKeys.MASKS],
|
||||
OutputKeys.LABELS:
|
||||
easycv_results[OutputKeys.LABELS],
|
||||
OutputKeys.SCORES:
|
||||
[0.999 for _ in range(len(easycv_results[OutputKeys.LABELS]))]
|
||||
}
|
||||
|
||||
return results
|
||||
@@ -1,19 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .utils import AddLrLogHook, EasyCVMetric
|
||||
else:
|
||||
_import_structure = {'utils': ['AddLrLogHook', 'EasyCVMetric']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,183 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from copy import deepcopy
|
||||
from functools import partial
|
||||
from typing import Callable, Optional, Tuple, Union
|
||||
|
||||
import torch
|
||||
from easycv.utils.checkpoint import load_checkpoint as ev_load_checkpoint
|
||||
from torch import nn
|
||||
from torch.utils.data import Dataset
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.models.base import TorchModel
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.preprocessors import Preprocessor
|
||||
from modelscope.trainers import EpochBasedTrainer
|
||||
from modelscope.trainers.base import TRAINERS
|
||||
from modelscope.trainers.easycv.utils import register_util
|
||||
from modelscope.trainers.hooks import HOOKS
|
||||
from modelscope.trainers.parallel.builder import build_parallel
|
||||
from modelscope.trainers.parallel.utils import is_parallel
|
||||
from modelscope.utils.config import Config
|
||||
from modelscope.utils.constant import DEFAULT_MODEL_REVISION
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
from modelscope.utils.registry import default_group
|
||||
|
||||
|
||||
@TRAINERS.register_module(module_name=Trainers.easycv)
|
||||
class EasyCVEpochBasedTrainer(EpochBasedTrainer):
|
||||
"""Epoch based Trainer for EasyCV.
|
||||
|
||||
Args:
|
||||
cfg_file(str): The config file of EasyCV.
|
||||
model (:obj:`torch.nn.Module` or :obj:`TorchModel` or `str`): The model to be run, or a valid model dir
|
||||
or a model id. If model is None, build_model method will be called.
|
||||
train_dataset (`MsDataset` or `torch.utils.data.Dataset`, *optional*):
|
||||
The dataset to use for training.
|
||||
Note that if it's a `torch.utils.data.IterableDataset` with some randomization and you are training in a
|
||||
distributed fashion, your iterable dataset should either use a internal attribute `generator` that is a
|
||||
`torch.Generator` for the randomization that must be identical on all processes (and the Trainer will
|
||||
manually set the seed of this `generator` at each epoch) or have a `set_epoch()` method that internally
|
||||
sets the seed of the RNGs used.
|
||||
eval_dataset (`MsDataset` or `torch.utils.data.Dataset`, *optional*): The dataset to use for evaluation.
|
||||
preprocessor (:obj:`Preprocessor`, *optional*): The optional preprocessor.
|
||||
NOTE: If the preprocessor has been called before the dataset fed into this trainer by user's custom code,
|
||||
this parameter should be None, meanwhile remove the 'preprocessor' key from the cfg_file.
|
||||
Else the preprocessor will be instantiated from the cfg_file or assigned from this parameter and
|
||||
this preprocessing action will be executed every time the dataset's __getitem__ is called.
|
||||
optimizers (`Tuple[torch.optim.Optimizer, torch.optim.lr_scheduler._LRScheduler]`, *optional*): A tuple
|
||||
containing the optimizer and the scheduler to use.
|
||||
max_epochs: (int, optional): Total training epochs.
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
cfg_file: Optional[str] = None,
|
||||
model: Optional[Union[TorchModel, nn.Module, str]] = None,
|
||||
arg_parse_fn: Optional[Callable] = None,
|
||||
train_dataset: Optional[Union[MsDataset, Dataset]] = None,
|
||||
eval_dataset: Optional[Union[MsDataset, Dataset]] = None,
|
||||
preprocessor: Optional[Preprocessor] = None,
|
||||
optimizers: Tuple[torch.optim.Optimizer,
|
||||
torch.optim.lr_scheduler._LRScheduler] = (None,
|
||||
None),
|
||||
model_revision: Optional[str] = DEFAULT_MODEL_REVISION,
|
||||
**kwargs):
|
||||
|
||||
register_util.register_parallel()
|
||||
register_util.register_part_mmcv_hooks_to_ms()
|
||||
|
||||
super(EasyCVEpochBasedTrainer, self).__init__(
|
||||
model=model,
|
||||
cfg_file=cfg_file,
|
||||
arg_parse_fn=arg_parse_fn,
|
||||
preprocessor=preprocessor,
|
||||
optimizers=optimizers,
|
||||
model_revision=model_revision,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
**kwargs)
|
||||
|
||||
# reset data_collator
|
||||
from mmcv.parallel import collate
|
||||
|
||||
self.train_data_collator = partial(
|
||||
collate,
|
||||
samples_per_gpu=self.cfg.train.dataloader.batch_size_per_gpu)
|
||||
self.eval_data_collator = partial(
|
||||
collate,
|
||||
samples_per_gpu=self.cfg.evaluation.dataloader.batch_size_per_gpu)
|
||||
|
||||
# load pretrained model
|
||||
load_from = self.cfg.get('load_from', None)
|
||||
if load_from is not None:
|
||||
ev_load_checkpoint(
|
||||
self.model,
|
||||
filename=load_from,
|
||||
map_location=self.device,
|
||||
strict=False,
|
||||
)
|
||||
|
||||
# reset parallel
|
||||
if not self._dist:
|
||||
assert not is_parallel(
|
||||
self.model
|
||||
), 'Not support model wrapped by custom parallel if not in distributed mode!'
|
||||
dp_cfg = dict(
|
||||
type='MMDataParallel',
|
||||
module=self.model,
|
||||
device_ids=[torch.cuda.current_device()])
|
||||
self.model = build_parallel(dp_cfg)
|
||||
|
||||
def rebuild_config(self, cfg: Config):
|
||||
cfg = super().rebuild_config(cfg)
|
||||
# Register easycv hooks dynamicly. If the hook already exists in modelscope,
|
||||
# the hook in modelscope will be used, otherwise register easycv hook into ms.
|
||||
# We must manually trigger lazy import to detect whether the hook is in modelscope.
|
||||
# TODO: use ast index to detect whether the hook is in modelscope
|
||||
for h_i in cfg.train.get('hooks', []):
|
||||
sig = ('HOOKS', default_group, h_i['type'])
|
||||
LazyImportModule.import_module(sig)
|
||||
if h_i['type'] not in HOOKS._modules[default_group]:
|
||||
if h_i['type'] in [
|
||||
'TensorboardLoggerHookV2', 'WandbLoggerHookV2'
|
||||
]:
|
||||
raise ValueError(
|
||||
'Not support hook %s now, we will support it in the future!'
|
||||
% h_i['type'])
|
||||
register_util.register_hook_to_ms(h_i['type'])
|
||||
return cfg
|
||||
|
||||
def create_optimizer_and_scheduler(self):
|
||||
""" Create optimizer and lr scheduler
|
||||
"""
|
||||
optimizer, lr_scheduler = self.optimizers
|
||||
if optimizer is None:
|
||||
optimizer_cfg = self.cfg.train.get('optimizer', None)
|
||||
else:
|
||||
optimizer_cfg = None
|
||||
|
||||
optim_options = {}
|
||||
if optimizer_cfg is not None:
|
||||
optim_options = optimizer_cfg.pop('options', {})
|
||||
from easycv.apis.train import build_optimizer
|
||||
optimizer = build_optimizer(self.model, optimizer_cfg)
|
||||
|
||||
if lr_scheduler is None:
|
||||
lr_scheduler_cfg = self.cfg.train.get('lr_scheduler', None)
|
||||
else:
|
||||
lr_scheduler_cfg = None
|
||||
|
||||
lr_options = {}
|
||||
# Adapt to mmcv lr scheduler hook.
|
||||
# Please refer to: https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py
|
||||
if lr_scheduler_cfg is not None:
|
||||
assert optimizer is not None
|
||||
lr_options = lr_scheduler_cfg.pop('options', {})
|
||||
assert 'policy' in lr_scheduler_cfg
|
||||
policy_type = lr_scheduler_cfg.pop('policy')
|
||||
if policy_type == policy_type.lower():
|
||||
policy_type = policy_type.title()
|
||||
hook_type = policy_type + 'LrUpdaterHook'
|
||||
lr_scheduler_cfg['type'] = hook_type
|
||||
|
||||
self.cfg.train.lr_scheduler_hook = lr_scheduler_cfg
|
||||
|
||||
self.optimizer = optimizer
|
||||
self.lr_scheduler = lr_scheduler
|
||||
|
||||
return self.optimizer, self.lr_scheduler, optim_options, lr_options
|
||||
|
||||
def to_parallel(self, model) -> Union[nn.Module, TorchModel]:
|
||||
if self.cfg.get('parallel', None) is not None:
|
||||
dp_cfg = deepcopy(self.cfg['parallel'])
|
||||
dp_cfg.update(
|
||||
dict(module=model, device_ids=[torch.cuda.current_device()]))
|
||||
return build_parallel(dp_cfg)
|
||||
|
||||
dp_cfg = dict(
|
||||
type='MMDistributedDataParallel',
|
||||
module=model,
|
||||
device_ids=[torch.cuda.current_device()])
|
||||
|
||||
return build_parallel(dp_cfg)
|
||||
@@ -1,21 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from modelscope.utils.import_utils import LazyImportModule
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .hooks import AddLrLogHook
|
||||
from .metric import EasyCVMetric
|
||||
|
||||
else:
|
||||
_import_structure = {'hooks': ['AddLrLogHook'], 'metric': ['EasyCVMetric']}
|
||||
|
||||
import sys
|
||||
|
||||
sys.modules[__name__] = LazyImportModule(
|
||||
__name__,
|
||||
globals()['__file__'],
|
||||
_import_structure,
|
||||
module_spec=__spec__,
|
||||
extra_objects={},
|
||||
)
|
||||
@@ -1,29 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
from modelscope.trainers.hooks import HOOKS, Priority
|
||||
from modelscope.trainers.hooks.lr_scheduler_hook import LrSchedulerHook
|
||||
from modelscope.utils.constant import LogKeys
|
||||
|
||||
|
||||
@HOOKS.register_module(module_name='AddLrLogHook')
|
||||
class AddLrLogHook(LrSchedulerHook):
|
||||
"""For EasyCV to adapt to ModelScope, the lr log of EasyCV is added in the trainer,
|
||||
but the trainer of ModelScope does not and it is added in the lr scheduler hook.
|
||||
But The lr scheduler hook used by EasyCV is the hook of mmcv, and there is no lr log.
|
||||
It will be deleted in the future.
|
||||
"""
|
||||
PRIORITY = Priority.NORMAL
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
def before_run(self, trainer):
|
||||
pass
|
||||
|
||||
def after_train_iter(self, trainer):
|
||||
trainer.log_buffer.output[LogKeys.LR] = self._get_log_lr(trainer)
|
||||
|
||||
def before_train_epoch(self, trainer):
|
||||
trainer.log_buffer.output[LogKeys.LR] = self._get_log_lr(trainer)
|
||||
|
||||
def after_train_epoch(self, trainer):
|
||||
pass
|
||||
@@ -1,62 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import itertools
|
||||
from typing import Dict
|
||||
|
||||
import numpy as np
|
||||
import torch
|
||||
|
||||
from modelscope.metrics.base import Metric
|
||||
from modelscope.metrics.builder import METRICS
|
||||
|
||||
|
||||
@METRICS.register_module(module_name='EasyCVMetric')
|
||||
class EasyCVMetric(Metric):
|
||||
"""Adapt to ModelScope Metric for EasyCV evaluator.
|
||||
"""
|
||||
|
||||
def __init__(self, trainer=None, evaluators=None, *args, **kwargs):
|
||||
from easycv.core.evaluation.builder import build_evaluator
|
||||
|
||||
self.trainer = trainer
|
||||
self.evaluators = build_evaluator(evaluators)
|
||||
self.preds = []
|
||||
self.grountruths = []
|
||||
|
||||
def add(self, outputs: Dict, inputs: Dict):
|
||||
self.preds.append(outputs)
|
||||
del inputs
|
||||
|
||||
def evaluate(self):
|
||||
results = {}
|
||||
for _, batch in enumerate(self.preds):
|
||||
for k, v in batch.items():
|
||||
if k not in results:
|
||||
results[k] = []
|
||||
results[k].append(v)
|
||||
|
||||
for k, v in results.items():
|
||||
if len(v) == 0:
|
||||
raise ValueError(f'empty result for {k}')
|
||||
|
||||
if isinstance(v[0], torch.Tensor):
|
||||
results[k] = torch.cat(v, 0)
|
||||
elif isinstance(v[0], (list, np.ndarray)):
|
||||
results[k] = list(itertools.chain.from_iterable(v))
|
||||
else:
|
||||
raise ValueError(
|
||||
f'value of batch prediction dict should only be tensor or list, {k} type is {v[0]}'
|
||||
)
|
||||
|
||||
metric_values = self.trainer.eval_dataset.evaluate(
|
||||
results, self.evaluators)
|
||||
return metric_values
|
||||
|
||||
def merge(self, other: 'EasyCVMetric'):
|
||||
self.preds.extend(other.preds)
|
||||
|
||||
def __getstate__(self):
|
||||
return self.preds
|
||||
|
||||
def __setstate__(self, state):
|
||||
self.__init__()
|
||||
self.preds = state
|
||||
@@ -1,97 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import inspect
|
||||
import logging
|
||||
|
||||
from modelscope.trainers.hooks import HOOKS
|
||||
from modelscope.trainers.parallel.builder import PARALLEL
|
||||
from modelscope.utils.registry import default_group
|
||||
|
||||
|
||||
class _RegisterManager:
|
||||
|
||||
def __init__(self):
|
||||
self.registries = {}
|
||||
|
||||
def add(self, module, name, group_key=default_group):
|
||||
if module.name not in self.registries:
|
||||
self.registries[module.name] = {}
|
||||
if group_key not in self.registries[module.name]:
|
||||
self.registries[module.name][group_key] = []
|
||||
|
||||
self.registries[module.name][group_key].append(name)
|
||||
|
||||
def exists(self, module, name, group_key=default_group):
|
||||
if self.registries.get(module.name, None) is None:
|
||||
return False
|
||||
if self.registries[module.name].get(group_key, None) is None:
|
||||
return False
|
||||
if name in self.registries[module.name][group_key]:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
_dynamic_register = _RegisterManager()
|
||||
|
||||
|
||||
def register_parallel():
|
||||
from mmcv.parallel import MMDistributedDataParallel, MMDataParallel
|
||||
|
||||
mmddp = 'MMDistributedDataParallel'
|
||||
mmdp = 'MMDataParallel'
|
||||
|
||||
if not _dynamic_register.exists(PARALLEL, mmddp):
|
||||
_dynamic_register.add(PARALLEL, mmddp)
|
||||
PARALLEL.register_module(
|
||||
module_name=mmddp, module_cls=MMDistributedDataParallel)
|
||||
if not _dynamic_register.exists(PARALLEL, mmdp):
|
||||
_dynamic_register.add(PARALLEL, mmdp)
|
||||
PARALLEL.register_module(module_name=mmdp, module_cls=MMDataParallel)
|
||||
|
||||
|
||||
def register_hook_to_ms(hook_name, logger=None):
|
||||
"""Register EasyCV hook to ModelScope."""
|
||||
from easycv.hooks import HOOKS as _EV_HOOKS
|
||||
|
||||
if hook_name not in _EV_HOOKS._module_dict:
|
||||
raise ValueError(
|
||||
f'Not found hook "{hook_name}" in EasyCV hook registries!')
|
||||
|
||||
if _dynamic_register.exists(HOOKS, hook_name):
|
||||
return
|
||||
_dynamic_register.add(HOOKS, hook_name)
|
||||
|
||||
obj = _EV_HOOKS._module_dict[hook_name]
|
||||
HOOKS.register_module(module_name=hook_name, module_cls=obj)
|
||||
|
||||
log_str = f'Register hook "{hook_name}" to modelscope hooks.'
|
||||
logger.info(log_str) if logger is not None else logging.info(log_str)
|
||||
|
||||
|
||||
def register_part_mmcv_hooks_to_ms():
|
||||
"""Register required mmcv hooks to ModelScope.
|
||||
Currently we only registered all lr scheduler hooks in EasyCV and mmcv.
|
||||
Please refer to:
|
||||
EasyCV: https://github.com/alibaba/EasyCV/blob/master/easycv/hooks/lr_update_hook.py
|
||||
mmcv: https://github.com/open-mmlab/mmcv/blob/master/mmcv/runner/hooks/lr_updater.py
|
||||
"""
|
||||
from mmcv.runner.hooks import lr_updater
|
||||
from mmcv.runner.hooks import HOOKS as _MMCV_HOOKS
|
||||
from easycv.hooks import StepFixCosineAnnealingLrUpdaterHook, YOLOXLrUpdaterHook
|
||||
|
||||
mmcv_hooks_in_easycv = [('StepFixCosineAnnealingLrUpdaterHook',
|
||||
StepFixCosineAnnealingLrUpdaterHook),
|
||||
('YOLOXLrUpdaterHook', YOLOXLrUpdaterHook)]
|
||||
|
||||
members = inspect.getmembers(lr_updater)
|
||||
members.extend(mmcv_hooks_in_easycv)
|
||||
|
||||
for name, obj in members:
|
||||
if name in _MMCV_HOOKS._module_dict:
|
||||
if _dynamic_register.exists(HOOKS, name):
|
||||
continue
|
||||
_dynamic_register.add(HOOKS, name)
|
||||
HOOKS.register_module(
|
||||
module_name=name,
|
||||
module_cls=obj,
|
||||
)
|
||||
@@ -195,17 +195,6 @@ class MsDatasetTest(unittest.TestCase):
|
||||
)
|
||||
print(next(iter(tf_dataset)))
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_streaming_load_coco(self):
|
||||
small_coco_for_test = MsDataset.load(
|
||||
dataset_name='EasyCV/small_coco_for_test',
|
||||
split='train',
|
||||
use_streaming=True,
|
||||
download_mode=DownloadMode.FORCE_REDOWNLOAD)
|
||||
dataset_sample_dict = next(iter(small_coco_for_test))
|
||||
print(dataset_sample_dict)
|
||||
assert dataset_sample_dict.values()
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_streaming_load_uni_fold(self):
|
||||
"""Test case for loading large scale datasets."""
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import unittest
|
||||
|
||||
import cv2
|
||||
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines import pipeline
|
||||
from modelscope.utils.constant import Tasks
|
||||
from modelscope.utils.cv.image_utils import panoptic_seg_masks_to_image
|
||||
from modelscope.utils.demo_utils import DemoCompatibilityCheck
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
class EasyCVPanopticSegmentationPipelineTest(unittest.TestCase,
|
||||
DemoCompatibilityCheck):
|
||||
img_path = 'data/test/images/image_semantic_segmentation.jpg'
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.task = Tasks.image_segmentation
|
||||
self.model_id = 'damo/cv_r50_panoptic-segmentation_cocopan'
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_r50(self):
|
||||
segmentor = pipeline(task=self.task, model=self.model_id)
|
||||
outputs = segmentor(self.img_path)
|
||||
draw_img = panoptic_seg_masks_to_image(outputs[OutputKeys.MASKS])
|
||||
cv2.imwrite('result.jpg', draw_img)
|
||||
print('print ' + self.model_id + ' success')
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_demo_compatibility(self):
|
||||
self.compatibility_check()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,88 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import unittest
|
||||
from distutils.version import LooseVersion
|
||||
|
||||
import cv2
|
||||
import easycv
|
||||
import numpy as np
|
||||
from PIL import Image
|
||||
|
||||
from modelscope.outputs import OutputKeys
|
||||
from modelscope.pipelines import pipeline
|
||||
from modelscope.utils.constant import Tasks
|
||||
from modelscope.utils.cv.image_utils import semantic_seg_masks_to_image
|
||||
from modelscope.utils.demo_utils import DemoCompatibilityCheck
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
class EasyCVSegmentationPipelineTest(unittest.TestCase,
|
||||
DemoCompatibilityCheck):
|
||||
img_path = 'data/test/images/image_segmentation.jpg'
|
||||
|
||||
def setUp(self) -> None:
|
||||
self.task = Tasks.image_segmentation
|
||||
self.model_id = 'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k'
|
||||
|
||||
def _internal_test_(self, model_id):
|
||||
semantic_seg = pipeline(task=Tasks.image_segmentation, model=model_id)
|
||||
outputs = semantic_seg(self.img_path)
|
||||
|
||||
draw_img = semantic_seg_masks_to_image(outputs[OutputKeys.MASKS])
|
||||
cv2.imwrite('result.jpg', draw_img)
|
||||
print('test ' + model_id + ' DONE')
|
||||
|
||||
def _internal_test_batch_(self, model_id, num_samples=2, batch_size=2):
|
||||
# TODO: support in the future
|
||||
img = np.asarray(Image.open(self.img_path))
|
||||
num_samples = num_samples
|
||||
batch_size = batch_size
|
||||
semantic_seg = pipeline(
|
||||
task=Tasks.image_segmentation,
|
||||
model=model_id,
|
||||
batch_size=batch_size)
|
||||
outputs = semantic_seg([self.img_path] * num_samples)
|
||||
|
||||
self.assertEqual(semantic_seg.predict_op.batch_size, batch_size)
|
||||
self.assertEqual(len(outputs), num_samples)
|
||||
|
||||
for output in outputs:
|
||||
self.assertListEqual(
|
||||
list(img.shape)[:2], list(output['seg_pred'].shape))
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_segformer_b0(self):
|
||||
model_id = 'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k'
|
||||
self._internal_test_(model_id)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_segformer_b1(self):
|
||||
model_id = 'damo/cv_segformer-b1_image_semantic-segmentation_coco-stuff164k'
|
||||
self._internal_test_(model_id)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_segformer_b2(self):
|
||||
model_id = 'damo/cv_segformer-b2_image_semantic-segmentation_coco-stuff164k'
|
||||
self._internal_test_(model_id)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_segformer_b3(self):
|
||||
model_id = 'damo/cv_segformer-b3_image_semantic-segmentation_coco-stuff164k'
|
||||
self._internal_test_(model_id)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_segformer_b4(self):
|
||||
model_id = 'damo/cv_segformer-b4_image_semantic-segmentation_coco-stuff164k'
|
||||
self._internal_test_(model_id)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_segformer_b5(self):
|
||||
model_id = 'damo/cv_segformer-b5_image_semantic-segmentation_coco-stuff164k'
|
||||
self._internal_test_(model_id)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_demo_compatibility(self):
|
||||
self.compatibility_check()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,238 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import json
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Models, Pipelines, Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.config import Config
|
||||
from modelscope.utils.constant import LogKeys, ModeKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import DistributedTestCase, test_level
|
||||
from modelscope.utils.torch_utils import is_master
|
||||
|
||||
|
||||
def train_func(work_dir, dist=False, log_interval=3, imgs_per_gpu=4):
|
||||
import easycv
|
||||
config_path = os.path.join(
|
||||
os.path.dirname(easycv.__file__),
|
||||
'configs/detection/yolox/yolox_s_8xb16_300e_coco.py')
|
||||
|
||||
cfg = Config.from_file(config_path)
|
||||
|
||||
cfg.log_config.update(
|
||||
dict(hooks=[
|
||||
dict(type='TextLoggerHook'),
|
||||
dict(type='TensorboardLoggerHook')
|
||||
])) # not support TensorboardLoggerHookV2
|
||||
|
||||
ms_cfg_file = os.path.join(work_dir, 'ms_yolox_s_8xb16_300e_coco.json')
|
||||
from easycv.utils.ms_utils import to_ms_config
|
||||
|
||||
if is_master():
|
||||
to_ms_config(
|
||||
cfg,
|
||||
dump=True,
|
||||
task=Tasks.image_object_detection,
|
||||
ms_model_name=Models.yolox,
|
||||
pipeline_name=Pipelines.easycv_detection,
|
||||
save_path=ms_cfg_file)
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_for_test', namespace='EasyCV', split='train')
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_for_test',
|
||||
namespace='EasyCV',
|
||||
split='validation')
|
||||
|
||||
cfg_options = {
|
||||
'train.max_epochs':
|
||||
2,
|
||||
'train.dataloader.batch_size_per_gpu':
|
||||
imgs_per_gpu,
|
||||
'evaluation.dataloader.batch_size_per_gpu':
|
||||
2,
|
||||
'train.hooks': [
|
||||
{
|
||||
'type': 'CheckpointHook',
|
||||
'interval': 1
|
||||
},
|
||||
{
|
||||
'type': 'EvaluationHook',
|
||||
'interval': 1
|
||||
},
|
||||
{
|
||||
'type': 'TextLoggerHook',
|
||||
'ignore_rounding_keys': None,
|
||||
'interval': log_interval
|
||||
},
|
||||
]
|
||||
}
|
||||
kwargs = dict(
|
||||
cfg_file=ms_cfg_file,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=work_dir,
|
||||
cfg_options=cfg_options,
|
||||
launcher='pytorch' if dist else None)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestSingleGpu(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
self.tmp_dir = tempfile.TemporaryDirectory().name
|
||||
if not os.path.exists(self.tmp_dir):
|
||||
os.makedirs(self.tmp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
shutil.rmtree(self.tmp_dir, ignore_errors=True)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_single_gpu(self):
|
||||
train_func(self.tmp_dir)
|
||||
|
||||
results_files = os.listdir(self.tmp_dir)
|
||||
json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
|
||||
with open(json_files[0], 'r', encoding='utf-8') as f:
|
||||
lines = [i.strip() for i in f.readlines()]
|
||||
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.TRAIN,
|
||||
LogKeys.EPOCH: 1,
|
||||
LogKeys.ITER: 3,
|
||||
LogKeys.LR: 0.00029
|
||||
}, json.loads(lines[0]))
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.EVAL,
|
||||
LogKeys.EPOCH: 1,
|
||||
LogKeys.ITER: 10
|
||||
}, json.loads(lines[1]))
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.TRAIN,
|
||||
LogKeys.EPOCH: 2,
|
||||
LogKeys.ITER: 3,
|
||||
LogKeys.LR: 0.00205
|
||||
}, json.loads(lines[2]))
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.EVAL,
|
||||
LogKeys.EPOCH: 2,
|
||||
LogKeys.ITER: 10
|
||||
}, json.loads(lines[3]))
|
||||
self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files)
|
||||
for i in [0, 2]:
|
||||
self.assertIn(LogKeys.DATA_LOAD_TIME, lines[i])
|
||||
self.assertIn(LogKeys.ITER_TIME, lines[i])
|
||||
self.assertIn(LogKeys.MEMORY, lines[i])
|
||||
self.assertIn('total_loss', lines[i])
|
||||
for i in [1, 3]:
|
||||
self.assertIn(
|
||||
'CocoDetectionEvaluator_DetectionBoxes_Precision/mAP',
|
||||
lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP', lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP@.50IOU', lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP@.75IOU', lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP (small)', lines[i])
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available()
|
||||
or torch.cuda.device_count() <= 1, 'distributed unittest')
|
||||
class EasyCVTrainerTestMultiGpus(DistributedTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
self.tmp_dir = tempfile.TemporaryDirectory().name
|
||||
if not os.path.exists(self.tmp_dir):
|
||||
os.makedirs(self.tmp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
shutil.rmtree(self.tmp_dir, ignore_errors=True)
|
||||
|
||||
@unittest.skipUnless(test_level() >= 2, 'skip test in current test level')
|
||||
def test_multi_gpus(self):
|
||||
self.start(
|
||||
train_func,
|
||||
num_gpus=2,
|
||||
work_dir=self.tmp_dir,
|
||||
dist=True,
|
||||
log_interval=2,
|
||||
imgs_per_gpu=5)
|
||||
|
||||
results_files = os.listdir(self.tmp_dir)
|
||||
json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
|
||||
with open(json_files[0], 'r', encoding='utf-8') as f:
|
||||
lines = [i.strip() for i in f.readlines()]
|
||||
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.TRAIN,
|
||||
LogKeys.EPOCH: 1,
|
||||
LogKeys.ITER: 2,
|
||||
LogKeys.LR: 0.0002
|
||||
}, json.loads(lines[0]))
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.EVAL,
|
||||
LogKeys.EPOCH: 1,
|
||||
LogKeys.ITER: 5
|
||||
}, json.loads(lines[1]))
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.TRAIN,
|
||||
LogKeys.EPOCH: 2,
|
||||
LogKeys.ITER: 2,
|
||||
LogKeys.LR: 0.0018
|
||||
}, json.loads(lines[2]))
|
||||
self.assertDictContainsSubset(
|
||||
{
|
||||
LogKeys.MODE: ModeKeys.EVAL,
|
||||
LogKeys.EPOCH: 2,
|
||||
LogKeys.ITER: 5
|
||||
}, json.loads(lines[3]))
|
||||
|
||||
self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files)
|
||||
|
||||
for i in [0, 2]:
|
||||
self.assertIn(LogKeys.DATA_LOAD_TIME, lines[i])
|
||||
self.assertIn(LogKeys.ITER_TIME, lines[i])
|
||||
self.assertIn(LogKeys.MEMORY, lines[i])
|
||||
self.assertIn('total_loss', lines[i])
|
||||
for i in [1, 3]:
|
||||
self.assertIn(
|
||||
'CocoDetectionEvaluator_DetectionBoxes_Precision/mAP',
|
||||
lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP', lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP@.50IOU', lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP@.75IOU', lines[i])
|
||||
self.assertIn('DetectionBoxes_Precision/mAP (small)', lines[i])
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,69 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import LogKeys
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestDetectionDino(unittest.TestCase):
|
||||
model_id = 'damo/cv_swinl_image-object-detection_dino'
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
|
||||
def _train(self, tmp_dir):
|
||||
cfg_options = {'train.max_epochs': 1}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_for_test',
|
||||
namespace='EasyCV',
|
||||
split='train')
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_for_test',
|
||||
namespace='EasyCV',
|
||||
split='validation')
|
||||
|
||||
kwargs = dict(
|
||||
model=self.model_id,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_trainer_single_gpu(self):
|
||||
temp_file_dir = tempfile.TemporaryDirectory()
|
||||
tmp_dir = temp_file_dir.name
|
||||
if not os.path.exists(tmp_dir):
|
||||
os.makedirs(tmp_dir)
|
||||
|
||||
self._train(tmp_dir)
|
||||
|
||||
results_files = os.listdir(tmp_dir)
|
||||
json_files = glob.glob(os.path.join(tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files)
|
||||
|
||||
temp_file_dir.cleanup()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,72 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import DownloadMode, LogKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestFace2DKeypoints(unittest.TestCase):
|
||||
model_id = 'damo/cv_mobilenet_face-2d-keypoints_alignment'
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
|
||||
def _train(self, tmp_dir):
|
||||
cfg_options = {'train.max_epochs': 2}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='face_2d_keypoints_dataset',
|
||||
namespace='modelscope',
|
||||
split='train',
|
||||
download_mode=DownloadMode.REUSE_DATASET_IF_EXISTS)
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='face_2d_keypoints_dataset',
|
||||
namespace='modelscope',
|
||||
split='train',
|
||||
download_mode=DownloadMode.REUSE_DATASET_IF_EXISTS)
|
||||
|
||||
kwargs = dict(
|
||||
model=self.model_id,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
@unittest.skip(
|
||||
'skip since face_2d_keypoints_dataset is set to private for now')
|
||||
def test_trainer_single_gpu(self):
|
||||
temp_file_dir = tempfile.TemporaryDirectory()
|
||||
tmp_dir = temp_file_dir.name
|
||||
if not os.path.exists(tmp_dir):
|
||||
os.makedirs(tmp_dir)
|
||||
|
||||
self._train(tmp_dir)
|
||||
|
||||
results_files = os.listdir(tmp_dir)
|
||||
json_files = glob.glob(os.path.join(tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files)
|
||||
|
||||
temp_file_dir.cleanup()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,72 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import DownloadMode, LogKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestHand2dKeypoints(unittest.TestCase):
|
||||
model_id = 'damo/cv_hrnetw18_hand-pose-keypoints_coco-wholebody'
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
self.tmp_dir = tempfile.TemporaryDirectory().name
|
||||
if not os.path.exists(self.tmp_dir):
|
||||
os.makedirs(self.tmp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
shutil.rmtree(self.tmp_dir, ignore_errors=True)
|
||||
|
||||
def _train(self):
|
||||
cfg_options = {'train.max_epochs': 20}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='cv_hand_2d_keypoints_coco_wholebody',
|
||||
namespace='chenhyer',
|
||||
split='subtrain',
|
||||
download_mode=DownloadMode.FORCE_REDOWNLOAD)
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='cv_hand_2d_keypoints_coco_wholebody',
|
||||
namespace='chenhyer',
|
||||
split='subtrain',
|
||||
download_mode=DownloadMode.FORCE_REDOWNLOAD)
|
||||
|
||||
kwargs = dict(
|
||||
model=self.model_id,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=self.tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_trainer_single_gpu(self):
|
||||
self._train()
|
||||
|
||||
results_files = os.listdir(self.tmp_dir)
|
||||
json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_10.pth', results_files)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_20.pth', results_files)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,63 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import DownloadMode, LogKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
class EasyCVTrainerTestHandDetection(unittest.TestCase):
|
||||
model_id = 'damo/cv_yolox-pai_hand-detection'
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
|
||||
def _train(self, tmp_dir):
|
||||
cfg_options = {'train.max_epochs': 2}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='hand_detection_dataset', split='subtrain')
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='hand_detection_dataset', split='subtrain')
|
||||
|
||||
kwargs = dict(
|
||||
model=self.model_id,
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
@unittest.skipUnless(test_level() >= 1, 'skip test in current test level')
|
||||
def test_trainer_single_gpu(self):
|
||||
temp_file_dir = tempfile.TemporaryDirectory()
|
||||
tmp_dir = temp_file_dir.name
|
||||
if not os.path.exists(tmp_dir):
|
||||
os.makedirs(tmp_dir)
|
||||
|
||||
self._train(tmp_dir)
|
||||
|
||||
results_files = os.listdir(tmp_dir)
|
||||
# json_files = glob.glob(os.path.join(tmp_dir, '*.log.json'))
|
||||
self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files)
|
||||
|
||||
temp_file_dir.cleanup()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,70 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
from mmcv.runner.hooks import HOOKS as MMCV_HOOKS
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import LogKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestPanopticMask2Former(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
self.tmp_dir = tempfile.TemporaryDirectory().name
|
||||
if not os.path.exists(self.tmp_dir):
|
||||
os.makedirs(self.tmp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
shutil.rmtree(self.tmp_dir, ignore_errors=True)
|
||||
|
||||
def _train(self):
|
||||
cfg_options = {'train.max_epochs': 1}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='COCO2017_panopic_subset', split='train')
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='COCO2017_panopic_subset', split='validation')
|
||||
kwargs = dict(
|
||||
model='damo/cv_r50_panoptic-segmentation_cocopan',
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=self.tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
|
||||
hook_name = 'YOLOXLrUpdaterHook'
|
||||
mmcv_hook = MMCV_HOOKS._module_dict.pop(hook_name, None)
|
||||
|
||||
trainer.train()
|
||||
|
||||
MMCV_HOOKS._module_dict[hook_name] = mmcv_hook
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_single_gpu_mask2former_r50(self):
|
||||
self._train()
|
||||
|
||||
results_files = os.listdir(self.tmp_dir)
|
||||
json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,99 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from modelscope.hub.snapshot_download import snapshot_download
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import DownloadMode, LogKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestRealtimeObjectDetection(unittest.TestCase):
|
||||
model_id = 'damo/cv_cspnet_image-object-detection_yolox'
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
|
||||
def _train(self, tmp_dir):
|
||||
# cfg_options = {'train.max_epochs': 2}
|
||||
self.cache_path = snapshot_download(self.model_id)
|
||||
cfg_options = {
|
||||
'train.max_epochs':
|
||||
2,
|
||||
'train.dataloader.batch_size_per_gpu':
|
||||
4,
|
||||
'evaluation.dataloader.batch_size_per_gpu':
|
||||
2,
|
||||
'train.hooks': [
|
||||
{
|
||||
'type': 'CheckpointHook',
|
||||
'interval': 1
|
||||
},
|
||||
{
|
||||
'type': 'EvaluationHook',
|
||||
'interval': 1
|
||||
},
|
||||
{
|
||||
'type': 'TextLoggerHook',
|
||||
'ignore_rounding_keys': None,
|
||||
'interval': 2
|
||||
},
|
||||
],
|
||||
'load_from':
|
||||
os.path.join(self.cache_path, 'pytorch_model.bin')
|
||||
}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_for_test',
|
||||
namespace='EasyCV',
|
||||
split='train')
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_for_test',
|
||||
namespace='EasyCV',
|
||||
split='validation')
|
||||
|
||||
kwargs = dict(
|
||||
model=self.model_id,
|
||||
# model_revision='v1.0.2',
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
@unittest.skipUnless(
|
||||
test_level() >= 0,
|
||||
'skip since face_2d_keypoints_dataset is set to private for now')
|
||||
def test_trainer_single_gpu(self):
|
||||
temp_file_dir = tempfile.TemporaryDirectory()
|
||||
tmp_dir = temp_file_dir.name
|
||||
if not os.path.exists(tmp_dir):
|
||||
os.makedirs(tmp_dir)
|
||||
|
||||
self._train(tmp_dir)
|
||||
|
||||
results_files = os.listdir(tmp_dir)
|
||||
json_files = glob.glob(os.path.join(tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files)
|
||||
|
||||
temp_file_dir.cleanup()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -1,72 +0,0 @@
|
||||
# Copyright (c) Alibaba, Inc. and its affiliates.
|
||||
import glob
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
import torch
|
||||
|
||||
from modelscope.metainfo import Trainers
|
||||
from modelscope.msdatasets import MsDataset
|
||||
from modelscope.trainers import build_trainer
|
||||
from modelscope.utils.constant import LogKeys, Tasks
|
||||
from modelscope.utils.logger import get_logger
|
||||
from modelscope.utils.test_utils import test_level
|
||||
|
||||
|
||||
@unittest.skipIf(not torch.cuda.is_available(), 'cuda unittest')
|
||||
class EasyCVTrainerTestSegformer(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.logger = get_logger()
|
||||
self.logger.info(('Testing %s.%s' %
|
||||
(type(self).__name__, self._testMethodName)))
|
||||
self.tmp_dir = tempfile.TemporaryDirectory().name
|
||||
if not os.path.exists(self.tmp_dir):
|
||||
os.makedirs(self.tmp_dir)
|
||||
|
||||
def tearDown(self):
|
||||
super().tearDown()
|
||||
shutil.rmtree(self.tmp_dir, ignore_errors=True)
|
||||
|
||||
def _train(self):
|
||||
|
||||
cfg_options = {
|
||||
'train.max_epochs': 2,
|
||||
'model.decode_head.norm_cfg.type': 'BN'
|
||||
}
|
||||
|
||||
trainer_name = Trainers.easycv
|
||||
train_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_stuff164k',
|
||||
namespace='EasyCV',
|
||||
split='train')
|
||||
eval_dataset = MsDataset.load(
|
||||
dataset_name='small_coco_stuff164k',
|
||||
namespace='EasyCV',
|
||||
split='validation')
|
||||
kwargs = dict(
|
||||
model=
|
||||
'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k',
|
||||
train_dataset=train_dataset,
|
||||
eval_dataset=eval_dataset,
|
||||
work_dir=self.tmp_dir,
|
||||
cfg_options=cfg_options)
|
||||
|
||||
trainer = build_trainer(trainer_name, kwargs)
|
||||
trainer.train()
|
||||
|
||||
@unittest.skipUnless(test_level() >= 0, 'skip test in current test level')
|
||||
def test_single_gpu_segformer(self):
|
||||
self._train()
|
||||
|
||||
results_files = os.listdir(self.tmp_dir)
|
||||
json_files = glob.glob(os.path.join(self.tmp_dir, '*.log.json'))
|
||||
self.assertEqual(len(json_files), 1)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_1.pth', results_files)
|
||||
self.assertIn(f'{LogKeys.EPOCH}_2.pth', results_files)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -11,33 +11,18 @@ model_trainer_map = {
|
||||
['tests/trainers/audio/test_separation_trainer.py'],
|
||||
'speech_tts/speech_sambert-hifigan_tts_zh-cn_multisp_pretrain_16k':
|
||||
['tests/trainers/audio/test_tts_trainer.py'],
|
||||
'damo/cv_mobilenet_face-2d-keypoints_alignment':
|
||||
['tests/trainers/easycv/test_easycv_trainer_face_2d_keypoints.py'],
|
||||
'damo/cv_hrnetw18_hand-pose-keypoints_coco-wholebody':
|
||||
['tests/trainers/easycv/test_easycv_trainer_hand_2d_keypoints.py'],
|
||||
'damo/cv_yolox-pai_hand-detection':
|
||||
['tests/trainers/easycv/test_easycv_trainer_hand_detection.py'],
|
||||
'damo/cv_r50_panoptic-segmentation_cocopan':
|
||||
['tests/trainers/easycv/test_easycv_trainer_panoptic_mask2former.py'],
|
||||
'damo/cv_segformer-b0_image_semantic-segmentation_coco-stuff164k':
|
||||
['tests/trainers/easycv/test_segformer.py'],
|
||||
'damo/cv_resnet_carddetection_scrfd34gkps':
|
||||
['tests/trainers/test_card_detection_scrfd_trainer.py'],
|
||||
'damo/multi-modal_clip-vit-base-patch16_zh': [
|
||||
'tests/trainers/test_clip_trainer.py'
|
||||
],
|
||||
'damo/nlp_space_pretrained-dialog-model': [
|
||||
'tests/trainers/test_dialog_intent_trainer.py'
|
||||
],
|
||||
'damo/cv_resnet_facedetection_scrfd10gkps': [
|
||||
'tests/trainers/test_face_detection_scrfd_trainer.py'
|
||||
],
|
||||
'damo/nlp_structbert_faq-question-answering_chinese-base': [
|
||||
'tests/trainers/test_finetune_faq_question_answering.py'
|
||||
],
|
||||
'PAI/nlp_gpt3_text-generation_0.35B_MoE-64': [
|
||||
'tests/trainers/test_finetune_gpt_moe.py'
|
||||
],
|
||||
'damo/multi-modal_clip-vit-base-patch16_zh':
|
||||
['tests/trainers/test_clip_trainer.py'],
|
||||
'damo/nlp_space_pretrained-dialog-model':
|
||||
['tests/trainers/test_dialog_intent_trainer.py'],
|
||||
'damo/cv_resnet_facedetection_scrfd10gkps':
|
||||
['tests/trainers/test_face_detection_scrfd_trainer.py'],
|
||||
'damo/nlp_structbert_faq-question-answering_chinese-base':
|
||||
['tests/trainers/test_finetune_faq_question_answering.py'],
|
||||
'PAI/nlp_gpt3_text-generation_0.35B_MoE-64':
|
||||
['tests/trainers/test_finetune_gpt_moe.py'],
|
||||
'damo/nlp_gpt3_text-generation_1.3B': [
|
||||
'tests/trainers/test_finetune_gpt3.py'
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user