Team Ai
Apppublic

Arulkumar03/Wheat_HEAD_Detection_Counting_ComputerVision_Model

sourceHugging Facemitupdated 3y agoView on Hugging Face
0likes
config.py266 linesDownload Raw Back to config
1# -*- coding: utf-8 -*-2# Copyright (c) Facebook, Inc. and its affiliates.3 4import functools5import inspect6import logging7from fvcore.common.config import CfgNode as _CfgNode8 9from detectron2.utils.file_io import PathManager10 11 12class CfgNode(_CfgNode):13    """14    The same as `fvcore.common.config.CfgNode`, but different in:15 16    1. Use unsafe yaml loading by default.17       Note that this may lead to arbitrary code execution: you must not18       load a config file from untrusted sources before manually inspecting19       the content of the file.20    2. Support config versioning.21       When attempting to merge an old config, it will convert the old config automatically.22 23    .. automethod:: clone24    .. automethod:: freeze25    .. automethod:: defrost26    .. automethod:: is_frozen27    .. automethod:: load_yaml_with_base28    .. automethod:: merge_from_list29    .. automethod:: merge_from_other_cfg30    """31 32    @classmethod33    def _open_cfg(cls, filename):34        return PathManager.open(filename, "r")35 36    # Note that the default value of allow_unsafe is changed to True37    def merge_from_file(self, cfg_filename: str, allow_unsafe: bool = True) -> None:38        """39        Load content from the given config file and merge it into self.40 41        Args:42            cfg_filename: config filename43            allow_unsafe: allow unsafe yaml syntax44        """45        assert PathManager.isfile(cfg_filename), f"Config file '{cfg_filename}' does not exist!"46        loaded_cfg = self.load_yaml_with_base(cfg_filename, allow_unsafe=allow_unsafe)47        loaded_cfg = type(self)(loaded_cfg)48 49        # defaults.py needs to import CfgNode50        from .defaults import _C51 52        latest_ver = _C.VERSION53        assert (54            latest_ver == self.VERSION55        ), "CfgNode.merge_from_file is only allowed on a config object of latest version!"56 57        logger = logging.getLogger(__name__)58 59        loaded_ver = loaded_cfg.get("VERSION", None)60        if loaded_ver is None:61            from .compat import guess_version62 63            loaded_ver = guess_version(loaded_cfg, cfg_filename)64        assert loaded_ver <= self.VERSION, "Cannot merge a v{} config into a v{} config.".format(65            loaded_ver, self.VERSION66        )67 68        if loaded_ver == self.VERSION:69            self.merge_from_other_cfg(loaded_cfg)70        else:71            # compat.py needs to import CfgNode72            from .compat import upgrade_config, downgrade_config73 74            logger.warning(75                "Loading an old v{} config file '{}' by automatically upgrading to v{}. "76                "See docs/CHANGELOG.md for instructions to update your files.".format(77                    loaded_ver, cfg_filename, self.VERSION78                )79            )80            # To convert, first obtain a full config at an old version81            old_self = downgrade_config(self, to_version=loaded_ver)82            old_self.merge_from_other_cfg(loaded_cfg)83            new_config = upgrade_config(old_self)84            self.clear()85            self.update(new_config)86 87    def dump(self, *args, **kwargs):88        """89        Returns:90            str: a yaml string representation of the config91        """92        # to make it show up in docs93        return super().dump(*args, **kwargs)94 95 96global_cfg = CfgNode()97 98 99def get_cfg() -> CfgNode:100    """101    Get a copy of the default config.102 103    Returns:104        a detectron2 CfgNode instance.105    """106    from .defaults import _C107 108    return _C.clone()109 110 111def set_global_cfg(cfg: CfgNode) -> None:112    """113    Let the global config point to the given cfg.114 115    Assume that the given "cfg" has the key "KEY", after calling116    `set_global_cfg(cfg)`, the key can be accessed by:117    ::118        from detectron2.config import global_cfg119        print(global_cfg.KEY)120 121    By using a hacky global config, you can access these configs anywhere,122    without having to pass the config object or the values deep into the code.123    This is a hacky feature introduced for quick prototyping / research exploration.124    """125    global global_cfg126    global_cfg.clear()127    global_cfg.update(cfg)128 129 130def configurable(init_func=None, *, from_config=None):131    """132    Decorate a function or a class's __init__ method so that it can be called133    with a :class:`CfgNode` object using a :func:`from_config` function that translates134    :class:`CfgNode` to arguments.135 136    Examples:137    ::138        # Usage 1: Decorator on __init__:139        class A:140            @configurable141            def __init__(self, a, b=2, c=3):142                pass143 144            @classmethod145            def from_config(cls, cfg):   # 'cfg' must be the first argument146                # Returns kwargs to be passed to __init__147                return {"a": cfg.A, "b": cfg.B}148 149        a1 = A(a=1, b=2)  # regular construction150        a2 = A(cfg)       # construct with a cfg151        a3 = A(cfg, b=3, c=4)  # construct with extra overwrite152 153        # Usage 2: Decorator on any function. Needs an extra from_config argument:154        @configurable(from_config=lambda cfg: {"a: cfg.A, "b": cfg.B})155        def a_func(a, b=2, c=3):156            pass157 158        a1 = a_func(a=1, b=2)  # regular call159        a2 = a_func(cfg)       # call with a cfg160        a3 = a_func(cfg, b=3, c=4)  # call with extra overwrite161 162    Args:163        init_func (callable): a class's ``__init__`` method in usage 1. The164            class must have a ``from_config`` classmethod which takes `cfg` as165            the first argument.166        from_config (callable): the from_config function in usage 2. It must take `cfg`167            as its first argument.168    """169 170    if init_func is not None:171        assert (172            inspect.isfunction(init_func)173            and from_config is None174            and init_func.__name__ == "__init__"175        ), "Incorrect use of @configurable. Check API documentation for examples."176 177        @functools.wraps(init_func)178        def wrapped(self, *args, **kwargs):179            try:180                from_config_func = type(self).from_config181            except AttributeError as e:182                raise AttributeError(183                    "Class with @configurable must have a 'from_config' classmethod."184                ) from e185            if not inspect.ismethod(from_config_func):186                raise TypeError("Class with @configurable must have a 'from_config' classmethod.")187 188            if _called_with_cfg(*args, **kwargs):189                explicit_args = _get_args_from_config(from_config_func, *args, **kwargs)190                init_func(self, **explicit_args)191            else:192                init_func(self, *args, **kwargs)193 194        return wrapped195 196    else:197        if from_config is None:198            return configurable  # @configurable() is made equivalent to @configurable199        assert inspect.isfunction(200            from_config201        ), "from_config argument of configurable must be a function!"202 203        def wrapper(orig_func):204            @functools.wraps(orig_func)205            def wrapped(*args, **kwargs):206                if _called_with_cfg(*args, **kwargs):207                    explicit_args = _get_args_from_config(from_config, *args, **kwargs)208                    return orig_func(**explicit_args)209                else:210                    return orig_func(*args, **kwargs)211 212            wrapped.from_config = from_config213            return wrapped214 215        return wrapper216 217 218def _get_args_from_config(from_config_func, *args, **kwargs):219    """220    Use `from_config` to obtain explicit arguments.221 222    Returns:223        dict: arguments to be used for cls.__init__224    """225    signature = inspect.signature(from_config_func)226    if list(signature.parameters.keys())[0] != "cfg":227        if inspect.isfunction(from_config_func):228            name = from_config_func.__name__229        else:230            name = f"{from_config_func.__self__}.from_config"231        raise TypeError(f"{name} must take 'cfg' as the first argument!")232    support_var_arg = any(233        param.kind in [param.VAR_POSITIONAL, param.VAR_KEYWORD]234        for param in signature.parameters.values()235    )236    if support_var_arg:  # forward all arguments to from_config, if from_config accepts them237        ret = from_config_func(*args, **kwargs)238    else:239        # forward supported arguments to from_config240        supported_arg_names = set(signature.parameters.keys())241        extra_kwargs = {}242        for name in list(kwargs.keys()):243            if name not in supported_arg_names:244                extra_kwargs[name] = kwargs.pop(name)245        ret = from_config_func(*args, **kwargs)246        # forward the other arguments to __init__247        ret.update(extra_kwargs)248    return ret249 250 251def _called_with_cfg(*args, **kwargs):252    """253    Returns:254        bool: whether the arguments contain CfgNode and should be considered255            forwarded to from_config.256    """257    from omegaconf import DictConfig258 259    if len(args) and isinstance(args[0], (_CfgNode, DictConfig)):260        return True261    if isinstance(kwargs.pop("cfg", None), (_CfgNode, DictConfig)):262        return True263    # `from_config`'s first argument is forced to be "cfg".264    # So the above check covers all cases.265    return False266