12- كورس تعلم الذكاء الاصطناعي Machine Learning – التكرار

التعلّم في تعلم الآلة

في تعلم الآلة، لا يحدث التعلّم مرة واحدة، بل يتم عبر التكرار المستمر على البيانات. فالنموذج يمر على البيانات مرات متعددة، وفي كل مرة يقوم بتعديل القيم الداخلية الخاصة به حتى يقترب أكثر من الحل الأفضل. هذا هو جوهر عملية التعلّم: تحسين تدريجي يحدث خطوة بعد خطوة، وليس نتيجة فورية من أول محاولة. :

التعلّم هو التكرار Looping

توضح الصفحة الأصلية أن نموذج تعلم الآلة يتم تدريبه من خلال المرور المتكرر على البيانات. وفي كل دورة تدريبية أو Iteration يتم تعديل قيم الأوزان داخل النموذج. وعندما تصبح هذه التكرارات غير قادرة على تقليل قيمة الخطأ أكثر، نعتبر أن التدريب وصل إلى مرحلة مناسبة أو اقترب من أفضل نتيجة ممكنة. :

بمعنى أبسط: النموذج يبدأ بتخمين غير مثالي، ثم يحاول التحسن في كل مرة يمر فيها على البيانات، إلى أن يصل إلى خط أو نتيجة تناسب البيانات بشكل أفضل.

Gradient Descent

بعد ذلك تنتقل الصفحة إلى مفهوم Gradient Descent، وهو من أشهر الخوارزميات المستخدمة في حل مسائل الذكاء الاصطناعي وتحسين النماذج. وتستخدم الصفحة مثال الانحدار الخطي البسيط Linear Regression لتوضيح الفكرة بشكل عملي. :

الهدف في هذا المثال هو إيجاد أفضل خط مستقيم يمر بالقرب من مجموعة من النقاط ذات الإحداثيات (x, y). ورغم أن هذه المسألة يمكن حلها بصيغة رياضية مباشرة، فإن خوارزمية تعلم الآلة تستطيع أيضًا الوصول إلى الحل من خلال التعلّم التدريجي وتعديل القيم خطوة بخطوة. :

يبدأ النموذج من معادلة خطية بسيطة بالشكل التالي:

مثال:
y = wx + b

حيث يتم تعديل:

  • weight وهو ميل الخط
  • bias وهو نقطة التقاطع مع المحور

حتى يصبح الخط أكثر توافقًا مع النقاط الموجودة في الرسم. :

كائن Trainer

تعرض الصفحة بعد ذلك كائنًا برمجيًا باسم Trainer. وظيفته استقبال قيم x وy داخل مصفوفتين، ثم استخدام هذه البيانات في التدريب. كما يبدأ الكائن بقيمة وزن تساوي صفرًا، وقيمة انحياز تساوي 1، ويحتوي أيضًا على ثابت للتعلّم ومتغير لتخزين قيمة الخطأ.

مثال:
function Trainer(xArray, yArray) {

this.xArr = xArray;

this.yArr = yArray;

this.points = this.xArr.length;

this.learnc = 0.00001;

this.weight = 0;

this.bias = 1;

this.cost;

}

ومن هذا الكود نفهم أن:

  • xArr تخزن قيم الإدخال
  • yArr تخزن القيم الحقيقية المقابلة
  • points تمثل عدد النقاط
  • learnc هو ثابت التعلّم
  • weight يمثل ميل الخط
  • bias يمثل نقطة التقاطع
  • cost ستخزن قيمة الخطأ بعد التدريب

دالة التكلفة Cost Function

تشرح الصفحة أن الطريقة الشائعة في مسائل الانحدار هي استخدام Cost Function لقياس جودة الحل الحالي. فكلما انخفضت قيمة الخطأ، كان الخط الناتج أكثر ملاءمة للنقاط في الرسم.

تعتمد هذه الدالة على قيم weight وbias من المعادلة الخطية السابقة، ثم تحسب الفرق بين القيمة الحقيقية لكل نقطة وبين القيمة التي يتوقعها الخط. ويتم جمع هذه الفروقات بعد تربيعها، وذلك لضمان أن تكون القيم موجبة، ولأن هذا الأسلوب مناسب للاشتقاق الرياضي.

مثال:
this.costError = function() {

total = 0;

for (let i = 0; i < this.points; i++) {
total += (this.yArr[i] - (this.weight * this.xArr[i] + this.bias)) ** 2;
}
return total / this.points;
}
[/example_code]


المعادلة المستخدمة في الصفحة الأصلية موضحة في الصورة التالية: :



وتعني رموز المعادلة ما يلي: 

 	E تمثل الخطأ أو التكلفة
 	N هو عدد النقاط أو الملاحظات
 	y هي القيمة الحقيقية لكل نقطة
 	x هي قيمة المتغير أو الخاصية
 	m هو الميل أو الوزن
 	b هو التقاطع أو الانحياز
 	mx + b هي قيمة التنبؤ

وتذكر الصفحة أيضًا أن Cost Function يمكن أن يطلق عليها كذلك
دالة التدريب Train Function
بعد ذلك تعرض الصفحة دالة التدريب، وهي المسؤولة عن تنفيذ عملية Gradient Descent. ففي كل دورة تدريبية يتم تحديث القيم بحيث يتحرك النموذج نحو خط أقل خطأً وأكثر توافقًا مع البيانات. :contentReference[oaicite:12]{index=12}

"مثال:"
this.train = function(iter) {
for (let i = 0; i < iter; i++) {
this.updateWeights();
}
this.cost = this.costError();
}
تستقبل هذه الدالة عدد التكرارات iter، ثم تستدعي دالة تحديث الأوزان في كل مرة، وبعد انتهاء جميع الدورات تقوم بحساب قيمة الخطأ الحالية وتخزينها في cost. دالة تحديث الأوزان Update Weights Function هنا نصل إلى الخطوة الأهم في الصفحة، وهي تحديث كل من الوزن والانحياز. توضح الصفحة أن اتجاه الحركة يتم حسابه باستخدام مشتقات جزئية، ومن خلالها يعرف النموذج كيف يغيّر القيم لكي ينخفض الخطأ تدريجيًا. :
"مثال:"
this.updateWeights = function() {

let wx;

let w_deriv = 0;

let b_deriv = 0;
for (let i = 0; i < this.points; i++) {
wx = this.yArr[i] - (this.weight * this.xArr[i] + this.bias);
w_deriv += -2 * wx * this.xArr[i];
b_deriv += -2 * wx;
}

this.weight -= (w_deriv / this.points) * this.learnc;
this.bias -= (b_deriv / this.points) * this.learnc;
}
الفكرة هنا أن الكود: يحسب الفرق بين القيمة الحقيقية والتنبؤ الحالي يجمع تأثير هذا الفرق على الوزن والانحياز يحسب متوسط التغيير المطلوب يحدّث القيم باستخدام ثابت التعلّم learnc وبهذا يتحسن النموذج تدريجيًا بعد كل تكرار، إلى أن يقترب من أفضل خط ممكن للبيانات. :
"مثال:"
contentReference[oaicite:15]{index=15}
إنشاء مكتبتك الخاصة
في الجزء الأخير، تجمع الصفحة كل ما سبق داخل كود واحد كامل، بحيث يمكن حفظه في ملف JavaScript مستقل واستخدامه لاحقًا كمكتبة صغيرة في المشاريع. :contentReference[oaicite:16]{index=16}
مثال:function Trainer(xArray, yArray) {

this.xArr = xArray;

this.yArr = yArray;

this.points = this.xArr.length;

this.learnc = 0.00001;

this.weight = 0;

this.bias = 1;

this.cost;
this.costError = function() {

total = 0;

for (let i = 0; i < this.points; i++) {
total += (this.yArr[i] - (this.weight * this.xArr[i] + this.bias)) ** 2;
}
return total / this.points;
}

this.train = function(iter) {
for (let i = 0; i < iter; i++) {
this.updateWeights();
}
this.cost = this.costError();
}

this.updateWeights = function() {
let wx;
let w_deriv = 0;
let b_deriv = 0;
for (let i = 0; i < this.points; i++) {
wx = this.yArr[i] - (this.weight * this.xArr[i] + this.bias);
w_deriv += -2 * wx * this.xArr[i];
b_deriv += -2 * wx;
}
this.weight -= (w_deriv / this.points) * this.learnc;
this.bias -= (b_deriv / this.points) * this.learnc;
}
}
وبعد حفظ الكود في ملف مثل myailib.js يمكن تضمينه داخل صفحة HTML بهذه الطريقة: :
"مثال:"

الخلاصة

يوضح هذا الدرس أن التعلّم في تعلم الآلة يعتمد على التكرار المستمر، وأن النموذج لا يصل إلى الحل المثالي مباشرة، بل يتحسن تدريجيًا من خلال Gradient Descent. كما يشرح الدرس كائنًا عمليًا باسم Trainer يحتوي على Cost Function وTrain Function وUpdate Weights Function، وهو مثال مبسط يوضح كيف يمكن تدريب نموذج انحدار خطي لإيجاد أفضل خط يناسب البيانات.