في التعلم الآلي، النموذج عبارة عن دالة ذات معلمات قابلة للتعلم تقوم بتعيين المدخلات إلى المخرجات. يتم الحصول على المعلمات المثالية من خلال تدريب النموذج على البيانات. سيوفر النموذج المدرب جيدًا تخطيطًا دقيقًا من المدخلات إلى المخرجات المطلوبة.
في TensorFlow.js هناك طريقتان لإنشاء نموذج التعلم الآلي:
- باستخدام Layers API حيث يمكنك إنشاء نموذج باستخدام الطبقات .
- استخدام Core API مع العمليات ذات المستوى الأدنى مثل
tf.matMul()
وtf.add()
وما إلى ذلك.
أولاً، سنلقي نظرة على Layers API، وهي واجهة برمجة تطبيقات ذات مستوى أعلى لبناء النماذج. ثم سنوضح كيفية بناء نفس النموذج باستخدام Core API.
إنشاء نماذج باستخدام Layers API
هناك طريقتان لإنشاء نموذج باستخدام Layers API: نموذج متسلسل ونموذج وظيفي . القسمان التاليان ينظران إلى كل نوع عن كثب.
النموذج المتسلسل
النوع الأكثر شيوعًا من النماذج هو النموذج Sequential
، وهو عبارة عن مجموعة خطية من الطبقات. يمكنك إنشاء نموذج Sequential
عن طريق تمرير قائمة الطبقات إلى الدالة sequential()
:
const model = tf.sequential({
layers: [
tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}),
tf.layers.dense({units: 10, activation: 'softmax'}),
]
});
أو عبر طريقة add()
:
const model = tf.sequential();
model.add(tf.layers.dense({inputShape: [784], units: 32, activation: 'relu'}));
model.add(tf.layers.dense({units: 10, activation: 'softmax'}));
هام: الطبقة الأولى في النموذج تحتاج إلى
inputShape
. تأكد من استبعاد حجم الدفعة عند توفيرinputShape
. على سبيل المثال، إذا كنت تخطط لتغذية موترات النموذج بالشكل[B, 784]
، حيث يمكن أن يكونB
بأي حجم دفعة، فحددinputShape
كـ[784]
عند إنشاء النموذج.
يمكنك الوصول إلى طبقات النموذج عبر model.layers
، وبشكل أكثر تحديدًا model.inputLayers
و model.outputLayers
.
النموذج الوظيفي
هناك طريقة أخرى لإنشاء LayersModel
وهي عبر الدالة tf.model()
. الفرق الرئيسي بين tf.model()
و tf.sequential()
هو أن tf.model()
يسمح لك بإنشاء رسم بياني عشوائي للطبقات، طالما أنها لا تحتوي على دورات.
فيما يلي مقتطف التعليمات البرمجية الذي يحدد نفس النموذج المذكور أعلاه باستخدام واجهة برمجة التطبيقات tf.model()
:
// Create an arbitrary graph of layers, by connecting them
// via the apply() method.
const input = tf.input({shape: [784]});
const dense1 = tf.layers.dense({units: 32, activation: 'relu'}).apply(input);
const dense2 = tf.layers.dense({units: 10, activation: 'softmax'}).apply(dense1);
const model = tf.model({inputs: input, outputs: dense2});
نسميه apply()
على كل طبقة من أجل توصيلها بمخرجات طبقة أخرى. نتيجة apply()
في هذه الحالة هي SymbolicTensor
، والتي تعمل مثل Tensor
ولكن دون أي قيم محددة.
لاحظ أنه على عكس النموذج المتسلسل، فإننا نقوم بإنشاء SymbolicTensor
عبر tf.input()
بدلاً من توفير inputShape
للطبقة الأولى.
يمكن أن يمنحك apply()
أيضًا Tensor
ملموسًا، إذا قمت بتمرير Tensor
ملموسًا إليه:
const t = tf.tensor([-2, 1, 0, 5]);
const o = tf.layers.activation({activation: 'relu'}).apply(t);
o.print(); // [0, 1, 0, 5]
يمكن أن يكون هذا مفيدًا عند اختبار الطبقات بشكل منفصل ورؤية مخرجاتها.
تمامًا كما هو الحال في النموذج المتسلسل، يمكنك الوصول إلى طبقات النموذج عبر model.layers
، وبشكل أكثر تحديدًا model.inputLayers
و model.outputLayers
.
تصديق
يعد كل من النموذج المتسلسل والنموذج الوظيفي مثيلين لفئة LayersModel
. أحد الفوائد الرئيسية للعمل مع LayersModel
هو التحقق من الصحة: فهو يفرض عليك تحديد شكل الإدخال وسيستخدمه لاحقًا للتحقق من صحة الإدخال الخاص بك. يقوم LayersModel
أيضًا بإجراء الاستدلال التلقائي للشكل أثناء تدفق البيانات عبر الطبقات. تتيح معرفة الشكل مسبقًا للنموذج إنشاء معلماته تلقائيًا، ويمكنه إخبارك ما إذا كانت الطبقتان المتتاليتان غير متوافقتين مع بعضهما البعض.
ملخص النموذج
اتصل بـ model.summary()
لطباعة ملخص مفيد للنموذج، والذي يتضمن:
- اسم ونوع جميع الطبقات في النموذج.
- شكل الإخراج لكل طبقة.
- عدد معلمات الوزن لكل طبقة.
- إذا كان النموذج يحتوي على طوبولوجيا عامة (موضحة أدناه)، فإن المدخلات التي تستقبلها كل طبقة
- إجمالي عدد المعلمات القابلة للتدريب وغير القابلة للتدريب للنموذج.
بالنسبة للنموذج الذي حددناه أعلاه، نحصل على الإخراج التالي على وحدة التحكم:
الطبقة (النوع) | شكل الإخراج | المعلمة # |
كثيفة_Dense1 (كثيفة) | [خالية، 32] | 25120 |
كثيف_Dense2 (كثيف) | [خالية، 10] | 330 |
إجمالي المعلمات: 25450 المعلمات القابلة للتدريب: 25450 المعلمات غير القابلة للتدريب: 0 |
لاحظ القيم null
في أشكال المخرجات للطبقات: تذكير بأن النموذج يتوقع أن يكون للمدخل حجم دفعة باعتباره البعد الخارجي، والذي يمكن أن يكون مرنًا في هذه الحالة بسبب القيمة null
.
التسلسل
إحدى الفوائد الرئيسية لاستخدام LayersModel
عبر واجهة برمجة التطبيقات ذات المستوى الأدنى هي القدرة على حفظ النموذج وتحميله. يعرف LayersModel
ما يلي:
- بنية النموذج، مما يسمح لك بإعادة إنشاء النموذج.
- أوزان النموذج
- تكوين التدريب (الخسارة، المحسن، المقاييس).
- حالة المحسن، مما يسمح لك باستئناف التدريب.
لحفظ نموذج أو تحميله، لا يلزمك سوى سطر واحد من التعليمات البرمجية:
const saveResult = await model.save('localstorage://my-model-1');
const model = await tf.loadLayersModel('localstorage://my-model-1');
يحفظ المثال أعلاه النموذج في وحدة التخزين المحلية في المتصفح. راجع model.save() documentation
ودليل الحفظ والتحميل لمعرفة كيفية الحفظ في وسائط مختلفة (مثل تخزين الملفات، IndexedDB
، وتشغيل تنزيل المتصفح، وما إلى ذلك)
طبقات مخصصة
الطبقات هي اللبنات الأساسية للنموذج. إذا كان النموذج الخاص بك يقوم بعملية حسابية مخصصة، فيمكنك تحديد طبقة مخصصة، والتي تتفاعل بشكل جيد مع بقية الطبقات. نحدد أدناه طبقة مخصصة تحسب مجموع المربعات:
class SquaredSumLayer extends tf.layers.Layer {
constructor() {
super({});
}
// In this case, the output is a scalar.
computeOutputShape(inputShape) { return []; }
// call() is where we do the computation.
call(input, kwargs) { return input.square().sum();}
// Every layer needs a unique name.
getClassName() { return 'SquaredSum'; }
}
لاختبار ذلك، يمكننا استدعاء apply()
بموتر ملموس:
const t = tf.tensor([-2, 1, 0, 5]);
const o = new SquaredSumLayer().apply(t);
o.print(); // prints 30
هام: إذا قمت بإضافة طبقة مخصصة، فستفقد القدرة على إجراء تسلسل للنموذج.
إنشاء نماذج باستخدام Core API
ذكرنا في بداية هذا الدليل أن هناك طريقتين لإنشاء نموذج التعلم الآلي في TensorFlow.js.
القاعدة العامة هي محاولة دائمًا استخدام واجهة برمجة التطبيقات للطبقات أولاً، نظرًا لأنه تم تصميمها على غرار واجهة برمجة تطبيقات Keras المعتمدة جيدًا والتي تتبع أفضل الممارسات وتقلل من الحمل المعرفي . توفر Layers API أيضًا العديد من الحلول الجاهزة مثل تهيئة الوزن، وتسلسل النماذج، والتدريب على المراقبة، وقابلية النقل، والتحقق من السلامة.
قد ترغب في استخدام Core API في أي وقت:
- أنت بحاجة إلى أقصى قدر من المرونة أو التحكم.
- لا تحتاج إلى إجراء تسلسل، أو يمكنك تنفيذ منطق التسلسل الخاص بك.
النماذج الموجودة في Core API هي مجرد وظائف تأخذ Tensors
واحدًا أو أكثر وتعيد Tensor
. يبدو نفس النموذج المكتوب أعلاه باستخدام Core API كما يلي:
// The weights and biases for the two dense layers.
const w1 = tf.variable(tf.randomNormal([784, 32]));
const b1 = tf.variable(tf.randomNormal([32]));
const w2 = tf.variable(tf.randomNormal([32, 10]));
const b2 = tf.variable(tf.randomNormal([10]));
function model(x) {
return x.matMul(w1).add(b1).relu().matMul(w2).add(b2).softmax();
}
لاحظ أننا في Core API مسؤولون عن إنشاء وتهيئة أوزان النموذج. كل وزن مدعوم Variable
يشير إلى TensorFlow.js أن هذه الموترات قابلة للتعلم. يمكنك إنشاء Variable
باستخدام tf.variable() وتمرير Tensor
موجود.
لقد تعرفت في هذا الدليل على الطرق المختلفة لإنشاء نموذج باستخدام الطبقات وواجهة برمجة التطبيقات الأساسية. بعد ذلك، راجع دليل نماذج التدريب لمعرفة كيفية تدريب النموذج.