timm documentation

Démarrage rapide

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v1.0.30).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Démarrage rapide

Ce guide de démarrage rapide s’adresse aux développeurs prêts à plonger dans le code et à découvrir un exemple d’intégration de timm dans leur flux de travail d’entraînement de modèle.

Tout d'abord, vous devrez installer timm. Pour plus d'informations sur l'installation, consultez Installation.

pip install timm

Charger un modèle pré-entraîné

Les modèles pré-entraînés peuvent être chargés à l'aide de create_model().

Ici, nous chargeons le modèle pré-entraîné 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.

Lister les modèles avec des poids pré-entraînés

Pour lister les modèles fournis avec timm, vous pouvez utiliser list_models(). Si vous spécifiez pretrained=True, cette fonction ne renverra que les noms de modèles pour lesquels des poids pré-entraînés sont disponibles.

>>> 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',
]

Vous pouvez également lister les modèles dont le nom contient un motif spécifique.

>>> import timm
>>> from pprint import pprint
>>> model_names = timm.list_models('*resne*t*')
>>> pprint(model_names)
[
    'cspresnet50',
    'cspresnet50d',
    'cspresnet50w',
    'cspresnext50',
    ...
]

Ajuster finement un modèle pré-entraîné

Vous pouvez affiner n'importe quel modèle pré-entraîné en modifiant simplement le classifieur (la dernière couche).

>>> model = timm.create_model('mobilenetv3_large_100', pretrained=True, num_classes=NUM_FINETUNE_CLASSES)

Pour effectuer un fine-tuning sur votre propre jeu de données, vous devez écrire une boucle d'entraînement PyTorch ou adapter le script d'entraînement de timm pour utiliser votre jeu de données.

Pour des canaux d’entrée différents, définissez in_chans sur le nombre de canaux cible du modèle ; la configuration préentraînée doit décrire les poids source. Consultez Adapt and Export Models pour la conversion des canaux et l’enregistrement des modèles adaptés avec leur configuration actuelle.

Utiliser un modèle pré-entraîné pour l'extraction de caractéristiques

Sans modifier le réseau, on peut appeler model.forward_features(input) sur n’importe quel modèle à la place de l’appel habituel model(input). Cela contourne le classifieur de tête et le regroupement global pour les réseaux.

Pour un guide plus approfondi sur l'utilisation de timm pour l'extraction de caractéristiques, consultez Extraction de caractéristiques.

>>> 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])

Augmentation d'images

Pour transformer des images en entrées valides pour un modèle, vous pouvez utiliser timm.data.create_transform() en fournissant la input_size attendue par le modèle.

Cela renverra une transformation générique qui utilise des valeurs par défaut raisonnables.

>>> 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]))
)

Les modèles pré-entraînés ont des transformations spécifiques qui ont été appliquées aux images qui leur étaient fournies pendant l’entraînement. Si vous utilisez la mauvaise transformation sur votre image, le modèle ne comprendra pas ce qu’il voit !

Pour déterminer quelles transformations ont été utilisées pour un modèle préentraîné donné, nous pouvons commencer par examiner son 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'}

Nous pouvons ensuite résoudre uniquement la configuration liée aux données en utilisant 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'}

Nous pouvons passer cette configuration de données à timm.data.create_transform() pour initialiser la transformation associée au modèle.

>>> 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.

Utilisation de modèles pré-entraînés pour l'inférence

Ici, nous allons assembler les sections ci-dessus et utiliser un modèle pré-entraîné pour l'inférence.

Nous aurons d'abord besoin d'une image sur laquelle effectuer l'inférence. Ici, nous chargeons une photo d'une feuille depuis le 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)
>>> image

Voici l’image que nous avons chargée :

An Image from a link

Maintenant, nous recréons notre modèle et nos transformations. Cette fois, nous veillons à placer notre modèle en mode évaluation.

>>> model = timm.create_model('mobilenetv3_large_100', pretrained=True).eval()
>>> transform = timm.data.create_transform(
    **timm.data.resolve_model_data_config(model)
)

Nous pouvons préparer cette image pour le modèle en la passant à la transformation.

>>> image_tensor = transform(image)
>>> image_tensor.shape
torch.Size([3, 224, 224])

Nous pouvons maintenant passer cette image au modèle pour obtenir les prédictions. Nous utilisons unsqueeze(0) dans ce cas, car le modèle s’attend à une dimension de lot.

>>> output = model(image_tensor.unsqueeze(0))
>>> output.shape
torch.Size([1, 1000])

Pour obtenir les probabilités prédites, nous appliquons softmax à la sortie. Il nous reste alors un tenseur de forme (num_classes,).

>>> probabilities = torch.nn.functional.softmax(output[0], dim=0)
>>> probabilities.shape
torch.Size([1000])

Nous allons maintenant trouver les 5 indices et valeurs de classes prédites les plus élevés à l'aide de torch.topk.

>>> values, indices = torch.topk(probabilities, 5)
>>> indices
tensor([281, 282, 285, 673, 670])

Si nous vérifions les étiquettes imagenet pour l'indice le plus élevé, nous pouvons voir ce que le modèle a prédit…

>>> 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}]
Update on GitHub