예제 #1
0
def prepare_for_launch():

    #runner = Detectron2GoRunner()
    runner = GeneralizedRCNNRunner()
    cfg = runner.get_default_cfg()
    cfg.merge_from_file(model_zoo.get_config_file("mask_rcnn_fbnetv3a_C4.yaml"))
    cfg.MODEL_EMA.ENABLED = False
    cfg.DATASETS.TRAIN = ("my_dataset_train",)
    cfg.DATASETS.TEST = ("my_dataset_val",)
    cfg.DATALOADER.NUM_WORKERS = 2 #no of cpu to be used
    cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("mask_rcnn_fbnetv3a_C4.yaml")  # Let training initialize from model zoo
    cfg.SOLVER.IMS_PER_BATCH = 2
    cfg.INPUT.CROP.ENABLED = True
    cfg.QUANTIZATION.BACKEND = 'qnnpack'
    cfg.INPUT.MAX_SIZE_TEST = 160
    cfg.INPUT.MIN_SIZE_TEST = 112
    #cfg.INPUT.RANDOM_FLIP = 'horizontal'
    #cfg.INPUT.RANDOM_FLIP = 'vertical'
    cfg.SOLVER.BASE_LR = 0.003  # pick a good LR
    cfg.SOLVER.MAX_ITER = 20   # you will need to train longer for a practical dataset
    cfg.SOLVER.STEPS = []        # do not decay learning rate
    cfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.8   # set the testing threshold for this model
    cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 40   # faster, and good enough for this toy dataset (default: 512)
    cfg.MODEL.ROI_HEADS.NUM_CLASSES = 1  # only has one class (mahesh). (see https://detectron2.readthedocs.io/tutorials/datasets.html#update-the-config-for-new-datasets)
    # NOTE: this config means the number of classes, but a few popular unofficial tutorials incorrect uses num_classes+1 here.
    os.makedirs(cfg.OUTPUT_DIR, exist_ok=True)
    return cfg, runner
예제 #2
0
        def setUp(self):
            runner = GeneralizedRCNNRunner()
            self.cfg = runner.get_default_cfg()
            self.is_mcs = False
            self.setup_custom_test()

            # NOTE: change some config to make the model run fast
            self.cfg.merge_from_list(get_quick_test_config_opts())

            self.cfg.merge_from_list(["MODEL.DEVICE", "cpu"])
            self.test_model = runner.build_model(self.cfg, eval_only=True)
예제 #3
0
    def test_export_torchvision_format(self):
        runner = GeneralizedRCNNRunner()
        cfg = runner.get_default_cfg()
        cfg.merge_from_file("detectron2go://mask_rcnn_fbnetv3a_dsmask_C4.yaml")
        cfg.merge_from_list(get_quick_test_config_opts())

        cfg.merge_from_list(["MODEL.DEVICE", "cpu"])
        pytorch_model = runner.build_model(cfg, eval_only=True)

        from typing import Dict, List

        class Wrapper(torch.nn.Module):
            def __init__(self, model):
                super().__init__()
                self.model = model

            def forward(self, inputs: List[torch.Tensor]):
                x = inputs[0].unsqueeze(0) * 255
                scale = 320.0 / min(x.shape[-2], x.shape[-1])
                x = torch.nn.functional.interpolate(
                    x,
                    scale_factor=scale,
                    mode="bilinear",
                    align_corners=True,
                    recompute_scale_factor=True,
                )
                out = self.model(x[0])
                res: Dict[str, torch.Tensor] = {}
                res["boxes"] = out[0] / scale
                res["labels"] = out[2]
                res["scores"] = out[1]
                return inputs, [res]

        size_divisibility = max(pytorch_model.backbone.size_divisibility, 10)
        h, w = size_divisibility, size_divisibility * 2
        with create_detection_data_loader_on_toy_dataset(
                cfg, h, w, is_train=False) as data_loader:
            with make_temp_directory(
                    "test_export_torchvision_format") as tmp_dir:
                predictor_path = convert_and_export_predictor(
                    cfg,
                    copy.deepcopy(pytorch_model),
                    "torchscript",
                    tmp_dir,
                    data_loader,
                )

                orig_model = torch.jit.load(
                    os.path.join(predictor_path, "model.jit"))
                wrapped_model = Wrapper(orig_model)
                # optionally do a forward
                wrapped_model([torch.rand(3, 600, 600)])
                scripted_model = torch.jit.script(wrapped_model)
                scripted_model.save(os.path.join(tmp_dir, "new_file.pt"))
예제 #4
0
class TestKmeansAnchors(unittest.TestCase):
    def setUp(self):
        self.runner = GeneralizedRCNNRunner()

    def _get_default_cfg(self):
        cfg = self.runner.get_default_cfg()
        add_kmeans_anchors_cfg(cfg)
        return cfg

    @unittest.skip("This can only run locally and takes significant of time")
    def test_matching_previous_results(self):
        cfg = self._get_default_cfg()
        cfg.INPUT.MIN_SIZE_TRAIN = (144, )
        cfg.MODEL.KMEANS_ANCHORS.KMEANS_ANCHORS_ON = True
        cfg.MODEL.KMEANS_ANCHORS.NUM_CLUSTERS = 10
        cfg.MODEL.KMEANS_ANCHORS.NUM_TRAINING_IMG = 512
        cfg.MODEL.KMEANS_ANCHORS.DATASETS = ()

        # NOTE: create a data loader that samples exact the same as previous
        # implementation. In D2Go, we will rely on the train loader instead.
        # NOTE: in order to load OV580_XRM dataset, change the IM_DIR to:
        # "/mnt/vol/gfsai-east/aml/mobile-vision//dataset/oculus/hand_tracking//torch/Segmentation/OV580_XRM_640x480_V3_new_rerun/images"  # noqa
        data_loader = build_sequence_loader(
            cfg,
            # dataset_name="coco_2014_valminusminival",
            # dataset_name="OV580_XRM_640x480_V3_train",
            dataset_name="OV580_XRM_640x480_V3_heldOut_small_512",
            mapper=self.runner.get_mapper(cfg, is_train=True),
            total_samples=cfg.MODEL.KMEANS_ANCHORS.NUM_TRAINING_IMG,
            batch_size=3,
        )

        kmeans_anchors = compute_kmeans_anchors(cfg,
                                                data_loader,
                                                sort_by_area=False,
                                                _stride=16,
                                                _legacy_plus_one=True)

        # Taken from D9849940
        reference_anchors = np.array([
            [-15.33554182, -15.29361029, 31.33554182, 31.29361029],  # noqa
            [-9.34156693, -9.32553548, 25.34156693, 25.32553548],  # noqa
            [-6.03052776, -6.02034167, 22.03052776, 22.02034167],  # noqa
            [-2.25951741, -2.182888, 18.25951741, 18.182888],  # noqa
            [-18.93553378, -18.93553403, 34.93553378, 34.93553403],  # noqa
            [-12.69068356, -12.73989029, 28.69068356, 28.73989029],  # noqa
            [-24.73489189, -24.73489246, 40.73489189, 40.73489246],  # noqa
            [-4.06014466, -4.06014469, 20.06014466, 20.06014469],  # noqa
            [-7.61036119, -7.60467538, 23.61036119, 23.60467538],  # noqa
            [-10.88200579, -10.87634414, 26.88200579, 26.87634414],  # noqa
        ])
        np.testing.assert_allclose(kmeans_anchors,
                                   reference_anchors,
                                   atol=1e-6)

    def test_build_model(self):
        cfg = self._get_default_cfg()
        cfg.INPUT.MIN_SIZE_TRAIN = (60, )
        cfg.MODEL.KMEANS_ANCHORS.KMEANS_ANCHORS_ON = True
        cfg.MODEL.KMEANS_ANCHORS.NUM_CLUSTERS = 3
        cfg.MODEL.KMEANS_ANCHORS.NUM_TRAINING_IMG = 5
        cfg.MODEL.KMEANS_ANCHORS.DATASETS = ("toy_dataset", )

        cfg.MODEL.DEVICE = "cpu"
        cfg.MODEL.ANCHOR_GENERATOR.NAME = "KMeansAnchorGenerator"

        with register_toy_coco_dataset(
                "toy_dataset",
                image_size=(80, 60),  # w, h
                num_images=cfg.MODEL.KMEANS_ANCHORS.NUM_TRAINING_IMG,
        ):
            model = self.runner.build_model(cfg)
            trainer = SimpleTrainer(model, data_loader=[], optimizer=None)
            trainer_hooks = [compute_kmeans_anchors_hook(self.runner, cfg)]
            trainer.register_hooks(trainer_hooks)
            trainer.before_train()
            anchor_generator = model.proposal_generator.anchor_generator
            cell_anchors = list(anchor_generator.cell_anchors)
            gt_anchors = np.array([
                [-20, -15, 20, 15]  # toy_dataset's bbox is half size of image
                for _ in range(cfg.MODEL.KMEANS_ANCHORS.NUM_CLUSTERS)
            ])
            np.testing.assert_allclose(cell_anchors[0], gt_anchors)
예제 #5
0
from d2go.runner import Detectron2GoRunner
from detectron2 import model_zoo
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
from detectron2.utils.visualizer import Visualizer
from detectron2.utils.video_visualizer import VideoVisualizer
from detectron2.data import MetadataCatalog
from detectron2.utils.visualizer import ColorMode
from lockit import lock, unlock
from mobile_cv.predictor.api import create_predictor
from d2go.utils.demo_predictor import DemoPredictor

from d2go.runner import GeneralizedRCNNRunner

runner = GeneralizedRCNNRunner()
cfg = runner.get_default_cfg()

#runner = Detectron2GoRunner()
#cfg = runner.get_default_cfg()

#cfg.merge_from_file(model_zoo.get_config_file("COCO-Detection/faster_rcnn_R_50_C4_1x.yaml"))
#cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-Detection/faster_rcnn_R_50_C4_1x.yaml")

#cfg.merge_from_file(model_zoo.get_config_file("COCO-InstanceSegmentation/mask_rcnn_R_50_C4_1x.yaml"))
#cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url("COCO-InstanceSegmentation/mask_rcnn_R_50_C4_1x.yaml")

cfg.merge_from_file(
    r"/home/pi/Desktop/project xcv/torchscript_int8@tracing/config2.yml")
cfg.MODEL.WEIGHTS = os.path.join(
    r"/home/pi/Desktop/project xcv/torchscript_int8@tracing/data.pth")
cfg.MODEL.DEVICE = "cpu"  #"cuda"
예제 #6
0
    class TemplateTestCase(unittest.TestCase
                           ):  # TODO: maybe subclass from TestMetaArch
        def setUp(self):
            # Add APIs to D2's meta arch, this is usually called in runner's setup,
            # however in unittest it needs to be called sperarately.
            # TODO: maybe we should apply this by default
            patch_d2_meta_arch()

            self.setup_test_dir()
            assert hasattr(self, "test_dir")

            self.setup_custom_test()
            assert hasattr(self, "runner")
            assert hasattr(self, "cfg")
            self.force_apply_overwrite_opts()

            self.test_model = self.runner.build_model(self.cfg, eval_only=True)

        def setup_test_dir(self):
            self.test_dir = tempfile.mkdtemp(prefix="test_export_")
            self.addCleanup(shutil.rmtree, self.test_dir)

        def setup_custom_test(self):
            """
            Override this when using different runner, using different base config file,
            or setting specific config for certain test.
            """
            self.runner = GeneralizedRCNNRunner()
            self.cfg = self.runner.get_default_cfg()
            # subclass can call: self.cfg.merge_from_file(...)

        def force_apply_overwrite_opts(self):
            """
            Recommend only overriding this for a group of tests, while indivisual test
            should have its own `setup_custom_test`.
            """
            # update config to make the model run fast
            self.cfg.merge_from_list(get_quick_test_config_opts())
            # forcing test on CPU
            self.cfg.merge_from_list(["MODEL.DEVICE", "cpu"])

        def _test_export(self, predictor_type, compare_match=True):
            size_divisibility = max(self.test_model.backbone.size_divisibility,
                                    10)
            h, w = size_divisibility, size_divisibility * 2
            with create_fake_detection_data_loader(
                    h, w, is_train=False) as data_loader:
                inputs = next(iter(data_loader))

                # TODO: the export may change model it self, need to fix this
                model_to_export = copy.deepcopy(self.test_model)
                predictor_path = convert_and_export_predictor(
                    self.cfg,
                    model_to_export,
                    predictor_type,
                    self.test_dir,
                    data_loader,
                )

                predictor = create_predictor(predictor_path)
                predicotr_outputs = predictor(inputs)
                _validate_outputs(inputs, predicotr_outputs)

                if compare_match:
                    with torch.no_grad():
                        pytorch_outputs = self.test_model(inputs)

                    assert_instances_allclose(
                        predicotr_outputs[0]["instances"],
                        pytorch_outputs[0]["instances"],
                    )

            return predictor_path

        # TODO: add test_train

        def _test_inference(self):
            size_divisibility = max(self.test_model.backbone.size_divisibility,
                                    10)
            h, w = size_divisibility, size_divisibility * 2

            with create_fake_detection_data_loader(
                    h, w, is_train=False) as data_loader:
                inputs = next(iter(data_loader))

            with torch.no_grad():
                outputs = self.test_model(inputs)
            _validate_outputs(inputs, outputs)
예제 #7
0
    class TemplateTestCase(unittest.TestCase
                           ):  # TODO: maybe subclass from TestMetaArch
        def setUp(self):
            # Add APIs to D2's meta arch, this is usually called in runner's setup,
            # however in unittest it needs to be called sperarately.
            # TODO: maybe we should apply this by default
            patch_d2_meta_arch()

            self.setup_test_dir()
            assert hasattr(self, "test_dir")

            self.setup_custom_test()
            assert hasattr(self, "runner")
            assert hasattr(self, "cfg")
            self.force_apply_overwrite_opts()

            self.test_model = self.runner.build_model(self.cfg, eval_only=True)

        def setup_test_dir(self):
            self.test_dir = tempfile.mkdtemp(prefix="test_export_")
            self.addCleanup(shutil.rmtree, self.test_dir)

        def _get_test_image_sizes_default(self, is_train):
            # model should work for any size, so don't alway use power of 2 or multiple
            # of size_divisibility for testing.
            side_length = max(self.test_model.backbone.size_divisibility, 10)
            # make it non-square to cover error caused by messing up width & height
            h, w = side_length, side_length * 2
            return h, w

        def _get_test_image_size_no_resize(self, is_train):
            # use cfg.INPUT to make sure data loader doesn't resize the image
            if is_train:
                assert len(self.cfg.INPUT.MAX_SIZE_TRAIN) == 1
                h = self.cfg.INPUT.MIN_SIZE_TRAIN[0]
                w = self.cfg.INPUT.MAX_SIZE_TRAIN
            else:
                h = self.cfg.INPUT.MIN_SIZE_TEST
                w = self.cfg.INPUT.MAX_SIZE_TEST
            return h, w

        def _get_test_image_sizes(self, is_train):
            """override this method to use other image size strategy"""
            return self._get_test_image_sizes_default(is_train)

        def setup_custom_test(self):
            """
            Override this when using different runner, using different base config file,
            or setting specific config for certain test.
            """
            self.runner = GeneralizedRCNNRunner()
            self.cfg = self.runner.get_default_cfg()
            # subclass can call: self.cfg.merge_from_file(...)

        def force_apply_overwrite_opts(self):
            """
            Recommend only overriding this for a group of tests, while indivisual test
            should have its own `setup_custom_test`.
            """
            # update config to make the model run fast
            self.cfg.merge_from_list(get_quick_test_config_opts())
            # forcing test on CPU
            self.cfg.merge_from_list(["MODEL.DEVICE", "cpu"])

        @contextlib.contextmanager
        def _create_data_loader(self, is_train):
            """
            Creating the data loader used for the test case. Note that it's better
            to use "fake" data for quick test and isolating I/O.
            """
            image_height, image_width = self._get_test_image_sizes(
                is_train=False)
            with create_detection_data_loader_on_toy_dataset(
                    self.cfg,
                    image_height,
                    image_width,
                    is_train=is_train,
                    runner=self.runner,
            ) as data_loader:
                yield data_loader

        def _test_export(self, predictor_type, compare_match=True):
            with self._create_data_loader(is_train=False) as data_loader:
                inputs = next(iter(data_loader))

                # TODO: the export may change model it self, need to fix this
                model_to_export = copy.deepcopy(self.test_model)
                predictor_path = convert_and_export_predictor(
                    self.cfg,
                    model_to_export,
                    predictor_type,
                    self.test_dir,
                    data_loader,
                )

                predictor = create_predictor(predictor_path)
                predictor_outputs = predictor(inputs)
                _validate_outputs(inputs, predictor_outputs)

                if compare_match:
                    with torch.no_grad():
                        pytorch_outputs = self.test_model(inputs)

                    assert_instances_allclose(
                        predictor_outputs[0]["instances"],
                        pytorch_outputs[0]["instances"],
                        size_as_tensor=True,
                    )

            return predictor_path

        # TODO: add test_train

        def _test_inference(self):
            with self._create_data_loader(is_train=False) as data_loader:
                inputs = next(iter(data_loader))

            with torch.no_grad():
                outputs = self.test_model(inputs)
            _validate_outputs(inputs, outputs)