سر الصنعة بين الأساس النظري والتطبيق
كما أن شراء كاميرا احترافية لن يجعل منك مصور واستعمال كالي لينكس لن يجعل منك خبير أمني كذلك فإن تغذية مدخلاتك إلى شبكة عصبونية Neural Network لن ينجح ولن يعطي النتيجة المرغوبة ولن يجعل منك عالم بيانات أو ذكاء صناعي.
في آخر مهمة لي عملت أكثر من أسبوع على تنظيف البيانات ثم قمت بتدريب الشبكة العصبونية لساعات فقط!
أساسيات نظرية قديمة لا تجعلها منسية
لقد حصل انفجار كبير في عالم الشبكات العصبونية والتعلم العميق في 2012 لكن الأساس النظري هو نفسه منذ زمن بعيد مثلا
في كتاب قديم من 1998 بعنوان Neural networks: tricks of the trade (هناك طبعة 1998 و 2003 و 2012 لعل بعضه متوفر هنا) هناك ورقة قديمة بعنوان Efficient backprop للعالم LeCun (ورقة مهمة جدا لدرجة أنها تجاوزت ال 2000 استشهاد citation) مما جاء فيها:
- حسنات ال stochastic learning مقارنة مع batch learning يعني تأخذ عينات عشوائية من المدخلات بدل أن تسير على كامل المدخلات في كل مرة.
- السرعة (لأنك تأخذ عينة صغيرة في كل مرة)
- تعميم أفضل (لأنه لا يملك كل المدخلات حتى يعمل over-fitting)
- اخلط العينات واختر عينات غنية بالمعلومات (لا تظل تكرر عينات من نفس الفئة وراء بعضها تأكد من أنها تعرض دائما بترتيب مختلف) أكثر من العينات التي تسبب لبس أكبر عند النموذج حتى يتعلم من أخطاؤه.
- تسوية المدخلات: إن كانت المدخلات على المحاور المختلفة لها وحدات قياس مختلفة وتدرجات مختلفة وحساسية مختلفة مثلا إن كنا نشخص مرض معين فإن ريادة 25% على على محور سكري الدم (الطبييعي في فحص الصائم هو 100 إلى 125 mg/dL) تختلف جذريا عن زيادة 25% في محور فيتامين B12 (قراءة بين 200 و ألف ng/mL تعتبر طبيعية). وإن كان عندنا محور للوزن بالكيلوغرام ومحور آخر للطول فبأي وحدة سم أم متر؟ يجب أن تجعل الحركة على المحاور متسقة وكأنها في فضاء واحد والحل هو استعمال العلامة العيارية standard score أو z-score وهي قسمة الإزاحة عن الوسط على الإنحراف المعياري. مثلا صفر تصبح تعني الوسط الحسابي للقراءات على ذلك المحور أما 1.25 مثلا فتعني أن القيمة أكبر من الوسط بمقدار انحراف عياري وربع. يقول LeCun يجب أن يكون
- الإزاحة: يجب أن يكون الوسط لكل متغير في المدخلات على أي من المحاور صفر أو قريب من الصفر.
- القياس: يجب أن تكون كل المتغيرات المختلفة لها نفس التباين variance
- الاستقلال (عدم الترابط): يجب أن تكون المدخلات عبر المحاور المختلفة غير مترابطة (يعني تجن أن يكون عندك محور ينتج من احتساب محورين آخرين)
- دوال عائلة ال sigmoid وهي تأخذ مدخلات في مجال لا محدود وتضعه في مدى محدود وهي نوعين نوع يعطي مخرجات من 0 إلى واحد وآخر يعطي مخرجات من -1 إلى 1 مثل ال tanh و LeCun يفضل هذا الأخير.
![]() |
عدد من دوال عائلة ال sigmoid |
- اجعل قيم المخرجات المتوقعة ضمن مخرجات الدالة مثلا بين -1 و 1 في حالة ال sigmoid
- إن اتبعت تسوية المدخلات المقترحة أعلاه يمكنك استهلال الأوزان من خلال قيم عشوائية وسطها الحسابي صفر وانحرافها المعياري هو مقلوب جذر m والذي هو عدد المدخلات في العصبون.
- معدل التعلم learning rate
- قلل قيمة معدل التعلم learning rate عندما تبدأ قيم الاوزان بالتذبذب وزدها أو ثبتها عندما تتستقر الأوزان
- يجب أن لا يكون معدل التعلم عاما بل لكل وزن له قيمته
- معدل التعلم يجب أن يتناسب مع جذر عدد المدخلات
- أوزان الطبقات الدنيا (الأقرب للمدخلات) يجب أن تكون أكبر من أوزان الطبقات العليا (الأقرب للمخرجات)
- استعمال الزخم momentum ومعدل التعلم المتكيف adaptive learning rate
- تعقيبي: هناك خوارزميات متكيفة مثل AdaDelta و AdaGrad و Adam و FtRL و RMSProp شاهدها هنا
نصائحي
- تعلم itertools فهي توفر الكثير من الذاكرة
- تعلم numpy فهي هي سريعة وباستعمالها يمكنك في بايثون وبكل سهولة سحق كل محاولات التحسين في سي/سي++ و rust
- تحصيل الجيد بما فيه كفاية أهم من مطاردة المثالية والصواب المطلق! في الصورة صحيح أن الخط الأحمر استطاع الفصل وتميز المثلثات من المربعات إلا أنه "بصيم" over-fitted أما الخط اﻷخضر وإن كان تجاوز بعض الأفراد عند الحدود إلا أنه أكثر قدرة على التعميم
- استعمل ال regulators مثل l1 وl2 أو كلاهما
- l1 يجبر الشبكة العصبونية على عمل feature selection
- استعمل ال drop-out layers لإجبار الشبكة على التعميم
- قم بتوسيع عينة التدريب من خلال معالجتها في وقت التنفيذ
- إضافة ضجيج عشوائي للمدخلات
- إن كانت صورة فيمكنك قص مناطق عشوائية منها random crop بشرط أن تظل تحتوي نسبة من المدخلات ويمكنك أيضا التلاعب عشوائيا بالألوان من حيث السطوع والإشباع اللوني.
- إن كانت سلاسل نصية يمكنك استبدال عدد من الكلمات عشوائيا ب "كذا" أو something (غالبا تسمى Out-of-vocabulary token)
- راقب ال confusion matrix ومتوسط ال recall و precision و f1 score
- مثلا إن كنت تعمل تشخيص لشيء نادر مثل مرض السرطان فلو عملت نموذج يقول أن كل الناس سليمين أو يختار 1 بالألف عشوائين كمصابين فإن دقة التشخيص ستكون عالية accuracy ليس لأن النموذج الذي صممته فعال (فهو غبي ولا ينظر للمدخلات) بل لأنه استغل الندرة. لكن لو كنت تستخدم معايير مثل f1-score ستكتشف هكذا دجل.
- تجنب المدخلات المسرحية staged input وحاول أن تكون مدخلاتك واقعية. مثلا من السهل أن تحصل دقة تزيد عن 99.9% في مسألة NIST Hand-written digits ليس لأنك ناجح في مهمة تمييز الأرقام لكن لأن تلك القاعدة معالجة ومعدة مسبقة بطريقة مسرحية فهي موسطة بالضبط ومقصوصة segmented ولها نفس القياس ...إلخ.
![]() |
صورة غير واقعية لسيارة تويوتا كورولا 2011 |
- تأكد من لخبطة ترتيب المدخلات في وقت التنفيذ إلى جانب وقت إنشاء الملف (سبق وذكرنا ذلك لكن للتأكيد)
- أحيانا تكون عنق الزجاجة في ال IO throughput تأكد من استمرارية ضخ البيانات للشبكة العصبونية مثلا
- ضع أكبر عدد ممكن من المدخلات في الرام إن كان هذا ممكنا
- أو استعمل صيغة ملفات سريعة مثلا لا تستعمل ملفات csv مباشرة (يمكنك مثلا استعمال msgpack أو protocol buffer مثل tfrecords)
- استعمل صيغ ملفات يمكن السير عليها دون تحميلها كلها دفعة واحدة مثلا jsonl وليس json
- لو كانت المدخلات نصية اجعل عملية التحويل إلى token ids عند الإعداد المسبق لتلك الملفات وليس في وقت التنفيذ.
- اجعل عدد الملفات من 5 إلى 50 ملف وحجم الملف بين 10 ميغا إلى 100 ميغا مثلا إن كان عندك 1 غيغا صور قسمها مثلا إلى 20 ملف كل ملف 50 ميغا وليس 1000 ملف كل ملف 1 ميغا.
- وجود عدد قليل من الملفات يمكنك من فتحها كلها دفعة واحدة وإعادة خلطها في وقت التنفيذ دون كلفة تذكر (من خلال قراءة عنصر واحد من ملف عشوائي من بينها)
- إن كنت تريد عمل oversample و undersample بشكل ديناميكي (حسب ال confusion matrix) يمكنك الاحتفاظ بكل فئة في ملف منفصل إلى جانب الملف الذي فيه كل الفئات وعندها تفتح ملف الفئة التي تريد تعمل لها oversample وتضخها إلى جانب بقية الفئات.
- افشل مبكرا وصحح خيرا من أن تؤخر الفشل. اختبر نماذج مبسطة على مسائل ذات صلة لكنها مبسطة قبل أن تتعامل مع المسألة المطلوبة.
- اعمل أدوات كي تستعرض محتويات الملفات (إن كنت حولتها لمعرفات حولها بالعكس واعرضها كنصوص) كذلك استعرض عينة عشوائية من السجلات التي ستجري التدريب عليها (كصور) وكذلك تحقق من عمليات ال preprocessing التي تعملها.
- استعرض عينة من المدخلات التي فشل النموذج في تخمينها لترى هل فشله مبرر (هل يمكنك أنت كأنسان تمييز كلب الهاسكي من الذئب؟).
- اعمل ادوات تفاعلية كي تجرب النموذج المدرب
- استعمل النقل المعرفي إن أمكن في الاستهلال.
- تصميم الشبكة العصبونية يجب أن يتناسب مع حجم المسألة فمثلا كثرة الأوزان وعمق الشبكة يعني أن الشبكة أكثر قدرة على "البصم" أو ال over-fitting وهذا سيء لأنها أقل قدرة على التعميم
- ادرس المئينات percentiles للمدخلات التي تعمل عليها ومنها الوسيط (المئين 50)
- قلنا سابقا أن الجيد كفاية أفضل من مطاردة المثالي! في أنظمة الاسترجاع لو أهملت أكثر الكلمات تكرارا لنقل ال 10% العليا (المئين 90) فإنك غالبا ستهمل أكثر من نصف الفهرس لكن في نفس الوقت لم تخسر شيء لأنها حروف جر وحشو. أيضا لو أهملت ال 10% الأقل تكرارا ستكون أهملت ذيل طويل جدا من الأخطاء الإملائية.
- عند تصميم CNN أو RNN يتعامل مع جمل عليك اختيار رقم ثابت ليكون عدد كلمات الجملة. في أحد التجارب كانت الجمل تصل إلى أكثر من 300 كلمة في بعض الأحيان! لكن المئين ال 99 كان 80 كلمة فقط (بمعنى لو اكتفيت ب 80 كلمة أكون غطيت أكثر من 99% من الحالات وفي نفس الوقت وفرت ثلاث أرباع الشبكة العصبونية وأبقيت ربعها)
هل يمكن تقديم نصائح عن كيفية البدأ الصحيح في مجال ال ML
ردحذف