تدريب نموذج المثال الثاني في TensorFlow.js
بعد بناء النموذج في المثال الثاني وتجهيز البيانات بالشكل المناسب،
تأتي المرحلة الأهم وهي مرحلة التدريب.
في هذه المرحلة يبدأ النموذج في تعديل أوزانه الداخلية
حتى يتعلّم العلاقة بين بيانات الإدخال والإخراج.
وتوضح الصفحة الأصلية أن هذه المرحلة لا تتوقف عند تشغيل التدريب فقط،
بل تمتد أيضًا إلى اختبار النموذج بعد التدريب
ورؤية ما الذي يتوقعه على قيم جديدة،
ثم مقارنة هذه النتائج بالبيانات الأصلية.
دالة التدريب Training Function
تبدأ الصفحة بتعريف دالة تدريب كاملة مسؤولة عن تشغيل
عملية التعلم داخل النموذج.
وتستقبل هذه الدالة:
- model وهو النموذج نفسه
- inputs وهي بيانات الإدخال بعد تجهيزها
- labels وهي القيم الصحيحة المقابلة
- surface وهو مكان عرض الرسوم أثناء التدريب
async function trainModel(model, inputs, labels, surface) {
const batchSize = 25;
const epochs = 100;
const callbacks = tfvis.show.fitCallbacks(surface, [\'loss\'], {callbacks:[\'onEpochEnd\']})
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle:true,
callbacks:callbacks
});
}ما معنى batchSize؟
في هذا المثال يتم تحديد:
const batchSize = 25;
والمقصود بذلك أن التدريب لا يتم على كل البيانات دفعة واحدة
في كل خطوة، بل يتم تقسيم البيانات إلى دفعات صغيرة،
كل دفعة تحتوي على 25 عنصرًا.
هذا يساعد على جعل التدريب أكثر تنظيمًا،
ويعطي النموذج فرصة للتعلم التدريجي بدلًا من معالجة
كل شيء مرة واحدة.
ما معنى epochs؟
تحدد الصفحة أيضًا:
const epochs = 100;
والمقصود بـ epochs هو عدد مرات
مرور النموذج الكامل على بيانات التدريب.
أي أن النموذج في هذا المثال يمر على البيانات
100 مرة أثناء عملية التعلم،
وفي كل مرة يحاول تحسين الأوزان وتقليل الخطأ.
دور model.fit()
الجزء الأساسي في الدالة هو:
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle:true,
callbacks:callbacks
});
هذه هي الدالة التي تنفذ التدريب فعليًا.
وفيها:
- inputs تمثل بيانات الإدخال
- labels تمثل القيم الصحيحة التي يجب أن يتعلمها النموذج
- shuffle: true تعني خلط البيانات أثناء التدريب
- callbacks تُستخدم لتحديث العرض الرسومي أثناء التعلم
وهذا يعني أن التدريب هنا لا يقتصر على تحسين الأوزان فقط،
بل يشمل أيضًا مراقبة ما يحدث أثناء عملية التعلم.
متابعة التدريب بصريًا
من النقاط المهمة في الصفحة أن المثال لا يدرّب النموذج بصمت،
بل يستخدم tfjs-vis لمتابعة النتائج بصريًا.
ولهذا يتم تعريف:
const callbacks = tfvis.show.fitCallbacks(surface, [\'loss\'], {callbacks:[\'onEpochEnd\']})
هذه الدالة تطلب من TensorFlow Visor تحديث الرسم
كلما انتهت دورة تدريبية، مع عرض قيمة واحدة أساسية هي:
loss
أي أن الصفحة تتابع كيف تنخفض قيمة الخطأ
مع تقدم التدريب من دورة إلى أخرى.
لماذا loss مهمة؟
قيمة loss تمثل مقدار الخطأ الحالي في النموذج.
وكلما انخفضت هذه القيمة، كان ذلك مؤشرًا على أن النموذج
أصبح أقرب إلى العلاقة الصحيحة بين البيانات.
ولهذا فإن مراقبة loss أثناء التدريب
تساعدنا على معرفة ما إذا كان النموذج يتحسن فعليًا أم لا.
اختبار النموذج بعد التدريب
بعد انتهاء التدريب، تنتقل الصفحة إلى جزء
Test the Model.
وتوضح أن النموذج بعد أن يتعلم لا بد أن يتم اختباره،
وذلك عبر فحص ما الذي يتوقعه على نطاق مختلف من القيم.
الهدف من هذه المرحلة هو التأكد من أن النموذج
لم يحفظ البيانات فقط، بل أصبح قادرًا على إنتاج
نتائج معقولة عندما نعطيه مدخلات جديدة.
فك التطبيع Un Normalize
توضح الصفحة نقطة مهمة جدًا قبل عرض النتائج:
البيانات كانت قد خضعت مسبقًا لعملية
Normalization،
ولذلك يجب الآن فك التطبيع
حتى يمكن قراءة النتائج بالمقياس الحقيقي.
let unX = tf.linspace(0, 1, 100);
let unY = model.predict(unX.reshape([100, 1]));
const unNormunX = unX.mul(inputMax.sub(inputMin)).add(inputMin);
const unNormunY = unY.mul(labelMax.sub(labelMin)).add(labelMin);
unX = unNormunX.dataSync();
unY = unNormunY.dataSync();في هذا الجزء:
- يتم إنشاء 100 قيمة إدخال موزعة بين 0 و1
- يتم تمريرها إلى النموذج باستخدام predict()
- ثم تُعاد هذه القيم إلى مقياسها الحقيقي باستخدام حدود البيانات الأصلية
هذا مهم لأن النتائج بعد التدريب تكون ما تزال
في المجال المطبّع، بينما نحن نريد فهمها
بالقيم الحقيقية التي تعبّر عن البيانات الأصلية.
استخدام predict()
في هذه المرحلة تستخدم الصفحة:
model.predict(unX.reshape([100, 1]))
وهذه الدالة تأخذ قيم الإدخال الجديدة
ثم تجعل النموذج ينتج القيم المتوقعة المقابلة لها.
وبما أن النموذج تعلّم مسبقًا من البيانات،
فمن المفترض أن تكون هذه القيم المتوقعة
قريبة من العلاقة الأصلية التي كان ينبغي عليه تعلمها.
تجهيز النتائج للرسم
بعد فك التطبيع، تعرض الصفحة كيفية تحويل النتائج المتوقعة
إلى مصفوفة من الكائنات حتى يمكن رسمها:
const predicted = Array.from(unX).map((val, i) => {
return {x: val, y: unY[i]}
});
هذا السطر يحوّل قيم الإدخال والإخراج إلى نقاط
في شكل:
- x لقيمة الإدخال
- y للقيمة التي توقعها النموذج
وبذلك تصبح النتائج جاهزة للعرض البصري.
رسم النتيجة النهائية
الخطوة الأخيرة هي عرض النتائج على الرسم،
بحيث يتم مقارنة البيانات الأصلية بما توقعه النموذج:
tfPlot([values, predicted], surface1)وهذا يعني أن الرسم النهائي يحتوي على سلسلتين:
- values وهي البيانات الأصلية
- predicted وهي القيم التي أنتجها النموذج
ومن خلال هذا الرسم يمكننا أن نرى هل تعلّم النموذج
العلاقة بين البيانات بشكل جيد أم لا.
ما الذي توضحه هذه الصفحة؟
هذه الصفحة مهمة لأنها تمثل الانتقال من
النموذج الجاهز إلى
النموذج المدرَّب والمختبَر.
وهي توضح أن تدريب النموذج لا يعني فقط استدعاء fit،
بل يشمل:
- تحديد حجم الدفعة batchSize
- تحديد عدد مرات المرور epochs
- متابعة loss أثناء التدريب
- اختبار النموذج على نطاق جديد من القيم
- فك التطبيع قبل قراءة النتائج
- رسم النتائج ومقارنتها بالبيانات الأصلية
وبذلك تعطي الصفحة صورة كاملة عن مرحلة التدريب
كما تحدث في مشروع تعلم آلة عملي.
الخلاصة
يوضح هذا الدرس أن تدريب نموذج
Example 2 في TensorFlow.js
يتم عبر دالة مخصصة تستخدم
model.fit()
مع batchSize = 25
وepochs = 100،
وتعرض تقدم التدريب بصريًا عبر
tfvis.show.fitCallbacks
من خلال متابعة loss.
ثم تنتقل الصفحة إلى اختبار النموذج باستخدام
predict() على قيم جديدة،
وفك التطبيع، ثم رسم النتائج النهائية
إلى جانب البيانات الأصلية لمقارنة أداء النموذج.
