Mecanismo de registro MMCV

Índice

introdução

1. Introdução

2. Componentes principais do MMCV - Configuração e registro 

2.1 Classe de configuração

2.2 Gerar classe Config a partir do arquivo de configuração

2.3 Análise de variáveis ​​predefinidas

2.4 Herança de arquivos de configuração

2.5 Registro

2.6 Exemplos 

2.7 Função de compilação personalizada (função de compilação)

2.8 Registro Hierárquico


introdução

      Aprendizado MMCV Estou aprendendo a biblioteca básica do mmcv recentemente, então escreva um blog para gravá-lo. Um é como uma nota de estudo para referência futura, e o outro é para compartilhar e trocar minha experiência de aprendizado com você. mmcv é uma biblioteca básica de visão computacional de código aberto da OpenMMLab, que suporta muitos armazéns excelentes de código aberto do OpenMMLab (como MMDetection, MMSegmentation, MMSelfSup, etc.).

1. Introdução

  Como uma biblioteca básica, o mmcv fornece principalmente os seguintes módulos funcionais:

  • API io unificada e escalável
  • Suporta operadores de processamento de imagem/vídeo muito ricos
  • Visualização de arquivo de anotação de imagem/vídeo
  • Classes de ferramentas comuns, como cronômetro e barra de progresso, etc.
  • O mecanismo de gancho exigido pela estrutura superior e a corrediça que pode ser usada diretamente
  • Esquema cfg altamente flexível e mecanismo de registro
  • cuda op eficiente e de alta qualidade

2. Componentes principais do MMCV - Configuração e registro 

2.1 Classe de configuração

O site oficial explica:

  Config A classe é usada para manipular arquivos de configuração e configuração. Ele suporta o carregamento de configurações de vários formatos de arquivo, incluindo  pythonjson  e  yaml . Ele fornece  APIs do tipo dict  para  obter  e  definir  valores.

2.2 Gerar classe Config a partir do arquivo de configuração

Suponha que tenhamos um arquivo config.py definido da seguinte forma:

a = 1
b = dict(b1=[0, 1, 2], b2=None)
c = (1, 2)
d = 'string'

Lemos este arquivo python diretamente e o imprimimos:

config = Config.fromfile("config.py")
print(config)
print(type(config))
# Output
# Config (path: config.py): {'a': 1, 'b': {'b1': [0, 1, 2], 'b2': None}, 'c': (1, 2), 'd': 'string'}
# <class 'mmcv.utils.config.Config'>

2.3 Análise de variáveis ​​predefinidas

      Além de definir diretamente as variáveis ​​de configuração, o Config também suporta a análise de variáveis ​​predefinidas, cujo formato é o seguinte { { var } } \{\{ var \}\} { {var}} . Atualmente, o Config suporta a análise de quatro variáveis ​​predefinidas, que podem facilmente obter as várias partes do caminho absoluto do arquivo de configuração aberto:

  • { { fileDirname } } \{\{ \mathrm{fileDirname} \}\} { {fileDirname}} - O diretório onde o arquivo de configuração atualmente aberto está localizado.
  • { { fileBasename } } \{\{ \mathrm{fileBasename} \}\} { {fileBasename}} - O nome do arquivo de configuração atualmente aberto, com sufixo.
  • { { file Basename No Extension } } \{\{ \mathrm{fileBasenameNoExtension} \}\} {{ fileBasenameNoExtension}} - O nome do arquivo de configuração atualmente aberto sem extensão.
  • { { file Extname } } \{\{ \mathrm{fileExtname } \}\} { {fileExtname}} - O sufixo do arquivo de configuração aberto no momento.

 No entanto, de fato, a partir da impressão anterior do objeto de exemplo Config, podemos ver que o mmcv atual fornece o atributo path do objeto para o exemplo Config , e podemos usar diretamente o atributo path para obter o caminho absoluto da configuração aberta.

2.4 Herança de arquivos de configuração

 Considerando a capacidade de reutilização dos arquivos de configuração, o mmcv fornece uma série de operações de herança de arquivo de configuração e permite que os usuários selecionem com flexibilidade as partes herdadas.

 Para fazer um arquivo de configuração herdar outro arquivo de configuração, você só precisa especificar a variável _base_ no arquivo de subconfiguração como o  caminho relativo do arquivo de configuração pai (relativo a config_b)  . Por exemplo, temos um arquivo de configuração config_a.py da seguinte forma:

# config_a.py
a = 1
b = dict(b1=[0, 1, 2], b2=None)

 Para herdar config_a, podemos especificar a variável _base_ no arquivo config_b:

# config_b.py
_base_ = './config_a.py'
b = dict(b2=1)
c = (1, 2)
config = Config.fromfile("./config_b.py")
print(config)
# Output
# Config (path: ./config_b.py): {'a': 1, 'b': {'b1': [0, 1, 2], 'b2': 1}, 'c': (1, 2)}

        Como pode ser visto na saída acima, quando há um conflito de chave entre o arquivo de subconfiguração e o arquivo de configuração pai (b.b2), o arquivo de subconfiguração será o principal. Este comportamento é muito semelhante ao processo de herança em orientação a objetos, por isso também é chamado de herança de arquivos de configuração em vez de síntese de arquivos de configuração. PS:  Config suporta herança de vários arquivos, você só precisa definir _base_ como uma lista de ['config1.py', 'config2.py', ...], mas a mesma configuração base não pode existir key , caso contrário, Config não existirá saber qual base usar.

 Vejamos uma sintaxe mais útil em Herança de configuração , que nos permite usar diretamente as variáveis ​​definidas no arquivo de configuração pai no arquivo de configuração filho. Por exemplo, queremos usar variáveis ​​no arquivo de configuração pai config_a.py no arquivo de configuração filho config_c.py:

# config_c.py
_base_ = ['./config_a.py']
item = dict(a = {
   
   { _base_.a}}, b = {
   
   {_base_.b.b1}})
config = Config.fromfile("./config_c.py")
print(config)
# Output:
# Config (path: ./config_c.py): {'a': 1, 'b': {'b1': [0, 1, 2], 'b2': None}, 'item': {'a': 1, 'b': [0, 1, 2]}}

2.5 Registro

Explicação oficial:

O MMCV implementa  registry para gerenciar diferentes módulos que compartilham  funcionalidades semelhantes , por exemplo, backbones, cabeça e pescoço, em detectores.

No MMCV, o registro pode ser considerado como um mapeamento entre strings e classes.Essas classes no mesmo registro têm funções semelhantes, que são um pouco semelhantes ao polimorfismo orientado a objetos. Com o registro, os usuários podem chamar e instanciar essas classes usando strings. O processo de uso do Registry é dividido principalmente nas três etapas a seguir:

  • Crie um construtor (opcional)
  • criar registro
  • O registro é usado para gerenciar esses módulos

2.6 Exemplos 

      Vamos dar um exemplo simples para ver como usar o Registry para gerenciar os módulos de um pacote. Supondo que tenhamos um pacote conversor, existem classes conversoras com diferentes funções que implementamos.
 Primeiro, vamos agora criar o arquivo converter/builder.py para criar o registro do conversor:

# converter/builder.py
from mmcv.utils import Registry
CONVERTERS = Registry("converter")

 Em seguida, use CONVERTERS para registrar a classe Converter1 que queremos gerenciar:

# converter/conerter1.py
from .builder import CONVERTERS

# 这里需要说明一下, 由于python的装饰器机制是在类定义被加载时触发,所以一般需要在converter/__init__.py里面去import这个类。
@CONVERTERS.register_module()
class Converter1(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

Supondo que exista um arquivo principal externo, se a classe Converter1 for usada, nosso método de escrita pode ficar mais elegante em vez de importar para todos os lugares:

# main.py
from converter import CONVERTERS

if __name__ == "__main__":
    converter_cfg = dict(type='Converter1', a=1, b=2)
    converter = CONVERTERS.build(converter_cfg)  # 这里的build是mmcv帮我们默认实现了
    print(converter)

2.7 Função de compilação personalizada (função de compilação)

 O exemplo introdutório acima apenas explica como usar o Registry para instanciar a classe gerenciada.Por padrão, basta usar a função build implementada pelo mmcv para ler o arquivo de configuração e instanciá-lo. Este tipo de método de gerenciamento realiza o processo do arquivo de configuração para a classe de instanciação diretamente, de forma que se você quiser modificar alguns parâmetros no futuro, você só precisa modificar o arquivo de configuração, o que é muito conveniente.
 Se precisarmos personalizar o construtor, podemos personalizá-lo da seguinte maneira:

# converter/builder.py
from mmcv.utils import Registry


def build_converter(cfg, registry, *args, **kwargs):
    # print(args)
    # print(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)

2.8 Registro Hierárquico

 O registro de todos os modelos de base de código downstream do MMCV é MODELSum subregistro do mmcv. Geralmente, há duas maneiras de instanciar o modelo do registro irmão e do registro pai:

(1) Instancie do registro irmão:

# 假设我们有一个classfication的代码库叫mmcls.py
from mmcv.utils import Registry
from mmcv.cnn import MODELS as MMCV_MODELS
from torch import nn

# Create a register
MODELS = Registry("model", parent=MMCV_MODELS)

# classification net
@MODELS.register_module()
class ClsNet(nn.Module):

    def __init__(self) -> None:
        super().__init__()
# detection的代码库叫mmdet.py
from mmcv.utils import Registry
from mmcv.cnn import MODELS as MMCV_MODELS
import mmcls
from torch import nn

# Create a register
MODELS = Registry("model", parent=MMCV_MODELS)

# Detection net
@MODELS.register_module()
class DetNet(nn.Module):

    def __init__(self) -> None:
        super().__init__()

# 这里我们使用mmdet的registry去实例化cls_net和det_net, 所以det_net不加模块名而cls_net要加
if __name__ == "__main__":
    det_net = MODELS.build({"type": "DetNet"})
    cls_net = MODELS.build({"type": "mmcls.ClsNet"})
    print(det_net)
    print(cls_net)

(2) Instancie do registro da classe pai:

# 外部父类的文件hierarchy_reg.py实例化
from mmcv.cnn import MODELS as MMCV_MODELS
import mmcls
import mmdet


if __name__ == "__main__":
    det_net = MMCV_MODELS.build({"type": "mmdet.DetNet"})
    cls_net = MMCV_MODELS.build({"type": "mmcls.ClsNet"})
    print(det_net)
    print(cls_net)

おすすめ

転載: blog.csdn.net/m0_53675977/article/details/130783257