OML هو إطار قائم على Pytorch لتدريب النماذج والتحقق من صحة النماذج التي تنتج تضمينات عالية الجودة.
ㅤㅤ
هناك عدد من الأشخاص من جامعات أكسفورد و HSE الذين استخدموا OML في أطروحاتهم. [1] [2] [3]
يركز التحديث على عدة مكونات:
أضفنا دعم النصوص "الرسمية" وأمثلة Python المقابلة. (لاحظ أن دعم النصوص في خطوط الأنابيب غير مدعوم بعد.)
قدمنا فئة RetrievalResults ( RR ) - حاوية لتخزين عناصر المعرض التي تم استردادها للاستعلامات المعطاة. يوفر RR طريقة موحدة لتصور التنبؤات وحساب المقاييس (إذا كانت الحقائق الأرضية معروفة). كما أنه يبسط معالجة ما بعد المعالجة ، حيث يتم أخذ كائن RR كمدخل ويتم إنتاج RR_upd آخر كمخرج. وجود هذين الكائنين يسمح بنتائج استرجاع المقارنة بصريًا أو عن طريق المقاييس. علاوة على ذلك ، يمكنك بسهولة إنشاء سلسلة من هذه المعالجات.
RR بسبب استخدام الدفع: بمعنى آخر ، لا تخزن مصفوفة كاملة من مسافات الاستعلام. (لا يجعل البحث تقريبيًا). لقد صنعنا Model ومجموعة Dataset الفصول الوحيدة المسؤولة عن معالجة المنطق الخاص بالطريقة. Model مسؤول عن تفسير أبعاد الإدخال الخاصة به: على سبيل المثال ، BxCxHxW للصور أو BxLxD لتسلسلات مثل النصوص. Dataset مسؤولة عن إعداد عنصر: قد تستخدم Transforms للصور أو Tokenizer للنصوص. وظائف الحوسبة مقاييس مثل calc_retrieval_metrics_rr ، RetrievalResults ، و PairwiseReranker ، والفئات والوظائف الأخرى موحدة للعمل مع أي طريقة.
IVisualizableDataset وجود طريقة .visaulize() التي تعرض عنصرًا واحدًا. إذا تم تنفيذها ، فإن RetrievalResults قادر على إظهار تخطيط النتائج التي تم استردادها. أسهل طريقة للحاق بالتغييرات هي إعادة قراءة الأمثلة!
تتمثل الطريقة الموصى بها في التحقق من الصحة في استخدام RetrievalResults ووظائف مثل calc_retrieval_metrics_rr ، calc_fnmr_at_fmr_rr ، وغيرها. يتم الحفاظ على فئة EmbeddingMetrics للاستخدام مع Lightning Pytorch وداخل خطوط الأنابيب. لاحظ أن توقيعات طرق EmbeddingMetrics قد تم تغييرها قليلاً ، انظر أمثلة البرق لذلك.
نظرًا لأن المنطق المحدد للمسلسل يقتصر على Dataset ، فإنه لا يخرج PATHS_KEY و X1_KEY و X2_KEY و Y1_KEY و Y2_KEY بعد الآن. لا تزال المفاتيح التي ليست خاصة بالطريقة مثل LABELS_KEY ، IS_GALLERY ، IS_QUERY_KEY ، CATEGORIES_KEY قيد الاستخدام.
inference_on_images هو الآن inference ويعمل مع أي طريقة.
واجهات تم تغييرها قليلاً من Datasets. على سبيل المثال ، لدينا واجهات IQueryGalleryDataset و IQueryGalleryLabeledDataset . الأول يجب استخدامه للاستدلال ، والثاني للتحقق من الصحة. وأضاف أيضا واجهة IVisualizableDataset .
إزالة بعض الأدوات الداخلية مثل IMetricDDP ، EmbeddingMetricsDDP ، calc_distance_matrix ، calc_gt_mask ، calc_mask_to_ignore ، apply_mask_to_ignore . لا ينبغي أن تؤثر هذه التغييرات عليك. كما تم إزالة الكود المتعلق بخط أنابيب مع ثلاثة توائم محسوبة.
استخراج الميزة: لا توجد تغييرات ، باستثناء إضافة وسيطة اختيارية - mode_for_checkpointing = (min | max) . قد يكون من المفيد التبديل بين الجزء السفلي ، وأفضل وأكبر ، وأفضل نوع المقاييس.
خط أنابيب معالجة Pairwise-Postprocess: غيرت قليلاً اسم ووسائط التكوين الفرعي لما بعد postprocessor pairwise_images الآن pairwise_reranker ولا يحتاج إلى تحويلات.
قد تفكر "إذا كنت بحاجة إلى تضمينات صورة ، يمكنني ببساطة تدريب مصنف الفانيليا وأخذ طبقتها قبل الأخيرة" . حسنًا ، من المنطقي كنقطة انطلاق. ولكن هناك العديد من العيوب الممكنة:
إذا كنت ترغب في استخدام التضمينات لأداء البحث ، فأنت بحاجة إلى حساب بعض المسافة بينها (على سبيل المثال ، جيب التمام أو L2). عادة ، لا تقوم بتحسين هذه المسافات مباشرة أثناء التدريب في إعداد التصنيف. لذلك ، لا يمكنك إلا أن تأمل في أن يكون للتضمينات النهائية الخصائص المطلوبة.
المشكلة الثانية هي عملية التحقق من الصحة . في إعداد البحث ، عادةً ما تهتم بمدى ارتباط مخرجات أفضل N بالاستعلام. تتمثل الطريقة الطبيعية لتقييم النموذج في محاكاة طلبات البحث في المجموعة المرجعية وتطبيق أحد مقاييس الاسترجاع. لذلك ، ليس هناك ما يضمن أن دقة التصنيف سترتبط بهذه المقاييس.
أخيرًا ، قد ترغب في تنفيذ خط أنابيب تعليمي متري بنفسك. هناك الكثير من العمل : لاستخدام الخسارة الثلاثية التي تحتاجها لتشكيل دفعات بطريقة محددة ، وتنفيذ أنواع مختلفة من التعدين الثلاثي ، ومسافات التتبع ، وما إلى ذلك. للتحقق من الصحة ، تحتاج أيضًا إلى تنفيذ مقاييس الاسترجاع ، والتي تشمل تراكمًا فعالًا للتضمينات أثناء الحقبة ، وتغطية حالات الزاوية ، وما إلى ذلك. قد ترغب أيضًا في تصور طلبات البحث عن طريق تسليط الضوء على نتائج البحث الجيدة والسيئة. بدلاً من القيام بذلك بنفسك ، يمكنك ببساطة استخدام OML لأغراضك.
PML هي المكتبة الشهيرة للتعلم المتري ، وتشمل مجموعة غنية من الخسائر وعمال المناجم والمسافات والمخفضات ؛ هذا هو السبب في أننا نقدم أمثلة مباشرة لاستخدامها مع OML. في البداية ، حاولنا استخدام PML ، ولكن في النهاية ، توصلنا إلى مكتبتنا ، والتي هي موجهة أكثر من خطوط الأنابيب / الوصفات. هكذا يختلف OML عن PML:
تحتوي OML على خطوط أنابيب تتيح نماذج التدريب عن طريق إعداد تكوين وبياناتك بالتنسيق المطلوب (يشبه تحويل البيانات إلى تنسيق COCO لتدريب كاشف من MMDETECELS).
يركز OML على خطوط الأنابيب الشاملة وحالات الاستخدام العملي. يحتوي على أمثلة على أساس التكوين على المعايير الشائعة القريبة من الحياة الحقيقية (مثل صور منتجات الآلاف من IDS). لقد وجدنا بعض مجموعات جيدة من المقاييس المفرطة على مجموعات البيانات هذه ، والنماذج المدربة والمنشورة وتكويناتها. وبالتالي ، فإنه يجعل OML المزيد من الوصفات الموجهة أكثر من PML ، ويؤكد مؤلفها هذا القول بأن مكتبته هي مجموعة من الأدوات بدلاً من الوصفات ، علاوة على ذلك ، فإن الأمثلة في PML هي في الغالب لجماعات البيانات CIFAR و MNIST.
يحتوي OML على حديقة حيوانات من النماذج المسبقة التي يمكن الوصول إليها بسهولة من الكود بالطريقة نفسها كما في torchvision (عند كتابة resnet50(pretrained=True) ).
تم دمج OML مع Lightning Pytorch ، لذلك ، يمكننا استخدام قوة المدرب. هذا مفيد بشكل خاص عندما نعمل مع DDP ، لذلك ، يمكنك مقارنة مثال DDP الخاص بنا و PMLS. بالمناسبة ، يحتوي PML أيضًا على مدربين ، لكنه لا يستخدم على نطاق واسع في الأمثلة ويتم استخدام وظائف train / test المخصصة بدلاً من ذلك.
نعتقد أن وجود خطوط أنابيب وأمثلة laconic وحديقة حيوانات النماذج المسبقة يضع عتبة الدخول إلى قيمة منخفضة حقًا.
تعني مشكلة التعلم المتري (المعروفة أيضًا باسم مشكلة التصنيف المتطرف ) موقفًا لدينا آلاف من المعرفات من بعض الكيانات ، ولكن فقط عدد قليل من العينات لكل كيان. غالبًا ما نفترض أنه خلال مرحلة الاختبار (أو الإنتاج) ، سوف نتعامل مع الكيانات غير المرئية مما يجعل من المستحيل تطبيق خط أنابيب تصنيف الفانيليا مباشرة. في كثير من الحالات يتم استخدام التضمينات التي تم الحصول عليها لإجراء إجراءات البحث أو المطابقة عليها.
فيما يلي بعض الأمثلة على هذه المهام من مجال رؤية الكمبيوتر:
embedding - إخراج النموذج (المعروف أيضًا باسم features vector أو descriptor ).query - عينة يتم استخدامها كطلب في إجراء الاسترجاع.gallery set - مجموعة الكيانات للبحث عن عناصر مماثلة query (المعروف أيضًا باسم reference أو index ).Sampler - وسيطة لـ DataLoader التي تستخدم لتشكيل دفعاتMiner - الكائن لتشكيل أزواج أو ثلاثة توائم بعد أن تم تشكيل الدفعة بواسطة Sampler . ليس من الضروري تكوين مجموعات من العينات فقط داخل الدفعة الحالية ، وبالتالي ، قد يكون بنك الذاكرة جزءًا من Miner .Samples / Labels / Instances - كمثال دعنا نفكر في مجموعة بيانات DeepFashion. ويشمل الآلاف من معرفات عناصر الموضة (نسميها labels ) والعديد من الصور لكل معرف عنصر (نسمي الصورة الفردية instance أو sample ). تحتوي جميع معرفات عناصر الموضة على مجموعات مثل "التنانير" و "السترات" و "السراويل القصيرة" وما إلى ذلك (نسميها categories ). ملاحظة ، نتجنب استخدام class المصطلح لتجنب سوء الفهم.training epoch - عينات الدُفعات التي نستخدمها للخسائر المستندة إلى المركب عادة ما يكون لها طول يساوي [number of labels in training dataset] / [numbers of labels in one batch] . وهذا يعني أننا لا نلاحظ جميع عينات التدريب المتاحة في فترة واحدة (على عكس تصنيف الفانيليا) ، بدلاً من ذلك ، نلاحظ جميع الملصقات المتاحة.قد تكون قابلة للمقارنة مع أساليب SOTA الحالية (2022) ، على سبيل المثال ، HYP-VIT. (بضع كلمات حول هذا النهج: إنها بنية VIT مدربة بخسارة متناقضة ، ولكن تم إسقاط التضمين في بعض المساحات الزائدية. كما ادعى المؤلفون ، فإن مثل هذه المساحة قادرة على وصف الهيكل المتداخل للبيانات الواقعية. لذلك ، تتطلب الورقة بعض الرياضيات الثقيلة لتكييف العمليات المعتادة للمساحة المفرطة للجلدية.)
قمنا بتدريب نفس الهندسة المعمارية مع الخسارة الثلاثي ، وإصلاح بقية المعلمات: التحولات التدريبية والاختبار ، وحجم الصورة ، والمحسّنة. انظر التكوينات في موديلات حديقة الحيوان. كانت الحيلة في الاستدلال في عمال المناجم وأخذ عيناتنا:
تشكل عينة توازن الفئة الدُفعات التي تحد من عدد الفئات C في ذلك. على سبيل المثال ، عندما يضع C = 1 فقط السترات في دفعة واحدة وبنطلون جينز فقط في واحدة أخرى (مجرد مثال). إنه يجعل الأزواج السلبية تلقائيًا أكثر صعوبة: من المستحق أن يدرك نموذجًا سبب وجود اثنين من السترات المختلفة عن فهم نفس سترة وقميص.
يجعل منجم التوائم الصلبة المهمة أكثر صعوبة الحفاظ على أصعب ثلاثة توائم (مع أقصى مسافات إيجابية وأقل مسافات سلبية).
فيما يلي CMC@1 درجات ل 2 معايير شعبية. مجموعة بيانات SOP: HYP-VIT-85.9 ، لنا-86.6. مجموعة بيانات DeepFashion: HYP-VIT-92.5 ، لنا-92.1. وبالتالي ، فإن الاستفادة من الاستدلال البسيط وتجنب الرياضيات الثقيلة ، يمكننا القيام بها على مستوى SOTA.
الأبحاث الحديثة في SSL حصلت بالتأكيد على نتائج رائعة. المشكلة هي أن هذه الأساليب تتطلب كمية هائلة من الحوسبة لتدريب النموذج. ولكن في إطار عملنا ، نعتبر الحالة الأكثر شيوعًا عندما لا يكون لدى المستخدم العادي أكثر من عدد قليل من وحدات معالجة الرسومات.
في الوقت نفسه ، سيكون من غير الحكمة تجاهل النجاح في هذا المجال ، لذلك ما زلنا نستغلها بطريقتين:
لا ، أنت لا تفعل ذلك. OML هو إطار عمل. على الرغم من أننا نستخدم Pytorch Lightning كعداء حلقة للتجارب ، إلا أننا نحافظ أيضًا على إمكانية تشغيل كل شيء على Pytorch النقي. وبالتالي ، فإن الجزء الصغير فقط من OML هو خاص بالبرق ونحافظ على هذا المنطق بشكل منفصل عن التعليمات البرمجية الأخرى (انظر oml.lightning ). حتى عند استخدام Lightning ، لا تحتاج إلى معرفته ، نظرًا لأننا نقدم جاهزًا لاستخدام خطوط الأنابيب.
إن إمكانية استخدام Pytorch النقي والبنية المعيارية للرمز تترك مجالًا لاستخدام OML مع إطارك المفضل بعد تنفيذ الأغطية اللازمة.
نعم. لتشغيل التجربة مع خطوط الأنابيب ، تحتاج فقط إلى كتابة محول إلى تنسيقنا (يعني إعداد جدول .csv مع بعض الأعمدة المحددة مسبقًا). هذا كل شيء!
ربما لدينا بالفعل نموذج مناسب تدريبه مسبقًا لنطاقك في حديقة حيوانات النماذج الخاصة بنا. في هذه الحالة ، لا تحتاج حتى إلى تدريبه.
حاليًا ، لا ندعم نماذج تصدير إلى ONNX مباشرة. ومع ذلك ، يمكنك استخدام إمكانيات Pytorch المدمجة لتحقيق ذلك. لمزيد من المعلومات ، يرجى الرجوع إلى هذه المشكلة.
الوثائق
البرنامج التعليمي للبدء بـ: اللغة الإنجليزية | الروسية | الصينية
العرض التوضيحي لحركنا الورقي: محولات سيامي لاسترجاع الصور بعد المعالجة
قابل OpenMetriclearning (OML) على MarkTechPost
تقرير Meetup ومقره برلين: "رؤية الكمبيوتر في الإنتاج". نوفمبر 2022. الرابط
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 الخسائر | عمال المناجم miner = AllTripletsMiner ()
miner = NHardTripletsMiner ()
miner = MinerWithBank ()
...
criterion = TripletLossWithMiner ( 0.1 , miner )
criterion = ArcFaceLoss ()
criterion = SurrogatePrecision () | عينات labels = train . get_labels ()
l2c = train . get_label2category ()
sampler = BalanceSampler ( labels )
sampler = CategoryBalanceSampler ( labels , l2c )
sampler = DistinctCategoryBalanceSampler ( labels , l2c ) |
تكوين الدعم max_epochs : 10
sampler :
name : balance
args :
n_labels : 2
n_instances : 2 | نماذج مدربة مسبقا 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" ) |
ما بعد المعالجة emb = inference ( extractor , dataset )
rr = RetrievalResults . from_embeddings ( emb , dataset )
postprocessor = AdaptiveThresholding ()
rr_upd = postprocessor . process ( rr , dataset ) | بعد المعالجة بواسطة NN | ورق embeddings = inference ( extractor , dataset )
rr = RetrievalResults . from_embeddings ( embeddings , dataset )
postprocessor = PairwiseReranker ( ConcatSiamese (), top_n = 3 )
rr_upd = postprocessor . process ( rr , dataset ) |
قطع الأشجار 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 ) |
دعم الفئات # train
loader = DataLoader ( CategoryBalanceSampler ())
# validation
rr = RetrievalResults . from_embeddings ()
m . calc_retrieval_metrics_rr ( rr , query_categories ) | مقاييس منصقة 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 ,)) |
البرق 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 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 ) |
فيما يلي مثال على كيفية التدريب والتحقق من صحة النموذج والتحقق منه على مجموعة بيانات صغيرة من الصور أو النصوص. انظر المزيد من التفاصيل حول تنسيق مجموعة البيانات.
| الصور | النصوص |
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 () |
الإخراج{ '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 }} | الإخراج{ '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 }} |
الرسوم التوضيحية الإضافية والتفسيرات والنصائح للرمز أعلاه.
فيما يلي مثال وقت الاستدلال (بمعنى آخر ، استرجاع مجموعة الاختبار). الرمز أدناه يعمل لكل من النصوص والصور.
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 )فيما يلي مثال حيث تمت معالجة الاستعلامات والمعارض بشكل منفصل.
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 )توفر خطوط الأنابيب طريقة لتشغيل تجارب التعلم المتري عبر تغيير ملف التكوين فقط. كل ما تحتاجه هو إعداد مجموعة البيانات الخاصة بك بتنسيق مطلوب.
انظر مجلد خطوط الأنابيب لمزيد من التفاصيل:
فيما يلي تكامل خفيف الوزن مع نماذج Luggingface Transformers. يمكنك استبداله بنماذج أخرى تعسفية موروثة من Iextractor.
لاحظ ، ليس لدينا حديقة حيوانات النصوص الخاصة بنا في الوقت الحالي.
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 )يمكنك استخدام نموذج صورة من حديقة الحيوان الخاصة بنا أو استخدام نماذج تعسفية أخرى بعد أن ورثتها من 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 )نماذج ، تدرب من قبلنا. المقاييس أدناه هي 224 × 224 صور:
| نموذج | CMC1 | مجموعة البيانات | الأوزان | تجربة |
|---|---|---|---|---|
ViTExtractor.from_pretrained("vits16_inshop") | 0.921 | Deepfashion Inshop | وصلة | وصلة |
ViTExtractor.from_pretrained("vits16_sop") | 0.866 | منتجات ستانفورد على الإنترنت | وصلة | وصلة |
ViTExtractor.from_pretrained("vits16_cars") | 0.907 | السيارات 196 | وصلة | وصلة |
ViTExtractor.from_pretrained("vits16_cub") | 0.837 | شبل 200 2011 | وصلة | وصلة |
نماذج ، تدرب من قبل باحثين آخرين. لاحظ أن بعض المقاييس على معايير معينة مرتفعة للغاية لأنها كانت جزءًا من مجموعة بيانات التدريب (على سبيل المثال unicom ). المقاييس أدناه هي 224 × 224 صور:
| نموذج | منتجات ستانفورد على الإنترنت | Deepfashion Inshop | شبل 200 2011 | السيارات 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 |
قد تختلف المقاييس عن تلك التي أبلغت عنها الأوراق ، لأن إصدار تقسيم القطار/VAL واستخدام الصناديق المحيطة قد يختلف.
نرحب بالمساهمين الجدد! من فضلك ، انظر لدينا:
بدأ المشروع في عام 2020 كوحدة لمكتبة Catalyst. أود أن أشكر الأشخاص الذين عملوا معي على تلك الوحدة: جوليا شينشينا ، نيكيتا بالاجانسكي ، سيرجي كولسنيكوف وآخرين.
أود أن أشكر الأشخاص الذين يواصلون العمل على خط الأنابيب هذا عندما أصبح مشروعًا منفصلاً: جوليا شينشينا ، وميشا كيندوولوف ، وآرون ديك ، وأليكسي تاراسوف ، وفيرخوفتسيف ليونيد.
أود أيضًا أن أشكر NewYorker ، حيث تم تطوير جزء من الوظيفة (واستخدمه) من قبل فريق رؤية الكمبيوتر الذي يقوده لي.