درّب نموذجك الأول على تعليقاتك التوضيحية
شغّل دراسة المراجعات النموذجية في Potato على حاسوب محمول بلا GPU، وصنّف 120 مراجعة بالمحاكي، ودرّب sklearn-text، واطّلع على التصنيفات المسبقة التي يقترحها النموذج.
جديد في v2.14.0
يدرّب هذا الدرس مصنِّفاً للمشاعر على تصنيفات دراسة نموذجية، ويعرض إجابات المصنِّف على المعلّق التالي بوصفها تصنيفات مسبقة. كُتب الدرس لصاحب دراسة يجرّب تدريب النماذج في Potato للمرة الأولى، وكل خطوة فيه تعمل على حاسوب محمول بلا GPU ومن دون تثبيت شيء سوى Potato نفسه. تبدأ مشروع المراجعات النموذجي في Potato، وتدع محاكي المستخدمين يصنّف 120 مراجعة من مراجعات المشروع البالغ عددها 160، وتدرّب sklearn-text من صفحة التدريب في لوحة الإدارة، وتقرأ درجة العناصر المحجوزة للتشغيلة، ثم تسجّل الدخول معلّقاً جديداً لترى إجابات النموذج. وللاطلاع على ما يفعله كل جزء من الحلقة عموماً، راجع نظرة عامة على تدريب النماذج.
تثبيت Potato والمشروع النموذجي
يستخدم الدرس sklearn-text، وهو مُدرِّب يحوّل كل مراجعة إلى ميزات TF-IDF ويلائم مصنِّف انحدار لوجستي. لا يحتاج sklearn-text إلى تثبيت إضافي لأن scikit-learn من الاعتماديات الأساسية في Potato. يوجد المشروع النموذجي في مستودع Potato على GitHub لا في حزمة pip، فثبّت Potato واستنسخ المستودع:
pip install --upgrade potato-annotation
git clone https://github.com/davidjurgens/potato.git
cd potatoيُشغَّل كل أمر أدناه من جذر المستودع. يضم مجلد المشروع examples/ai-assisted/model-training/ ثلاثة ملفات:
config.yamlهو ملف تهيئة الدراسة، وتوجد أوامر هذا الدرس في تعليقاته.data/reviews.jsonيضم 160 مراجعة منتجات اصطناعية، في كل سطر كائن JSON يحملidوtext.data/gold.jsonيعطي التصنيف الصحيح لكل مراجعة. يجيب المحاكي من هذا الملف.
ملف التهيئة النموذجي
يعرّف ملف التهيئة مخططاً واحداً من نوع radio باسم sentiment وتصنيفين هما positive وnegative، ويفعّل تدريب النماذج. الكتلة أدناه هي الملف المشحون بعد حذف التعليقات، ويجتاز الملف الأمر python -m potato.validate_cli --strict من دون تعديل:
annotation_task_name: "Review Sentiment (model training demo)"
data_files:
- "data/reviews.json"
item_properties:
id_key: "id"
text_key: "text"
task_dir: "."
output_annotation_dir: "annotation_output"
require_password: false
admin_api_key: "demo-admin-key"
num_annotators_per_item: 1
annotation_schemes:
- annotation_type: "radio"
name: "sentiment"
description: "Is this review positive or negative?"
labels:
- "positive"
- "negative"
sequential_key_binding: true
model_training:
enabled: true
writeback:
schemas: ["sentiment"]
include_unlabeled: true
min_confidence: 0.6أربعة إعدادات تحدد مسار الدرس:
num_annotators_per_item: 1يعطي كل مراجعة تصنيفاً واحداً. وهكذا يغطي ثلاثة معلّقين محاكَين، لكل منهم 40 مراجعة، 120 مراجعة مختلفة ويتركون 40 مراجعة غير مصنّفة للنموذج.require_password: falseيتيح للمعلّق الجديد تسجيل الدخول باسم مستخدم وحده. وتسجّل الخطوة الأخيرة الدخول بهذه الطريقة.admin_api_key: "demo-admin-key"يفتح صفحات الإدارة. استبدل هذا المفتاح على أي خادم يستطيع آخرون الوصول إليه.model_trainingيسجّل مسارات/admin/training. وتعرض كتلةwritebackتنبؤات المخططsentimentعلى المعلّقين، ويشرح القسم الخاص بالكتابة الراجعة أدناه كل مفتاح فيها.
تشغيل الخادم على المنفذ 8000
شغّل Potato بملف التهيئة النموذجي:
potato start examples/ai-assisted/model-training/config.yaml -p 8000يحمّل الخادم المراجعات الـ160 ويخدم صفحة التعليق التوضيحي على http://localhost:8000. وإن كان المنفذ 8000 مشغولاً على جهازك، فأعطِ -p منفذاً آخر واستخدمه في كل عنوان URL أدناه.
تصنيف 120 مراجعة بالمحاكي
يحتاج النموذج إلى تصنيفات بشرية ليتعلم منها. ويقوم محاكي المستخدمين مقام ثلاثة معلّقين. يجيب كل معلّق محاكى من ملف gold ويصيب في معظم إجاباته. شغّل المحاكي في نافذة طرفية ثانية، من جذر المستودع:
python -m potato.simulator --server http://localhost:8000 --users 3 \
--strategy gold_standard --competence good=1.0 --max-annotations 40 \
--gold-file examples/ai-assisted/model-training/data/gold.json \
--sequential --fast-mode --no-exportيجعل --strategy gold_standard كل معلّق محاكى يجيب من gold.json، ويعطي --competence good=1.0 المعلّقين الثلاثة جميعاً الملف good في المحاكي. يسحب المعلّق good دقةً بين 0.80 و0.90 ويجيب كل مراجعة إجابة صحيحة بهذا الاحتمال. ولذلك تتضمن التصنيفات أخطاءً، كما تتضمن تصنيفات أي فريق حقيقي. يشغّل --sequential المعلّقين الثلاثة واحداً بعد الآخر، ويحذف --fast-mode الفواصل بين الإجابات، ويتجاوز --no-export كتابة ملفات نتائج المحاكي نفسها. ينتهي المحاكي في نحو ثانيتين بملخص. تأكد من أن الملخص يذكر Total annotations: 120 قبل أن تتابع. ويمكنك أيضاً تصنيف المراجعات يدوياً على http://localhost:8000. يرفض sklearn-text الملاءمة إذا كان في قسم train أقل من 10 عناصر مصنّفة.
فتح صفحة التدريب بمفتاح المسؤول
تحتاج صفحة التدريب إلى جلسة مسؤول. افتح http://localhost:8000/admin، وأدخل demo-admin-key حين تطلب الصفحة مفتاح API، ثم افتح http://localhost:8000/admin/training.
صفحة التدريب بعد تشغيلتين لـ sklearn-text على المشروع النموذجي
تضم لوحة Start a run في الأعلى الإعداد كله. يسرد Schema مخطط المشروع الوحيد، sentiment (radio). ويسرد Trainer المُدرِّبات الثمانية والثلاثين كلها، ويحمل المُدرِّب الذي لا يستطيع المشروع تشغيله سببه بجوار اسمه، مثل "not installed". تختار الصفحة sklearn-text متى كان sklearn-text مناسباً للمخطط. ويعرض Runs on الخلفية الوحيدة في المشروع، local (this machine).
تدريب sklearn-text
اترك Parameters فارغاً لتستخدم القيم الافتراضية للمُدرِّب، وانقر Train now. تحسم التشغيلة التعليقات إلى تصنيف واحد لكل مراجعة، وتقسّم المراجعات المصنّفة البالغ عددها 120 إلى مجموعات train وval وtest، وتلائم النموذج في عملية منفصلة. استغرقت تشغيلتنا 1.5 ثانية، وعرضت اللوحة "Run finished." عند انتهاء التشغيلة.
يستخدم sklearn-text افتراضياً TfidfVectorizer من scikit-learn للميزات، وLogisticRegression للمصنِّف. وحين يبلغ قسم train 50 عنصراً أو أكثر، يُجري sklearn-text أيضاً معايرة لثقة المصنِّف. تستخدم المعايرة تدريج Platt دون 1000 عنصر تدريب، والانحدار المتساوي ابتداءً من 1000 عنصر. ولا يُبقى على النموذج المعايَر إلا إذا كلّفت المعايرة دقة تدريب لا تزيد على 0.05. وللمعايرة أهمية هنا لأن خطوة الكتابة الراجعة تقارن ثقة كل تنبؤ بـmin_confidence.
لبدء التشغيلة نفسها من سكربت، أرسل مفتاح المسؤول في الترويسة X-API-Key:
curl -X POST -H "X-API-Key: demo-admin-key" -H "Content-Type: application/json" \
http://localhost:8000/admin/training/api/runs \
-d '{"trainer": "sklearn-text", "schemas": ["sentiment"]}'تحمل الاستجابة run_id الجديد و"started": true.
صفحة التشغيلة ودرجة العناصر المحجوزة
تظهر التشغيلة المنتهية في جدول التشغيلات مع حجمي train وval وعمود Held-out score. انقر معرّف التشغيلة لفتح صفحة التشغيلة في /admin/training/runs/<run_id>. تسرد صفحة التشغيلة حالتها والمُدرِّب والخلفية وأحجام الأقسام وبذرة التقسيم ودرجة العناصر المحجوزة والمعاملات، ثم جدولاً بكل مقياس وسجل التشغيلة.
تحجز التشغيلة افتراضياً 15% من العناصر المصنّفة لقسم val و15% لقسم test، ويحدد split_seed أي العناصر تقع في أي قسم. يبقى التقسيم ثابتاً من تشغيلة إلى أخرى ما دام split_seed محتفظاً بقيمته، فتُقاس تشغيلتان على التصنيفات نفسها على العناصر نفسها. درجة العناصر المحجوزة في تشغيلة sklearn-text هي macro-F1 على val. يأخذ macro-F1 متوسط درجة F1 لكل تصنيف، وهما هنا positive وnegative. وتسجّل التشغيلة أيضاً الدقة وmacro-F1 على test. أما الدقة على قسم train فتُسجَّل باسم train_accuracy ولا تُستخدم درجةً أبداً. وفي تشغيلتنا، جاء السجل هكذا:
[info] Read 76 labelled rows from the train split
[info] Applied sigmoid calibration over 5 folds
[info] Held-out val macro_f1: 0.725تذكر وثائق Potato نفسها تشغيلة واحدة على المشروع نفسه، ويضع الجدول تلك التشغيلة بجانب تشغيلتنا:
| وثائق Potato | تشغيلتنا | |
|---|---|---|
| المراجعات المصنّفة | 120 | 120 |
| عناصر train وval وtest | غير مذكورة | 76 و19 و25 |
| درجة العناصر المحجوزة (macro-F1 على val) | 0.84 | 0.725 |
| macro-F1 على test | غير مذكور | 0.826 |
| التصنيفات المسبقة المنشورة | 80 | 73 |
التنبؤات دون min_confidence | 4 | 11 |
ستختلف أرقامك عن العمودين كليهما، لأن كل معلّق محاكى يسحب دقة عشوائية ويخطئ في مواضع مختلفة. في تشغيلتنا، طابقت التصنيفات المحاكاة الملف gold.json في 97 مراجعة من 120، وفي 15 مراجعة من مراجعات val التسع عشرة. تقيس درجة العناصر المحجوزة الاتفاق مع تصنيفات معلّقيك لا مع أي مفتاح إجابات، فتخفض أخطاء المعلّقين في val الدرجة. وقد طابق كل تصنيف من التصنيفات المسبقة الثلاثة والسبعين التي نشرتها تشغيلتنا الملف gold.json. وفي دراسة حقيقية بلا ملف gold، اقرأ الدرجة المنخفضة سبباً لفحص اتفاق المعلّقين قبل لوم النموذج.
تفعيل الكتابة الراجعة للمخطط
لا تصل تنبؤات التشغيلة إلى المعلّقين إلا عبر الكتابة الراجعة. يفعّل ملف التهيئة النموذجي الكتابة الراجعة للمخطط sentiment سلفاً. وفي مشروعك أنت، أضف هذه الكتلة تحت model_training في ملف التهيئة وأعد تشغيل الخادم:
model_training:
enabled: true
writeback:
schemas: ["sentiment"]
include_unlabeled: true
min_confidence: 0.6يسمّي writeback.schemas المخططات التي يرى المعلّقون تنبؤاتها. القائمة فارغة افتراضياً، فلا يغيّر تفعيل التدريب شيئاً في صفحة التعليق التوضيحي حتى تسمّي مخططاً. ويجعل include_unlabeled: true كل تشغيلة تتنبأ بمراجعات لم يصنّفها أحد، إضافة إلى مراجعات val وtest. ومن دون include_unlabeled، لا تتنبأ التشغيلة إلا بمراجعات val وtest، وهذه المراجعات لها تصنيف بشري أصلاً. ويُبقي min_confidence: 0.6 التنبؤ بعيداً عن صفحة التعليق التوضيحي إذا نزلت ثقة النموذج دون 0.6. ويحتفظ Potato بالتنبؤ مع ذلك.
تعمل الكتابة الراجعة بعد كل تشغيلة ناجحة، وتتجاوز أي عنصر في قسم train للتشغيلة. في تشغيلتنا تنبأ النموذج بـ84 مراجعة (19 من val و25 من test والـ40 غير المصنّفة)، ونزل 11 تنبؤاً دون 0.6، ونشرت التشغيلة الـ73 الباقية. ويعطي الحقل writeback في GET /admin/training/api/status الأعداد نفسها، مع الملخص "Published 73 prediction(s) as prelabels." وتُكتب التنبؤات المخزّنة كتابةً راجعة من جديد عند بدء الخادم، فتبقى التصنيفات المسبقة بعد إعادة التشغيل. ولإزالة التصنيفات المسبقة لتشغيلة عن العناصر، أرسل DELETE /admin/training/api/runs/<run_id>/predictions.
تصنيف مسبق يراه معلّق جديد
افتح http://localhost:8000 في نافذة تصفح خاص وسجّل الدخول باسم مستخدم لم يستخدمه أحد، مثل newannotator. لكل مراجعة مصنّفة تصنيفها الواحد سلفاً، فيُسنَد إلى المعلّق الجديد المراجعات الـ40 غير المصنّفة، وقرأ عدّاد التقدم في تشغيلتنا 0/40. كانت مراجعتنا الأولى "The toaster: Disappointed, it stopped working within a week. Much smaller than the photos suggest." مع تحديد Negative مسبقاً بثقة 0.68.
مراجعة تُفتح وإجابة النموذج محددة، قبل أن يحفظ المعلّق شيئاً
لا يُحفظ التصنيف المسبق ما دام المعلّق يكتفي بالنظر إلى المراجعة، وتظل شارة الحالة تقرأ "Not labeled" إلى أن يحفظ المعلّق إجابة. وتصبح إجابة النموذج إجابة المعلّق حين يغيّر التحديد أو ينقر Next. في تشغيلتنا، فُتحت المراجعات الخمس غير المصنّفة التي نزل تنبؤها دون min_confidence من دون تحديد. أما المعلّق المستثنى من المساعدة الآلية بـai_support.holdout فلا يرى تصنيفات مسبقة على الإطلاق. تشدّ التصنيفات المسبقة المعلّقين نحو إجابة النموذج، فلا تفعّل الكتابة الراجعة إلا حين تكون درجة العناصر المحجوزة عالية بما يكفي للوثوق بها، وراقب المعلّقين الذين يقبلون كل تصنيف مسبق بالفحوص الواردة في الكشف عن التصنيفات المسبقة التي تُقبل دون تدقيق.
الخطوات التالية
يتيح المشروع نفسه بضع تجارب أخرى قبل أن تنتقل إلى بياناتك:
- غيّر معاملاً. اكتب
{"vectorizer_kwargs": {"ngram_range": [1, 2]}}في Parameters ودرّب مرة أخرى لإضافة أزواج الكلمات إلى الميزات. حقّقت تشغيلتنا الثانية بأزواج الكلمات 0.774 macro-F1 على val على التقسيم نفسه ونشرت 74 تصنيفاً مسبقاً. ويُرفض اسم المعامل الذي لا يقبلهsklearn-textمع قائمة الأسماء التي يقبلها المُدرِّب. - جرّب محوِّلاً. يتعلم
hf-text-classification(pip install "potato-annotation[train-text]") وsetfit(pip install "potato-annotation[embeddings]") المخطط نفسه، وتعطي صفحة المُدرِّبات معاملات كل مُدرِّب. - أغلق الحلقة. تضيف النموذج في الحلقة طابور المراجعة، وإعادة التدريب كلما وصلت تعليقات توضيحية بـ
auto_retrain، وحفظ تقسيم التشغيلة إصداراً من مجموعة بيانات. - انقل التدريب إلى GPU. يرسل التدريب على خادم GPU أو عنقود SLURM أو جهاز خلف NAT التشغيلات نفسها إلى جهاز آخر.
- درّب أنواعاً أخرى من النماذج. تتبع الدروس عن الضبط الدقيق للنماذج اللغوية الكبيرة ونماذج الرؤية ونماذج الصوت والنماذج العلمية الخطوات نفسها بمُدرِّبات ومخططات أخرى.
كل مفتاح استُخدم هنا مدرج في مرجع تهيئة تدريب النماذج. ابدأ أول تشغيلة في مشروعك بنسخ كتلة model_training أعلاه إلى ملف التهيئة وتسمية مخططك تحت writeback.schemas.