في منشور المدونة هذا، سأوضح لك كيف صنعت خربش داش، لعبة ويب تعمل بالتعلم الآلي في الوقت الفعلي ويتم تشغيلها بالكامل في متصفحك (بفضل Transformers.js). الهدف من هذا البرنامج التعليمي هو توضيح مدى سهولة إنشاء لعبة ويب خاصة بك تعتمد على التعلم الآلي… في الوقت المناسب تمامًا لـ Open Source AI Game Jam القادم (7-9 يوليو 2023). انضم إلى مربى اللعبة إذا لم تكن قد قمت بذلك بالفعل!
روابط سريعة
ملخص
قبل أن نبدأ، دعونا نتحدث عن ما سنقوم بإنشائه. اللعبة مستوحاة من لعبة Google Quick, Draw! لعبة، حيث يتم إعطاؤك كلمة ويكون لدى الشبكة العصبية 20 ثانية لتخمين ما ترسمه (متكرر 6 مرات). في الواقع، سنستخدم بيانات التدريب الخاصة بهم لتدريب نموذج الكشف عن الرسومات الخاص بنا! ألا تحب المصادر المفتوحة فحسب؟ 😍
في نسختنا، سيكون لديك دقيقة واحدة لرسم أكبر عدد ممكن من العناصر، دفعة واحدة في كل مرة. إذا توقع النموذج التسمية الصحيحة، فسيتم مسح اللوحة وستحصل على كلمة جديدة. استمر في القيام بذلك حتى نفاد الموقت! نظرًا لأن اللعبة تعمل محليًا في متصفحك، فلا داعي للقلق بشأن زمن استجابة الخادم على الإطلاق. النموذج قادر على عمل تنبؤات في الوقت الفعلي أثناء الرسم، بما يصل إلى أكثر من 60 توقعًا في الثانية… 🤯 واو!
ينقسم هذا البرنامج التعليمي إلى 3 أقسام:
- تدريب الشبكة العصبية
- يعمل في المتصفح باستخدام Transformers.js
- تصميم اللعبة
1. تدريب الشبكة العصبية
بيانات التدريب
سنقوم بتدريب نموذجنا باستخدام مجموعة فرعية من Quick, Draw! مجموعة البيانات، والتي تحتوي على أكثر من 5 ملايين رسم عبر 345 فئة. فيما يلي بعض العينات من مجموعة البيانات:

العمارة النموذجية
سنقوم بالضبط الدقيق apple/mobilevit-small، وهو عبارة عن Vision Transformer خفيف الوزن وسهل الاستخدام للهاتف المحمول، وقد تم تدريبه مسبقًا على ImageNet-1k. يحتوي على 5.6 مليون معلمة فقط (حجم ملف يصل إلى 20 ميجا بايت تقريبًا)، وهو مرشح مثالي للتشغيل داخل المتصفح! لمزيد من المعلومات، راجع ورقة MobileViT وبنية النموذج أدناه.

الكون المثالى
لإبقاء منشور المدونة قصيرًا (نسبيًا)، قمنا بإعداد دفتر ملاحظات Colab الذي سيوضح لك الخطوات الدقيقة التي اتخذناها لتحسين apple/mobilevit-small على مجموعة البيانات لدينا. وعلى مستوى عالٍ، يتضمن ذلك ما يلي:
-
جارٍ تحميل “Quick, Draw!” dataset.
-
تحويل مجموعة البيانات باستخدام
MobileViTImageProcessor. -
تحديد وظيفة التجميع ومقياس التقييم.
-
تحميل نموذج MobileVIT المدرب مسبقًا باستخدام
MobileViTForImageClassification.from_pretrained. -
تدريب النموذج باستخدام
TrainerوTrainingArgumentsالطبقات المساعدة. -
تقييم النموذج باستخدام 🤗 التقييم.
ملحوظة: يمكنك العثور على نموذجنا الدقيق هنا على Hugging Face Hub.
2. يعمل في المتصفح باستخدام Transformers.js
ما هو Transformers.js؟
Transformers.js هي مكتبة جافا سكريبت تسمح لك بتشغيل 🤗 Transformers مباشرة في متصفحك (لا حاجة لخادم)! لقد تم تصميمه ليكون مكافئًا وظيفيًا لمكتبة Python، مما يعني أنه يمكنك تشغيل نفس النماذج المدربة مسبقًا باستخدام واجهة برمجة تطبيقات مشابهة جدًا.
خلف الكواليس، يستخدم Transformers.js ONNX Runtime، لذلك نحتاج إلى تحويل نموذج PyTorch المضبوط لدينا إلى ONNX.
تحويل نموذجنا إلى ONNX
لحسن الحظ، مكتبة 🤗 Optimum تجعل من السهل جدًا تحويل نموذجك المضبوط إلى ONNX! الطريقة الأسهل (والطريقة الموصى بها) هي:
-
انسخ مستودع Transformers.js وقم بتثبيت التبعيات الضرورية:
git clone https://github.com/xenova/transformers.js.git cd transformers.js pip install -r scripts/requirements.txt -
قم بتشغيل البرنامج النصي للتحويل (يستخدم
Optimumتحت غطاء محرك السيارة):python -m scripts.convert --model_id <model_id>أين
<model_id>هو اسم النموذج الذي تريد تحويله (على سبيل المثالXenova/quickdraw-mobilevit-small).
إعداد مشروعنا
لنبدأ ببناء تطبيق React بسيط باستخدام Vite:
npm create vite@latest doodle-dash -- --template react
بعد ذلك، أدخل دليل المشروع وقم بتثبيت التبعيات الضرورية:
cd doodle-dash
npm install
npm install @xenova/transformers
يمكنك بعد ذلك بدء تشغيل خادم التطوير عن طريق تشغيل:
npm run dev
تشغيل النموذج في المتصفح
يعد تشغيل نماذج التعلم الآلي أمرًا مكثفًا من الناحية الحسابية، لذا من المهم إجراء الاستدلال في سلسلة رسائل منفصلة. بهذه الطريقة لن نقوم بحظر الموضوع الرئيسي، والذي يُستخدم لعرض واجهة المستخدم والتفاعل مع إيماءات الرسم الخاصة بك 😉. تجعل واجهة برمجة تطبيقات Web Workers هذا الأمر بسيطًا للغاية!
قم بإنشاء ملف جديد (على سبيل المثال، worker.js) في src الدليل وأضف الكود التالي:
import { pipeline, RawImage } from "@xenova/transformers";
const classifier = await pipeline("image-classification", 'Xenova/quickdraw-mobilevit-small', { quantized: false });
const image = await RawImage.read('https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/blog/ml-web-games/skateboard.png');
const output = await classifier(image.grayscale());
console.log(output);
يمكننا الآن استخدام هذا العامل في منطقتنا App.jsx الملف عن طريق إضافة الكود التالي إلى App عنصر:
import { useState, useEffect, useRef } from 'react'
function App() {
const worker = useRef(null);
useEffect(() => {
if (!worker.current) {
worker.current = new Worker(new URL('./worker.js', import.meta.url), {
type: 'module'
});
}
const onMessageReceived = (e) => { };
worker.current.addEventListener('message', onMessageReceived);
return () => worker.current.removeEventListener('message', onMessageReceived);
});
}
يمكنك اختبار أن كل شيء يعمل عن طريق تشغيل خادم التطوير (مع npm run dev)، وزيارة موقع الويب المحلي (عادةً http://localhost:5173/)، وفتح وحدة تحكم المتصفح. يجب أن تشاهد إخراج النموذج الذي تم تسجيله في وحدة التحكم.
[{ label: "skateboard", score: 0.9980043172836304 }]
رائع! 🥳 على الرغم من أن الكود أعلاه ليس سوى جزء صغير من المنتج النهائي، إلا أنه يوضح مدى بساطة جانب التعلم الآلي منه! الباقي هو مجرد جعلها تبدو جميلة وإضافة بعض منطق اللعبة.
3. تصميم اللعبة
في هذا القسم، سأناقش بإيجاز عملية تصميم اللعبة. للتذكير، يمكنك العثور على الكود المصدري الكامل للمشروع على GitHub، لذلك لن أخوض في التفاصيل حول الكود نفسه.
الاستفادة من الأداء في الوقت الحقيقي
إحدى المزايا الرئيسية لإجراء الاستدلال داخل المتصفح هي أنه يمكننا إجراء تنبؤات في الوقت الفعلي (أكثر من 60 مرة في الثانية). في النسخة الأصلية Quick، Draw! في اللعبة، يقوم النموذج بإجراء تنبؤ جديد كل ثانيتين فقط. يمكننا أن نفعل الشيء نفسه في لعبتنا، ولكننا لن نستفيد من أدائها في الوقت الفعلي! لذلك، قررت إعادة تصميم حلقة اللعبة الرئيسية:
- بدلاً من ست جولات مدتها 20 ثانية (حيث تتوافق كل جولة مع كلمة جديدة)، يكلف إصدارنا اللاعب برسم أكبر عدد ممكن من رسومات الشعار المبتكرة بشكل صحيح في 60 ثانية (مطالبة واحدة في كل مرة).
- إذا صادفتك كلمة لا تستطيع رسمها، يمكنك تخطيها (لكن هذا سيكلفك 3 ثوانٍ من الوقت المتبقي).
- في اللعبة الأصلية، نظرًا لأن النموذج كان يقوم بالتخمين كل بضع ثوانٍ، فيمكنه حذف التسميات ببطء من القائمة حتى يتم التخمين بشكل صحيح في النهاية. في نسختنا، نقوم بدلاً من ذلك بتقليل درجات النموذج للأول
nتسميات غير صحيحة، معnتتزايد بمرور الوقت مع استمرار المستخدم في الرسم.
تحسينات نوعية الحياة
تحتوي مجموعة البيانات الأصلية على 345 فئة مختلفة، وبما أن نموذجنا صغير نسبيًا (حوالي 20 ميجابايت)، فإنه في بعض الأحيان يكون غير قادر على تخمين بعض الفئات بشكل صحيح. ولحل هذه المشكلة قمنا بإزالة بعض الكلمات وهي إما:
- مشابهة جدًا للتصنيفات الأخرى (على سبيل المثال، “حظيرة” مقابل “منزل”)
- من الصعب جدًا فهمها (على سبيل المثال، “هجرة الحيوانات”)
- من الصعب جدًا رسم تفاصيل كافية (على سبيل المثال، “الدماغ”)
- غامضة (على سبيل المثال، “الخفافيش”)
بعد التصفية، بقي لدينا أكثر من 300 فئة مختلفة!
المكافأة: الخروج بالاسم
انطلاقًا من روح التطوير مفتوح المصدر، قررت أن أطلب من Hugging Chat بعض أفكار أسماء الألعاب… وغني عن القول أن الأمر لم يخيب ظني!

أعجبني جناس “Doodle Dash” (الاقتراح رقم 4)، لذلك قررت أن أتبعه. شكرا معانقة الدردشة! 🤗
أتمنى أن تستمتع ببناء هذه اللعبة معي! إذا كان لديك أي أسئلة أو اقتراحات، يمكنك أن تجدني على تغريدأو GitHub أو 🤗 Hub. أيضًا، إذا كنت ترغب في تحسين اللعبة (أوضاع اللعبة؟ تعزيزات الطاقة؟ الرسوم المتحركة؟ المؤثرات الصوتية؟)، فلا تتردد في تقسيم المشروع وإرسال طلب سحب! أحب أن أرى ما توصلت إليه!
ملاحظة:: لا تنس الانضمام إلى Open Source AI Game Jam! نأمل أن يلهمك منشور المدونة هذا لبناء لعبة الويب الخاصة بك باستخدام Transformers.js! 😉 نراكم في Game Jam! 🚀