timm documentation
Início rápido
Início rápido
Este guia rápido é destinado a desenvolvedores que estão prontos para mergulhar no código e ver um exemplo de como integrar o timm ao seu fluxo de trabalho de treinamento de modelos.
Primeiro, você precisará instalar o timm. Para mais informações sobre a instalação, consulte Installation.
pip install timm
Carregar um Modelo Pré-treinado
Modelos pré-treinados podem ser carregados usando create_model().
Aqui, carregamos o modelo pré-treinado mobilenetv3_large_100.
>>> import timm
>>> m = timm.create_model('mobilenetv3_large_100', pretrained=True)
>>> m.eval()Note: The returned PyTorch model is set to train mode by default, so you must call .eval() on it if you plan to use it for inference.
Listar modelos com pesos pré-treinados
Para listar os modelos empacotados com timm, você pode usar list_models(). Se você especificar pretrained=True, esta função retornará apenas os nomes de modelos que possuem pesos pré-treinados associados disponíveis.
>>> import timm
>>> from pprint import pprint
>>> model_names = timm.list_models(pretrained=True)
>>> pprint(model_names)
[
'adv_inception_v3',
'cspdarknet53',
'cspresnext50',
'densenet121',
'densenet161',
'densenet169',
'densenet201',
'densenetblur121d',
'dla34',
'dla46_c',
]Você também pode listar modelos com um padrão específico em seus nomes.
>>> import timm
>>> from pprint import pprint
>>> model_names = timm.list_models('*resne*t*')
>>> pprint(model_names)
[
'cspresnet50',
'cspresnet50d',
'cspresnet50w',
'cspresnext50',
...
]Ajuste fino de um modelo pré-treinado
Você pode fazer o ajuste fino de qualquer um dos modelos pré-treinados apenas alterando o classificador (a última camada).
>>> model = timm.create_model('mobilenetv3_large_100', pretrained=True, num_classes=NUM_FINETUNE_CLASSES)Para fazer o ajuste fino em seu próprio conjunto de dados, você precisa escrever um loop de treinamento do PyTorch ou adaptar o script de treinamento do timm para usar seu conjunto de dados.
Para diferentes canais de entrada, defina in_chans para a contagem de canais alvo do modelo;
a configuração pré-treinada deve descrever os pesos de origem. Consulte Adapt and Export Models para conversão de canais e salvamento
de modelos adaptados com sua configuração atual.
Use um Modelo Pré-treinado para Extração de Recursos
Sem modificar a rede, é possível chamar model.forward_features(input) em qualquer modelo em vez do habitual model(input). Isso ignorará o classificador da cabeça e o agrupamento global para as redes.
Para um guia mais detalhado sobre o uso de timm para extração de recursos, consulte Extração de Recursos.
>>> import timm
>>> import torch
>>> x = torch.randn(1, 3, 224, 224)
>>> model = timm.create_model('mobilenetv3_large_100', pretrained=True)
>>> features = model.forward_features(x)
>>> print(features.shape)
torch.Size([1, 960, 7, 7])Aumento de Imagem
Para transformar imagens em entradas válidas para um modelo, você pode usar timm.data.create_transform(), fornecendo o input_size desejado que o modelo espera.
Isso retornará uma transformação genérica que usa padrões razoáveis.
>>> timm.data.create_transform((3, 224, 224))
Compose(
Resize(size=256, interpolation=bilinear, max_size=None, antialias=True)
CenterCrop(size=(224, 224))
MaybeToTensor()
Normalize(mean=tensor([0.4850, 0.4560, 0.4060]), std=tensor([0.2290, 0.2240, 0.2250]))
)Os modelos pré-treinados possuem transformações específicas que foram aplicadas às imagens fornecidas a eles durante o treinamento. Se você usar a transformação errada na sua imagem, o modelo não entenderá o que está vendo!
Para descobrir quais transformações foram usadas para um determinado modelo pré-treinado, podemos começar analisando seu pretrained_cfg
>>> model.pretrained_cfg
{'url': 'https://github.com/rwightman/pytorch-image-models/releases/download/v0.1-weights/mobilenetv3_large_100_ra-f55367f5.pth',
'hf_hub_id': 'timm/mobilenetv3_large_100.ra_in1k',
'architecture': 'mobilenetv3_large_100',
'tag': 'ra_in1k',
'custom_load': False,
'input_size': (3, 224, 224),
'fixed_input_size': False,
'interpolation': 'bicubic',
'crop_pct': 0.875,
'crop_mode': 'center',
'mean': (0.485, 0.456, 0.406),
'std': (0.229, 0.224, 0.225),
'num_classes': 1000,
'pool_size': (7, 7),
'first_conv': 'conv_stem',
'classifier': 'classifier',
'license': 'apache-2.0'}Em seguida, podemos resolver apenas a configuração relacionada aos dados usando timm.data.resolve_model_data_config().
>>> timm.data.resolve_model_data_config(model)
{'input_size': (3, 224, 224),
'interpolation': 'bicubic',
'mean': (0.485, 0.456, 0.406),
'std': (0.229, 0.224, 0.225),
'crop_pct': 0.875,
'crop_mode': 'center'}Podemos passar essa configuração de dados para timm.data.create_transform() para inicializar a transformação associada ao modelo.
>>> data_cfg = timm.data.resolve_model_data_config(model)
>>> transform = timm.data.create_transform(**data_cfg)
>>> transform
Compose(
Resize(size=256, interpolation=bicubic, max_size=None, antialias=True)
CenterCrop(size=(224, 224))
MaybeToTensor()
Normalize(mean=tensor([0.4850, 0.4560, 0.4060]), std=tensor([0.2290, 0.2240, 0.2250]))
)Note: Here, the pretrained model's config happens to be the same as the generic config we made earlier. This is not always the case. So, it's safer to use the data config to create the transform as we did here instead of using the generic transform.
Usando Modelos Pré-treinados para Inferência
Aqui, vamos reunir as seções acima e usar um modelo pré-treinado para inferência.
Primeiro, precisaremos de uma imagem para realizar a inferência. Aqui, carregamos uma foto de uma folha da web:
>>> import requests
>>> from PIL import Image
>>> from io import BytesIO
>>> url = 'https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/timm/cat.jpg'
>>> image = Image.open(requests.get(url, stream=True).raw)
>>> imageAqui está a imagem que carregamos:
Agora, criaremos novamente nosso modelo e transforms. Dessa vez, nos certificamos de colocar o modelo em modo de avaliação.
>>> model = timm.create_model('mobilenetv3_large_100', pretrained=True).eval()
>>> transform = timm.data.create_transform(
**timm.data.resolve_model_data_config(model)
)Podemos preparar esta imagem para o modelo passando-a para o transform.
>>> image_tensor = transform(image)
>>> image_tensor.shape
torch.Size([3, 224, 224])Agora podemos passar essa imagem ao modelo para obter as previsões. Usamos unsqueeze(0) neste caso, pois o modelo espera uma dimensão de lote.
>>> output = model(image_tensor.unsqueeze(0))
>>> output.shape
torch.Size([1, 1000])Para obter as probabilidades previstas, aplicamos softmax à saída. Isso nos deixa com um tensor de forma (num_classes,).
>>> probabilities = torch.nn.functional.softmax(output[0], dim=0)
>>> probabilities.shape
torch.Size([1000])Agora, encontraremos os 5 principais índices e valores de classes previstos usando torch.topk.
>>> values, indices = torch.topk(probabilities, 5)
>>> indices
tensor([281, 282, 285, 673, 670])Se verificarmos os rótulos do imagenet para o índice mais alto, podemos ver o que o modelo previu…
>>> IMAGENET_1k_URL = 'https://storage.googleapis.com/bit_models/ilsvrc2012_wordnet_lemmas.txt'
>>> IMAGENET_1k_LABELS = requests.get(IMAGENET_1k_URL).text.strip().split('\n')
>>> [{'label': IMAGENET_1k_LABELS[idx], 'value': val.item()} for val, idx in zip(values, indices)]
[{'label': 'tabby, tabby_cat', 'value': 0.5101025700569153},
{'label': 'tiger_cat', 'value': 0.22490699589252472},
{'label': 'Egyptian_cat', 'value': 0.1835290789604187},
{'label': 'mouse, computer_mouse', 'value': 0.006752475164830685},
{'label': 'motor_scooter, scooter', 'value': 0.004942195490002632}]