다양한 형식의 데이터를 특정 형식으로 변환하기 위해 Dataset Converter 구현한다고 가정
# builder.py
from mmcv.utils import Registry
# create a registry for converters
CONVERTERS = Registry('converters')
converters/builder.py에서 빌더를 구현하는 파일 만듦
- 핵심 단계는 모듈을 생성할 때 구현된 모듈을 레지스트리에 등록하는 것
- @CONVERTERS.register_module()
- 문자열과 클래스(함수) 간의 매핑은 다음과 같이 빌드되고 유지
- Converter1 → <class ‘Converter1’>
- converter2 → <function ‘converter2’>
# converter1.py
from .builder import CONVERTERS
# use the registry to manage the module
@CONVERTERS.register_module()
class Converter1(object):
def __init__(self, a, b):
self.a = a
self.b = b
# converter2.py
from .builder import CONVERTERS
from .converter1 import Converter1
@CONVERTERS.register_module()
def converter2(a, b):
return Converter1(a, b)
모듈이 성공적으로 등록되면 구성을 통해 converter를 다음과 같이 사용 가능
converter1_cfg = dict(type='Converter1', a=a_value, b=b_value)
converter2_cfg = dict(type='converter2', a=a_value, b=b_value)
converter1 = CONVERTERS.build(converter1_cfg)
result = CONVERTERS.build(converter2_cfg)
from mmcv.utils import Registry
def build_converters(cfg, registry, *args, **kwargs):
cfg_ = cfg.copy()
converter_type = cfg_.pop('type')
if converter_type not in registry:
raise KeyError(f'Unrecognized converter type {converter_type}')
else:
converter_cls = registry.get(converter_type)
converter = converter_cls(*args, **kwargs, **cfg_)
return converter
CONVERTERS = Registry('converter', build_func=build_converter)
child registry에서 빌드
from mmcv.utils import Registry
from mmcv.cnn import MODELS as MMCV_MODELS
MODELS = Registry('model', parent=MMCV_MODELS)
@MODELS.register_module()
class NetA(nn.Module):
def forawrd(self, x):
return x
from mmcv.utils import Registry
from mmcv.cnn import MODELS as MMCV_MODELS
MODELS = Registry('model', parent=MMCV_MODELS)
@MODELS.register_module()
class NetB(nn.Module):
def forward(self, x):
return x+1
from mmdet.models import MODELS
net_a = MODELS.build(cfg=dict(type='NetA'))
net_b = MODELS.build(cfg=dict(type='mmcls.NetB'))
# 아래도 동일한 코드
net_a = MODELS.build(cfg=dict(type='mmdet.NetA'))
net_b = MODELS.build(cfg=dict(type='NetB'))
상위 레지스트리에서 빌드
from mmcv.cnn import MODELS as MMCV_MODELS
net_a = MMCV_MODELS.build(cfg=dict(type='mmdet.NetA'))
net_b = MMCV_MODELS.build(cfg=dict(type='mmcls.NetB'))
@
in python- 클래스 및 함수 decorator
- decorator: 함수, 메소드, 클래스 수정에 사용되는 python object
- original object를 입력받아 modified object를 반환
- java에서 영감 받음
- 함수 속에 함수를 입력하는 꼴
- 예시 1
```python
@viking_chorus
def menu_item():
print("spam")
# 위 함수는 코드와 동일
def menu_item():
print("spam")
menu_item = viking_chorus(menu_item)
# viking_chorus는 아래와 같이 정의되어 있다고 가정
def viking_chorus(myfunc):
def inner_func(*args, **kwargs):
for i in range(8):
myfunc(*args, @@kwargs)
return inner_func
```
- 예시 2
```python
@invincible
@favourite_colour("Blue")
def black_knight():
pass
# 아래와 동일
def favourite_colour(colour):
def decorator(func):
def wrapper():
print(colour)
func()
return wrapper
return decorator
def black_knight():
pass
blacknight = invincible(favourite_colour("Blue")(black_knight))
# 아래와도 동일
blue_decorator = favourite_colour("Blue")
decorated_by_blue = blue_decorator(black_knight)
black_knight = invincible(decorated_by_blue)
```
- 폴더로 패키지를 작성할 때 참조하지 못하는 문제를 해결하기 위해 `__init__.py` 사용
- 해당 디렉토리가 패키지의 일부임을 알려주는 역할 수행
- 해당 디렉토리의 모듈을 `*`을 활용해 import할 때 `__all__`이라는 변수 설정하고 import 가능한 모듈 정의
```python
# __init__.py
__all__ = ['hi', 'bye', 'hello']
```
참고
https://better-tomorrow.tistory.com/entry/MMCV-의-Registry
https://mmcv.readthedocs.io/en/latest/understand_mmcv/registry.html
https://wiki.python.org/moin/PythonDecorators#head-f22ccf491766760d15b371b8ed27c8a81b7cde2f
https://nesoy.github.io/articles/2018-07/Python-init-all