Transformers documentation
التقطير المعرفي لرؤية الحاسوب
التقطير المعرفي لرؤية الحاسوب
تُعد تقطير المعرفة تقنية تُستخدم لنقل المعرفة من نموذج أكبر وأكثر تعقيدًا (المعلم) إلى نموذج أصغر وبساطة (الطالب). ولتقطير المعرفة من نموذج إلى آخر، نأخذ نموذج معلم مُدرَّب مسبقًا على مهمة معينة (تصنيف الصور في هذه الحالة) ونُهيّئ نموذج طالب عشوائيًا ليُدرَّب على تصنيف الصور. ثم ندرّب نموذج الطالب لتقليل الفرق بين مخرجاته ومخرجات المعلم، مما يجعله يحاكي سلوكه. وقد قُدِّمت هذه التقنية لأول مرة في Distilling the Knowledge in a Neural Network بواسطة Hinton وآخرون. في هذا الدليل، سنقوم بتقطير المعرفة الخاص بالمهمة. وسنستخدم مجموعة بيانات beans لهذا الغرض.
يُبيّن هذا الدليل كيفية تقطير نموذج ViT المُحسَّن (نموذج المعلم) إلى MobileNet (نموذج الطالب) باستخدام واجهة Trainer API في 🤗 Transformers.
لنقم بتثبيت المكتبات اللازمة لعملية التقطير وتقييمها.
pip install transformers datasets accelerate tensorboard evaluate trackio --upgrade
في هذا المثال، نستخدم نموذج merve/beans-vit-224 كنموذج مُعلِّم. وهو نموذج لتصنيف الصور، مبني على google/vit-base-patch16-224-in21k وخضع لضبط الدقة على مجموعة بيانات beans. سنقوم بتقطير هذا النموذج إلى نموذج MobileNetV2 مُهيّأ عشوائياً.
سنقوم الآن بتحميل مجموعة البيانات.
from datasets import load_dataset
dataset = load_dataset("AI-Lab-Makerere/beans")يمكننا استخدام مُعالج صور من أيٍّ من النموذجين، ففي هذه الحالة يُرجِعان نفس المخرجات بنفس الدقة. سنستخدم طريقة map() الخاصة بـdataset لتطبيق المعالجة المسبقة على كل تقسيم من مجموعات البيانات.
from transformers import AutoImageProcessor
teacher_processor = AutoImageProcessor.from_pretrained("merve/beans-vit-224")
def process(examples):
processed_inputs = teacher_processor(examples["image"])
return processed_inputs
processed_datasets = dataset.map(process, batched=True)في جوهر الأمر، نريد أن يحاكي نموذج الطالب (وهو MobileNet مُهيّأ عشوائياً) نموذج المعلم (وهو vision transformer مُعدّل). لتحقيق ذلك، نحصل أولاً على مخرجات logits من كلٍّ من نموذج المعلم ونموذج الطالب. ثم نقسم كلًّا منهما على المعامل temperature الذي يتحكم في أهمية كل هدف ناعم. ويوزن معامل يُدعى lambda أهمية خسارة التقطير. في هذا المثال، سنستخدم temperature=5 وlambda=0.5. سنستخدم خسارة تباعد كولباك-لايبلر (Kullback-Leibler Divergence) لحساب التباعد بين نموذج الطالب ونموذج المعلم. عند وجود بيانات P وQ، يوضح تباعد KL مقدار المعلومات الإضافية التي نحتاجها لتمثيل P باستخدام Q. إذا كانت البيانات متطابقة، فإن تباعد KL بينهما يساوي صفرًا، إذ لا توجد معلومات أخرى مطلوبة لشرح P انطلاقًا من Q. وبالتالي، في سياق تقطير المعرفة، يكون تباعد KL مفيدًا.
from transformers import TrainingArguments, Trainer
from accelerate import Accelerator
import torch
import torch.nn as nn
import torch.nn.functional as F
class ImageDistilTrainer(Trainer):
def __init__(self, teacher_model=None, student_model=None, temperature=None, lambda_param=None, *args, **kwargs):
super().__init__(model=student_model, *args, **kwargs)
self.teacher = teacher_model
self.student = student_model
self.loss_function = nn.KLDivLoss(reduction="batchmean")
device = Accelerator().device
self.teacher.to(device)
self.teacher.eval()
self.temperature = temperature
self.lambda_param = lambda_param
def compute_loss(self, student, inputs, return_outputs=False):
student_output = self.student(**inputs)
with torch.no_grad():
teacher_output = self.teacher(**inputs)
# Compute soft targets for teacher and student
soft_teacher = F.softmax(teacher_output.logits / self.temperature, dim=-1)
soft_student = F.log_softmax(student_output.logits / self.temperature, dim=-1)
# Compute the loss
distillation_loss = self.loss_function(soft_student, soft_teacher) * (self.temperature ** 2)
# Compute the true label loss
student_target_loss = student_output.loss
# Calculate final loss
loss = (1. - self.lambda_param) * student_target_loss + self.lambda_param * distillation_loss
return (loss, student_output) if return_outputs else lossسنسجّل الدخول الآن إلى Hugging Face Hub حتى نتمكن من دفع نموذجنا إلى Hugging Face Hub عبر Trainer.
from huggingface_hub import notebook_login
notebook_login()لنقم بتعيين TrainingArguments ونموذج المعلم ونموذج الطالب.
from transformers import AutoModelForImageClassification, MobileNetV2Config, MobileNetV2ForImageClassification
training_args = TrainingArguments(
output_dir="my-awesome-model",
num_train_epochs=30,
fp16=True,
logging_strategy="epoch",
eval_strategy="epoch",
save_strategy="epoch",
load_best_model_at_end=True,
metric_for_best_model="accuracy",
push_to_hub=True,
hub_strategy="every_save",
hub_model_id=repo_name,
report_to="trackio",
run_name="distillation",
)
num_labels = len(processed_datasets["train"].features["labels"].names)
# initialize models
teacher_model = AutoModelForImageClassification.from_pretrained(
"merve/beans-vit-224",
num_labels=num_labels,
ignore_mismatched_sizes=True
)
# training MobileNetV2 from scratch
student_config = MobileNetV2Config()
student_config.num_labels = num_labels
student_model = MobileNetV2ForImageClassification(student_config)يمكننا استخدام دالة compute_metrics لتقييم نموذجنا على مجموعة الاختبار. ستُستخدم هذه الدالة أثناء عملية التدريب لحساب accuracy و f1 لنموذجنا.
import evaluate
import numpy as np
accuracy = evaluate.load("accuracy")
def compute_metrics(eval_pred):
predictions, labels = eval_pred
acc = accuracy.compute(references=labels, predictions=np.argmax(predictions, axis=1))
return {"accuracy": acc["accuracy"]}لنقم بتهيئة Trainer باستخدام حُجج التدريب التي عرّفناها. كما سنقوم بتهيئة مُجمِّع البيانات الخاص بنا.
from transformers import DefaultDataCollator
data_collator = DefaultDataCollator()
trainer = ImageDistilTrainer(
student_model=student_model,
teacher_model=teacher_model,
training_args=training_args,
train_dataset=processed_datasets["train"],
eval_dataset=processed_datasets["validation"],
data_collator=data_collator,
processing_class=teacher_processor,
compute_metrics=compute_metrics,
temperature=5,
lambda_param=0.5
)يمكننا الآن تدريب نموذجنا.
trainer.train()
يمكننا تقييم النموذج على مجموعة الاختبار.
trainer.evaluate(processed_datasets["test"])على مجموعة الاختبار، تصل دقة نموذجنا إلى 72 في المئة. ولإجراء فحص صحة لكفاءة التقطير، قمنا أيضاً بتدريب MobileNet على مجموعة بيانات الفول من الصفر باستخدام نفس المعلمات الفائقة، ولاحظنا دقة قدرها 63 في المئة على مجموعة الاختبار. ندعو القراء إلى تجربة نماذج معلمة مسبقة التدريب مختلفة، وهياكل طالب مختلفة، ومعلمات تقطير مختلفة، وإبلاغ نتائجهم. يمكن العثور على سجلات التدريب ونقاط التفتيش للنموذج المُقطَّر في هذا المستودع، ويمكن العثور على MobileNetV2 المُدرَّب من الصفر في هذا المستودع.
Update on GitHub