OML est un cadre basé sur Pytorch pour former et valider les modèles produisant des intégres de haute qualité.
ㅤㅤ
Il y a un certain nombre de personnes des universités d'Oxford et HSE qui ont utilisé OML dans leurs thèses. [1] [2] [3]
La mise à jour se concentre sur plusieurs composants:
Nous avons ajouté la prise en charge des textes "officiels" et les exemples Python correspondants. (Remarque, la prise en charge des textes dans les pipelines n'est pas encore prise en charge.)
Nous avons introduit la classe RetrievalResults ( RR ) - un conteneur pour stocker les articles de la galerie récupérés pour des requêtes données. RR fournit un moyen unifié de visualiser les prédictions et de calculer les mesures (si les vérités au sol sont connues). Il simplifie également le post-traitement, où un objet RR est pris en entrée et un autre RR_upd est produit en sortie. Le fait d'avoir ces deux objets permet des résultats de récupération de comparaison visuellement ou par des mesures. De plus, vous pouvez facilement créer une chaîne de ces post-processeurs.
RR est optimisé par la mémoire en raison de l'utilisation de lots: en d'autres termes, il ne stockait pas la matrice complète des distances de galerie de requête. (Cela ne rend pas la recherche approximative cependant). Nous avons fait Model et Dataset les seules classes responsables du traitement de la logique spécifique à la modalité. Model est responsable de l'interprétation de ses dimensions d'entrée: par exemple, BxCxHxW pour les images ou BxLxD pour des séquences comme des textes. Dataset est responsable de la préparation d'un élément: il peut utiliser Transforms pour les images ou Tokenizer pour les textes. Fonctions Computing Des métriques comme calc_retrieval_metrics_rr , RetrievalResults , PairwiseReranker et d'autres classes et fonctions sont unifiées pour fonctionner avec n'importe quelle modalité.
IVisualizableDataset ayant la méthode .visaulize() qui montre un seul élément. S'il est mis en œuvre, RetrievalResults est capable de montrer la disposition des résultats récupérés. La façon la plus simple de rattraper les modifications est de relire les exemples!
La manière recommandée de validation est d'utiliser RetrievalResults et des fonctions comme calc_retrieval_metrics_rr , calc_fnmr_at_fmr_rr , et autres. La classe EmbeddingMetrics est conservée pour une utilisation avec la foudre Pytorch et les pipelines intérieurs. Remarque, les signatures des méthodes EmbeddingMetrics ont été légèrement modifiées, voir des exemples de foudre pour cela.
Étant donné que la logique spécifique à la modalité se limite à Dataset , il ne publie plus PATHS_KEY , X1_KEY , X2_KEY , Y1_KEY et Y2_KEY . Les touches qui ne sont pas spécifiques à la modalité comme LABELS_KEY , IS_GALLERY , IS_QUERY_KEY , CATEGORIES_KEY sont toujours utilisées.
inference_on_images est désormais inference et fonctionne avec n'importe quelle modalité.
Interfaces légèrement modifiées des Datasets. Par exemple, nous avons IQueryGalleryDataset et IQueryGalleryLabeledDataset interfaces. Le premier doit être utilisé pour l'inférence, le second pour la validation. Ajout de l'interface IVisualizableDataset .
Supprimé certains internes comme IMetricDDP , EmbeddingMetricsDDP , calc_distance_matrix , calc_gt_mask , calc_mask_to_ignore , apply_mask_to_ignore . Ces changements ne devraient pas vous affecter. Également supprimé le code lié à un pipeline avec des triplets précomposés.
Extraction des fonctionnalités: pas de modifications, sauf pour l'ajout d'un argument facultatif - mode_for_checkpointing = (min | max) . Il peut être utile de basculer entre le bas, le meilleur et le plus grand, le meilleur type de métriques.
Pipeline Pairwise-PostProcessing: légèrement modifié le nom et les arguments du sous-configuration postprocessor - pairwise_images est désormais pairwise_reranker et n'a pas besoin de transformations.
Vous pensez peut-être "si j'ai besoin d'incorporation d'image, je peux simplement entraîner un classificateur de vanille et prendre son avant-dernière couche" . Eh bien, cela a du sens en tant que point de départ. Mais il y a plusieurs inconvénients possibles:
Si vous souhaitez utiliser des intégres pour effectuer la recherche, vous devez calculer une certaine distance entre eux (par exemple, Cosine ou L2). Habituellement, vous n'optimisez pas directement ces distances lors de la formation dans la configuration de la classification. Ainsi, vous ne pouvez qu'espérer que les intérêts finaux auront les propriétés souhaitées.
Le deuxième problème est le processus de validation . Dans la configuration de recherche, vous vous souciez généralement de la façon dont vos sorties Top-N sont liées à la requête. La façon naturelle d'évaluer le modèle consiste à simuler les demandes de recherche à l'ensemble de référence et à appliquer l'une des mesures de récupération. Il n'y a donc aucune garantie que la précision de la classification sera en corrélation avec ces mesures.
Enfin, vous voudrez peut-être mettre en œuvre vous-même un pipeline d'apprentissage métrique. Il y a beaucoup de travail : pour utiliser la perte de triplet, vous devez former des lots d'une manière spécifique, mettre en œuvre différents types d'exploitation d'exploitation de triplés, de distances de suivi, etc. Vous pouvez également visualiser vos demandes de recherche en mettant en évidence les bons et les mauvais résultats de recherche. Au lieu de le faire par vous-même, vous pouvez simplement utiliser OML à vos fins.
PML est la bibliothèque populaire de l'apprentissage métrique, et il comprend une riche collection de pertes, de mineurs, de distances et de réducteurs; C'est pourquoi nous fournissons des exemples simples de les utiliser avec OML. Initialement, nous avons essayé d'utiliser PML, mais en fin de compte, nous avons proposé notre bibliothèque, qui est orientée vers le pipeline / recettes. C'est ainsi que OML diffère de PML:
OML a des pipelines qui permet des modèles de formation en préparant une configuration et vos données dans le format requis (c'est comme convertir les données en format CoCo pour former un détecteur à partir de MMDETECTION).
OML se concentre sur les pipelines de bout en bout et les cas d'utilisation pratiques. Il dispose d'exemples basés sur la configuration sur des repères populaires proches de la vraie vie (comme des photos de produits de milliers d'iD). Nous avons trouvé de bonnes combinaisons d'hyperparamètres sur ces ensembles de données, des modèles formés et publiés et leurs configurations. Ainsi, il rend OML plus orienté vers les recettes que PML, et son auteur confirme ce disant que sa bibliothèque est un ensemble d'outils plutôt que les recettes, en outre, les exemples de PML sont principalement pour les ensembles de données CIFAR et MNIST.
OML a le zoo de modèles pré-entraînés qui peuvent être facilement accessibles à partir du code de la même manière que dans torchvision (lorsque vous tapez resnet50(pretrained=True) ).
OML est intégré à Pytorch Lightning, nous pouvons donc utiliser la puissance de son entraîneur. Cela est particulièrement utile lorsque nous travaillons avec DDP, vous comparez donc notre exemple DDP et celui de PMLS. Soit dit en passant, PML a également des formateurs, mais il n'est pas largement utilisé dans les exemples et les fonctions train / test personnalisées sont utilisées à la place.
Nous pensons que le fait d'avoir des pipelines, des exemples laconiques et du zoo de modèles pré-entraînés mettent le seuil d'entrée à une valeur très faible.
Le problème d'apprentissage métrique (également connu sous le nom de problème de classification extrême ) signifie une situation dans laquelle nous avons des milliers d'ID de certaines entités, mais seulement quelques échantillons pour chaque entité. Souvent, nous supposons que pendant le stade (ou la production) de test, nous traiterons des entités invisibles, ce qui rend impossible d'appliquer directement le pipeline de classification de la vanille. Dans de nombreux cas, des intégres obtenus sont utilisés pour effectuer des procédures de recherche ou de correspondance dessus.
Voici quelques exemples de ces tâches de la sphère de vision par ordinateur:
embedding - Sortie du modèle (également connu sous le nom de features vector ou descriptor ).query - Un échantillon qui est utilisé comme demande dans la procédure de récupération.gallery set - L'ensemble des entités pour rechercher des éléments similaires à query (également connue sous le nom reference ou index ).Sampler - Un argument pour DataLoader qui est utilisé pour former des lotsMiner - L'objet pour former des paires ou des triplés après la formation du lot par Sampler . Il n'est pas nécessaire de former les combinaisons d'échantillons uniquement à l'intérieur du lot actuel, ainsi, la banque de mémoire peut faire partie de Miner .Samples / Labels / Instances - Par exemple, considérons le jeu de données DeepFashion. Il comprend des milliers d'ID d'élément de mode (nous les nommons labels ) et plusieurs photos pour chaque ID d'article (nous nommons la photo individuelle en instance ou sample ). Tous les ID d'objets de mode ont leurs groupes comme des "jupes", des "vestes", des "shorts" et ainsi de suite (nous les nommons categories ). Remarque, nous évitons d'utiliser la class de terme pour éviter les malentendus.training epoch - Les échantillonneurs par lots que nous utilisons pour les pertes basées sur la combinaison ont généralement une longueur égale à [number of labels in training dataset] / [numbers of labels in one batch] . Cela signifie que nous n'observons pas tous les échantillons de formation disponibles en une époque (par opposition à la classification de la vanille), nous observons plutôt toutes les étiquettes disponibles.Il peut être comparable avec les méthodes SOTA (2022 ans), par exemple, Hyp-Vit. (Peu de mots sur cette approche: c'est une architecture Vit formée avec une perte contrastée, mais les intégres ont été projetés dans un espace hyperbolique. Comme le prétendent les auteurs, un tel espace est capable de décrire la structure imbriquée des données réelles.
Nous avons formé la même architecture avec la perte de triplet, fixant le reste des paramètres: formation et transformations de test, taille de l'image et optimiseur. Voir configs dans les modèles zoo. L'astuce était dans l'heuristique dans notre mineur et notre échantillonneur:
Catégorie Balance L'échantillonneur forme les lots limitant le nombre de catégories C dedans. Par exemple, lorsque C = 1, il ne met que des vestes dans un lot et uniquement un jean dans un autre (juste un exemple). Cela rend automatiquement les paires négatives plus difficiles: il est plus significatif qu'un modèle se rend compte pourquoi deux vestes sont différentes que de comprendre la même chose à propos d'une veste et d'un t-shirt.
Le mineur des triplets durs rend la tâche encore plus difficile à garder uniquement les triplets les plus durs (avec des distances maximales positives et négatives minimales).
Voici les scores CMC @ 1 pour 2 repères populaires. Ensemble de données SOP: Hyp-Vit - 85,9, le nôtre - 86.6. Ensemble de données Deepfashion: Hyp-Vit - 92.5, le nôtre - 92.1. Ainsi, en utilisant des heuristiques simples et en évitant les mathématiques lourdes, nous sommes en mesure de performer au niveau SOTA.
Des recherches récentes en SSL ont vraiment obtenu d'excellents résultats. Le problème est que ces approches ont nécessité une énorme quantité de calcul pour former le modèle. Mais dans notre cadre, nous considérons le cas le plus courant lorsque l'utilisateur moyen n'a pas plus de quelques GPU.
Dans le même temps, il serait imprudent d'ignorer le succès dans cette sphère, nous l'exploitons donc de deux manières:
Non, tu ne le fais pas. OML est un framework-agnostique. Malgré que nous utilisons Pytorch Lightning comme coureur de boucle pour les expériences, nous gardons également la possibilité d'exécuter tout sur Pytorch pur. Ainsi, seule la petite partie de l'OML est spécifique à la foudre et nous gardons cette logique séparément de l'autre code (voir oml.lightning ). Même lorsque vous utilisez Lightning, vous n'avez pas besoin de le savoir, car nous fournissons des pipelines prêts à l'emploi.
La possibilité d'utiliser le pytorche pur et la structure modulaire du code laissent une pièce pour utiliser OML avec votre cadre préféré après la mise en œuvre des emballages nécessaires.
Oui. Pour exécuter l'expérience avec des pipelines, vous n'avez qu'à écrire un convertisseur vers notre format (cela signifie préparer le tableau .csv avec quelques colonnes prédéfinies). C'est ça!
Nous avons probablement déjà un modèle pré-formé approprié pour votre domaine dans notre zoo de modèles . Dans ce cas, vous n'avez même pas besoin de le former.
Actuellement, nous ne prenons pas directement des modèles d'exportation vers ONNX. Cependant, vous pouvez utiliser les capacités Pytorch intégrées pour y parvenir. Pour plus d'informations, veuillez vous référer à ce problème.
DOCUMENTATION
Tutoriel pour commencer par: anglais | Russe | Chinois
La démo de notre remorque papier: Transformers Siamois pour la récupération d'image après le traitement
Rencontrez OpenMetricLearning (OML) sur MarkTechPost
Le rapport pour Meetup basé à Berlin: "Vision par ordinateur en production". Novembre 2022. Lien
pip install -U open-metric-learning ; # minimum dependencies
pip install -U open-metric-learning[nlp]
pip install -U open-metric-learning[audio]docker pull omlteam/oml:gpu
docker pull omlteam/oml:cpu Pertes | Mineurs miner = AllTripletsMiner ()
miner = NHardTripletsMiner ()
miner = MinerWithBank ()
...
criterion = TripletLossWithMiner ( 0.1 , miner )
criterion = ArcFaceLoss ()
criterion = SurrogatePrecision () | Échantillonneurs labels = train . get_labels ()
l2c = train . get_label2category ()
sampler = BalanceSampler ( labels )
sampler = CategoryBalanceSampler ( labels , l2c )
sampler = DistinctCategoryBalanceSampler ( labels , l2c ) |
Prise en charge des configurations max_epochs : 10
sampler :
name : balance
args :
n_labels : 2
n_instances : 2 | Modèles pré-formés model_hf = AutoModel . from_pretrained ( "roberta-base" )
tokenizer = AutoTokenizer . from_pretrained ( "roberta-base" )
extractor_txt = HFWrapper ( model_hf )
extractor_img = ViTExtractor . from_pretrained ( "vits16_dino" )
transforms , _ = get_transforms_for_pretrained ( "vits16_dino" ) |
Post-traitement emb = inference ( extractor , dataset )
rr = RetrievalResults . from_embeddings ( emb , dataset )
postprocessor = AdaptiveThresholding ()
rr_upd = postprocessor . process ( rr , dataset ) | Post-traitement par NN | Papier embeddings = inference ( extractor , dataset )
rr = RetrievalResults . from_embeddings ( embeddings , dataset )
postprocessor = PairwiseReranker ( ConcatSiamese (), top_n = 3 )
rr_upd = postprocessor . process ( rr , dataset ) |
Enregistrement logger = TensorBoardPipelineLogger ()
logger = NeptunePipelineLogger ()
logger = WandBPipelineLogger ()
logger = MLFlowPipelineLogger ()
logger = ClearMLPipelineLogger () | PML from pytorch_metric_learning import losses
criterion = losses . TripletMarginLoss ( 0.2 , "all" )
pred = ViTExtractor ()( data )
criterion ( pred , gts ) |
Catégories Support # train
loader = DataLoader ( CategoryBalanceSampler ())
# validation
rr = RetrievalResults . from_embeddings ()
m . calc_retrieval_metrics_rr ( rr , query_categories ) | Métriques divers embeddigs = inference ( model , dataset )
rr = RetrievalResults . from_embeddings ( embeddings , dataset )
m . calc_retrieval_metrics_rr ( rr , precision_top_k = ( 5 ,))
m . calc_fnmr_at_fmr_rr ( rr , fmr_vals = ( 0.1 ,))
m . calc_topological_metrics ( embeddings , pcf_variance = ( 0.5 ,)) |
Foudre import pytorch_lightning as pl
model = ViTExtractor . from_pretrained ( "vits16_dino" )
clb = MetricValCallback ( EmbeddingMetrics ( dataset ))
module = ExtractorModule ( model , criterion , optimizer )
trainer = pl . Trainer ( max_epochs = 3 , callbacks = [ clb ])
trainer . fit ( module , train_loader , val_loader ) | DDP Lightning clb = MetricValCallback ( EmbeddingMetrics ( val ))
module = ExtractorModuleDDP (
model , criterion , optimizer , train , val
)
ddp = { "devices" : 2 , "strategy" : DDPStrategy ()}
trainer = pl . Trainer ( max_epochs = 3 , callbacks = [ clb ], ** ddp )
trainer . fit ( module ) |
Voici un exemple de la façon de former, de valider et de reprendre le modèle sur un petit ensemble de données d'images ou de textes. Voir plus de détails sur le format de l'ensemble de données.
| Images | Textes |
from torch . optim import Adam
from torch . utils . data import DataLoader
from oml import datasets as d
from oml . inference import inference
from oml . losses import TripletLossWithMiner
from oml . metrics import calc_retrieval_metrics_rr
from oml . miners import AllTripletsMiner
from oml . models import ViTExtractor
from oml . registry import get_transforms_for_pretrained
from oml . retrieval import RetrievalResults , AdaptiveThresholding
from oml . samplers import BalanceSampler
from oml . utils import get_mock_images_dataset
model = ViTExtractor . from_pretrained ( "vits16_dino" ). to ( "cpu" ). train ()
transform , _ = get_transforms_for_pretrained ( "vits16_dino" )
df_train , df_val = get_mock_images_dataset ( global_paths = True )
train = d . ImageLabeledDataset ( df_train , transform = transform )
val = d . ImageQueryGalleryLabeledDataset ( df_val , transform = transform )
optimizer = Adam ( model . parameters (), lr = 1e-4 )
criterion = TripletLossWithMiner ( 0.1 , AllTripletsMiner (), need_logs = True )
sampler = BalanceSampler ( train . get_labels (), n_labels = 2 , n_instances = 2 )
def training ():
for batch in DataLoader ( train , batch_sampler = sampler ):
embeddings = model ( batch [ "input_tensors" ])
loss = criterion ( embeddings , batch [ "labels" ])
loss . backward ()
optimizer . step ()
optimizer . zero_grad ()
print ( criterion . last_logs )
def validation ():
embeddings = inference ( model , val , batch_size = 4 , num_workers = 0 )
rr = RetrievalResults . from_embeddings ( embeddings , val , n_items = 3 )
rr = AdaptiveThresholding ( n_std = 2 ). process ( rr )
rr . visualize ( query_ids = [ 2 , 1 ], dataset = val , show = True )
print ( calc_retrieval_metrics_rr ( rr , map_top_k = ( 3 ,), cmc_top_k = ( 1 ,)))
training ()
validation () | from torch . optim import Adam
from torch . utils . data import DataLoader
from transformers import AutoModel , AutoTokenizer
from oml import datasets as d
from oml . inference import inference
from oml . losses import TripletLossWithMiner
from oml . metrics import calc_retrieval_metrics_rr
from oml . miners import AllTripletsMiner
from oml . models import HFWrapper
from oml . retrieval import RetrievalResults , AdaptiveThresholding
from oml . samplers import BalanceSampler
from oml . utils import get_mock_texts_dataset
model = HFWrapper ( AutoModel . from_pretrained ( "bert-base-uncased" ), 768 ). to ( "cpu" ). train ()
tokenizer = AutoTokenizer . from_pretrained ( "bert-base-uncased" )
df_train , df_val = get_mock_texts_dataset ()
train = d . TextLabeledDataset ( df_train , tokenizer = tokenizer )
val = d . TextQueryGalleryLabeledDataset ( df_val , tokenizer = tokenizer )
optimizer = Adam ( model . parameters (), lr = 1e-4 )
criterion = TripletLossWithMiner ( 0.1 , AllTripletsMiner (), need_logs = True )
sampler = BalanceSampler ( train . get_labels (), n_labels = 2 , n_instances = 2 )
def training ():
for batch in DataLoader ( train , batch_sampler = sampler ):
embeddings = model ( batch [ "input_tensors" ])
loss = criterion ( embeddings , batch [ "labels" ])
loss . backward ()
optimizer . step ()
optimizer . zero_grad ()
print ( criterion . last_logs )
def validation ():
embeddings = inference ( model , val , batch_size = 4 , num_workers = 0 )
rr = RetrievalResults . from_embeddings ( embeddings , val , n_items = 3 )
rr = AdaptiveThresholding ( n_std = 2 ). process ( rr )
rr . visualize ( query_ids = [ 2 , 1 ], dataset = val , show = True )
print ( calc_retrieval_metrics_rr ( rr , map_top_k = ( 3 ,), cmc_top_k = ( 1 ,)))
training ()
validation () |
Sortir{ 'active_tri' : 0.125 , 'pos_dist' : 82.5 , 'neg_dist' : 100.5 } # batch 1
{ 'active_tri' : 0.0 , 'pos_dist' : 36.3 , 'neg_dist' : 56.9 } # batch 2
{ 'cmc' : { 1 : 0.75 }, 'precision' : { 5 : 0.75 }, 'map' : { 3 : 0.8 }} | Sortir{ 'active_tri' : 0.0 , 'pos_dist' : 8.5 , 'neg_dist' : 11.0 } # batch 1
{ 'active_tri' : 0.25 , 'pos_dist' : 8.9 , 'neg_dist' : 9.8 } # batch 2
{ 'cmc' : { 1 : 0.8 }, 'precision' : { 5 : 0.7 }, 'map' : { 3 : 0.9 }} |
Illustrations, explications et conseils supplémentaires pour le code ci-dessus.
Voici un exemple de temps d'inférence (en d'autres termes, la récupération sur le jeu de test). Le code ci-dessous fonctionne pour les textes et les images.
from oml . datasets import ImageQueryGalleryDataset
from oml . inference import inference
from oml . models import ViTExtractor
from oml . registry import get_transforms_for_pretrained
from oml . utils import get_mock_images_dataset
from oml . retrieval import RetrievalResults , AdaptiveThresholding
_ , df_test = get_mock_images_dataset ( global_paths = True )
del df_test [ "label" ] # we don't need gt labels for doing predictions
extractor = ViTExtractor . from_pretrained ( "vits16_dino" ). to ( "cpu" )
transform , _ = get_transforms_for_pretrained ( "vits16_dino" )
dataset = ImageQueryGalleryDataset ( df_test , transform = transform )
embeddings = inference ( extractor , dataset , batch_size = 4 , num_workers = 0 )
rr = RetrievalResults . from_embeddings ( embeddings , dataset , n_items = 5 )
rr = AdaptiveThresholding ( n_std = 3.5 ). process ( rr )
rr . visualize ( query_ids = [ 0 , 1 ], dataset = dataset , show = True )
# you get the ids of retrieved items and the corresponding distances
print ( rr )Voici un exemple où les requêtes et les galeries traitées séparément.
import pandas as pd
from oml . datasets import ImageBaseDataset
from oml . inference import inference
from oml . models import ViTExtractor
from oml . registry import get_transforms_for_pretrained
from oml . retrieval import RetrievalResults , ConstantThresholding
from oml . utils import get_mock_images_dataset
extractor = ViTExtractor . from_pretrained ( "vits16_dino" ). to ( "cpu" )
transform , _ = get_transforms_for_pretrained ( "vits16_dino" )
paths = pd . concat ( get_mock_images_dataset ( global_paths = True ))[ "path" ]
galleries , queries1 , queries2 = paths [: 20 ], paths [ 20 : 22 ], paths [ 22 : 24 ]
# gallery is huge and fixed, so we only process it once
dataset_gallery = ImageBaseDataset ( galleries , transform = transform )
embeddings_gallery = inference ( extractor , dataset_gallery , batch_size = 4 , num_workers = 0 )
# queries come "online" in stream
for queries in [ queries1 , queries2 ]:
dataset_query = ImageBaseDataset ( queries , transform = transform )
embeddings_query = inference ( extractor , dataset_query , batch_size = 4 , num_workers = 0 )
# for the operation below we are going to provide integrations with vector search DB like QDrant or Faiss
rr = RetrievalResults . from_embeddings_qg (
embeddings_query = embeddings_query , embeddings_gallery = embeddings_gallery ,
dataset_query = dataset_query , dataset_gallery = dataset_gallery
)
rr = ConstantThresholding ( th = 80 ). process ( rr )
rr . visualize_qg ([ 0 , 1 ], dataset_query = dataset_query , dataset_gallery = dataset_gallery , show = True )
print ( rr )Les pipelines fournissent un moyen d'exécuter des expériences d'apprentissage métrique en modifiant uniquement le fichier de configuration. Tout ce dont vous avez besoin est de préparer votre ensemble de données dans un format requis.
Voir le dossier Pipelines pour plus de détails:
Voici une intégration légère avec les modèles de transformateurs HuggingFace. Vous pouvez le remplacer par d'autres modèles arbitraires hérités de IExtractor.
Remarque, nous n'avons pas nos propres modèles de texte zoo pour le moment.
pip install open-metric-learning[nlp] from transformers import AutoModel , AutoTokenizer
from oml . models import HFWrapper
model = AutoModel . from_pretrained ( 'bert-base-uncased' ). eval ()
tokenizer = AutoTokenizer . from_pretrained ( 'bert-base-uncased' )
extractor = HFWrapper ( model = model , feat_dim = 768 )
inp = tokenizer ( text = "Hello world" , return_tensors = "pt" , add_special_tokens = True )
embeddings = extractor ( inp )Vous pouvez utiliser un modèle d'image à partir de notre zoo ou utiliser d'autres modèles arbitraires après l'avoir hérité de IExtractor.
from oml . const import CKPT_SAVE_ROOT as CKPT_DIR , MOCK_DATASET_PATH as DATA_DIR
from oml . models import ViTExtractor
from oml . registry import get_transforms_for_pretrained
model = ViTExtractor . from_pretrained ( "vits16_dino" ). eval ()
transforms , im_reader = get_transforms_for_pretrained ( "vits16_dino" )
img = im_reader ( DATA_DIR / "images" / "circle_1.jpg" ) # put path to your image here
img_tensor = transforms ( img )
# img_tensor = transforms(image=img)["image"] # for transforms from Albumentations
features = model ( img_tensor . unsqueeze ( 0 ))
# Check other available models:
print ( list ( ViTExtractor . pretrained_models . keys ()))
# Load checkpoint saved on a disk:
model_ = ViTExtractor ( weights = CKPT_DIR / "vits16_dino.ckpt" , arch = "vits16" , normalise_features = False )Modèles, formés par nous. Les métriques ci-dessous sont pour 224 x 224 images:
| modèle | CMC1 | ensemble de données | poids | expérience |
|---|---|---|---|---|
ViTExtractor.from_pretrained("vits16_inshop") | 0,921 | Deepfashion Inshop | lien | lien |
ViTExtractor.from_pretrained("vits16_sop") | 0,866 | Produits en ligne de Stanford | lien | lien |
ViTExtractor.from_pretrained("vits16_cars") | 0,907 | Voitures 196 | lien | lien |
ViTExtractor.from_pretrained("vits16_cub") | 0,837 | Cub 200 2011 | lien | lien |
Modèles, formés par d'autres chercheurs. Notez que certaines mesures sur des références particulières sont si élevées car elles faisaient partie de l'ensemble de données de formation (par exemple unicom ). Les métriques ci-dessous sont pour 224 x 224 images:
| modèle | Produits en ligne de Stanford | Deepfashion Inshop | Cub 200 2011 | Voitures 196 |
|---|---|---|---|---|
ViTUnicomExtractor.from_pretrained("vitb16_unicom") | 0,700 | 0,734 | 0,847 | 0,916 |
ViTUnicomExtractor.from_pretrained("vitb32_unicom") | 0,690 | 0,722 | 0,796 | 0,893 |
ViTUnicomExtractor.from_pretrained("vitl14_unicom") | 0,726 | 0,790 | 0,868 | 0,922 |
ViTUnicomExtractor.from_pretrained("vitl14_336px_unicom") | 0,745 | 0,810 | 0,875 | 0,924 |
ViTCLIPExtractor.from_pretrained("sber_vitb32_224") | 0,547 | 0,514 | 0,448 | 0,618 |
ViTCLIPExtractor.from_pretrained("sber_vitb16_224") | 0,565 | 0,565 | 0,524 | 0,648 |
ViTCLIPExtractor.from_pretrained("sber_vitl14_224") | 0,512 | 0,555 | 0,606 | 0,707 |
ViTCLIPExtractor.from_pretrained("openai_vitb32_224") | 0,612 | 0,491 | 0,560 | 0,693 |
ViTCLIPExtractor.from_pretrained("openai_vitb16_224") | 0,648 | 0,606 | 0,665 | 0,767 |
ViTCLIPExtractor.from_pretrained("openai_vitl14_224") | 0,670 | 0,675 | 0,745 | 0,844 |
ViTExtractor.from_pretrained("vits16_dino") | 0,648 | 0,509 | 0,627 | 0,265 |
ViTExtractor.from_pretrained("vits8_dino") | 0,651 | 0,524 | 0,661 | 0,315 |
ViTExtractor.from_pretrained("vitb16_dino") | 0,658 | 0,514 | 0,541 | 0,288 |
ViTExtractor.from_pretrained("vitb8_dino") | 0,689 | 0,599 | 0,506 | 0,313 |
ViTExtractor.from_pretrained("vits14_dinov2") | 0,566 | 0,334 | 0,797 | 0,503 |
ViTExtractor.from_pretrained("vits14_reg_dinov2") | 0,566 | 0,332 | 0,795 | 0,740 |
ViTExtractor.from_pretrained("vitb14_dinov2") | 0,565 | 0,342 | 0,842 | 0,644 |
ViTExtractor.from_pretrained("vitb14_reg_dinov2") | 0,557 | 0,324 | 0,833 | 0,828 |
ViTExtractor.from_pretrained("vitl14_dinov2") | 0,576 | 0,352 | 0,844 | 0,692 |
ViTExtractor.from_pretrained("vitl14_reg_dinov2") | 0,571 | 0,340 | 0,840 | 0,871 |
ResnetExtractor.from_pretrained("resnet50_moco_v2") | 0,493 | 0,267 | 0,264 | 0.149 |
ResnetExtractor.from_pretrained("resnet50_imagenet1k_v1") | 0,515 | 0,284 | 0,455 | 0,247 |
Les mesures peuvent être différentes de celles rapportées par les articles, car la version de la division Train / Val et l'utilisation des boîtes de délimitation peuvent différer.
Nous accueillons de nouveaux contributeurs! S'il vous plaît, voyez notre:
Le projet a été lancé en 2020 en tant que module pour la bibliothèque Catalyst. Je tiens à remercier les gens qui ont travaillé avec moi sur ce module: Julia Shenshina, Nikita Balagansky, Sergey Kolesnikov et autres.
Je tiens à remercier les gens qui continuent de travailler sur ce pipeline lorsqu'il est devenu un projet distinct: Julia Shenshina, Misha Kindulov, Aron Dik, Aleksei Tarasov et Verkhovtsev Leonid.
Je tiens également à remercier Newyorker, car la partie de la fonctionnalité a été développée (et utilisée) par son équipe de vision par ordinateur dirigée par moi.