1. مقدمة
ستدرّب في هذا الدرس التطبيقي نموذجًا لتقديم تنبؤات من البيانات الرقمية التي تصف مجموعة من السيارات.
سيوضح هذا التمرين الخطوات الشائعة لتدريب العديد من أنواع النماذج المختلفة، ولكنه سيستخدم مجموعة بيانات صغيرة ونموذجًا بسيطًا (ضحلًا). الهدف الأساسي هو مساعدتك في التعرّف على المصطلحات الأساسية والمفاهيم وبناء الجملة حول نماذج التدريب باستخدام TensorFlow.js وتوفير نقطة انطلاق لمزيد من الاستكشاف والتعلّم.
ولأننا ندرّب نموذجًا للتنبؤ بالأعداد المستمرة، يُشار إلى هذه المهمة أحيانًا باسم مهمة الانحدار. سنقوم بتدريب النموذج من خلال توضيح العديد من الأمثلة على المدخلات معه إلى جانب المخرجات الصحيحة. ويُشار إلى ذلك باسم التعلّم المُوجّه.
ما الذي ستقوم ببنائه
ستنشئ صفحة ويب تستخدم TensorFlow.js لتدريب نموذج في المتصفح. بما أن "القوة الحصانية" بالنسبة للسيارة، فسيتعلم النموذج التنبؤ "بالميل لكل غالون" (MPG).
للقيام بذلك، ستقوم بما يلي:
- قم بتحميل البيانات وإعدادها للتدريب.
- تحديد بنية النموذج.
- درِّب النموذج وراقب أدائه أثناء تدريبه.
- يمكنك تقييم النموذج المُدرَّب من خلال إجراء بعض التوقّعات.
المعلومات التي ستطّلع عليها
- أفضل الممارسات لإعداد البيانات لتعلُّم الآلة، بما في ذلك الترتيب العشوائي والتسوية.
- بنية TensorFlow.js لإنشاء نماذج باستخدام tf.layers API.
- كيفية مراقبة التدريب ضمن المتصفح باستخدام مكتبة tfjs-vis
المتطلبات
- إصدار حديث من Chrome أو أي متصفّح حديث آخر
- محرّر نصوص يعمل محليًا على جهازك أو على الويب من خلال برامج مثل Codepen أو Glitch
- معرفة HTML وCSS وJavaScript وChrome DevTools (أو أدوات مطوري البرامج للمتصفحات المفضلة لديك).
- فهم نظري عالي المستوى للشبكات العصبية. إذا كنت بحاجة إلى مقدمة أو تنشيط للذاكرة، يمكنك مشاهدة هذا الفيديو من قناة 3blue1brown أو هذا الفيديو حول التعلم المتعمق بلغة JavaScript من إعداد "آشي كريشنان".
2. الإعداد
إنشاء صفحة HTML وتضمين JavaScript
انسخ الرمز التالي إلى ملف HTML باسم
index.html
<!DOCTYPE html>
<html>
<head>
<title>TensorFlow.js Tutorial</title>
<!-- Import TensorFlow.js -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@2.0.0/dist/tf.min.js"></script>
<!-- Import tfjs-vis -->
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
</head>
<body>
<!-- Import the main script file -->
<script src="script.js"></script>
</body>
</html>
أنشئ ملف JavaScript للرمز البرمجي
- في المجلد نفسه الذي يضم ملف HTML أعلاه، أنشئ ملفًا باسم script.js وضَع الرمز التالي فيه.
console.log('Hello TensorFlow');
تجربة الميزة
الآن بعد الانتهاء من إنشاء ملفات HTML وJavaScript، جرِّبها. افتح ملف index.html في المتصفح وافتح وحدة التحكم في أدوات dev.
إذا كان كل شيء يعمل، فمن المفترض أن يكون هناك متغيران عموميان تم إنشاؤهما وإتاحتها في وحدة تحكم أدوات مطوّري البرامج.
tf
هو مرجع إلى مكتبة TensorFlow.js.tfvis
هو مرجع لمكتبة tfjs-vis
افتح أدوات المطوّرين في المتصفّح، ومن المفترَض أن تظهر لك رسالة نصّها Hello TensorFlow
في نتائج وحدة التحكّم. إذا كان الأمر كذلك، فأنت جاهز للانتقال إلى الخطوة التالية.
3- تحميل بيانات الإدخال وتنسيقها وعرضها مرئيًا
كخطوة أولى، دعنا نحمّل وننسق ونصور البيانات التي نرغب في تطبيق النموذج عليها.
سنقوم بتحميل "السيارات" من ملف JSON استضفناه لك. يحتوي على العديد من الميزات المختلفة حول كل سيارة معينة. في هذا البرنامج التعليمي، نريد فقط استخراج البيانات حول القدرة الحصانية والأميال لكل غالون.
أضف الرمز التالي إلى
ملف واحد (script.js
)
/**
* Get the car data reduced to just the variables we are interested
* and cleaned of missing data.
*/
async function getData() {
const carsDataResponse = await fetch('https://storage.googleapis.com/tfjs-tutorials/carsData.json');
const carsData = await carsDataResponse.json();
const cleaned = carsData.map(car => ({
mpg: car.Miles_per_Gallon,
horsepower: car.Horsepower,
}))
.filter(car => (car.mpg != null && car.horsepower != null));
return cleaned;
}
سيؤدي هذا أيضًا إلى إزالة أي إدخالات ليس لها إما أميال لكل غالون أو قوة حصان محددة. ولنرسم هذه البيانات أيضًا في مخطط مبعثر لنرى كيف تبدو.
أضف الرمز التالي إلى أسفل
script.js
.
async function run() {
// Load and plot the original input data that we are going to train on.
const data = await getData();
const values = data.map(d => ({
x: d.horsepower,
y: d.mpg,
}));
tfvis.render.scatterplot(
{name: 'Horsepower v MPG'},
{values},
{
xLabel: 'Horsepower',
yLabel: 'MPG',
height: 300
}
);
// More code will be added below
}
document.addEventListener('DOMContentLoaded', run);
عند إعادة تحميل الصفحة من المفترض أن تظهر لك لوحة على الجانب الأيسر من الصفحة بها مخطط مبعثر للبيانات. من المفترض أن يبدو مماثلاً لهذا.
تُعرف هذه اللوحة باسم الحاجب وتتوفر من خلال tfjs-vis. إنه مكان مناسب لعرض التصورات.
بشكل عام عند التعامل مع البيانات، من الجيد إيجاد طرق لإلقاء نظرة على بياناتك وتنظيفها إذا لزم الأمر. في هذه الحالة، اضطررنا إلى إزالة إدخالات معيّنة من carsData
لا تحتوي على جميع الحقول المطلوبة. يمكن أن يمنحنا تصور البيانات فكرة عما إذا كانت هناك أي بنية للبيانات يمكن أن يتعلمها النموذج.
يتضح لنا من المخطط أعلاه أن هناك ارتباطًا سلبيًا بين القدرة الحصانية والميل في الغالون، أي أنه مع زيادة القدرة الحصانية، تحصل السيارات عمومًا على عدد أقل من الأميال لكل غالون.
وضع تصوّر للمهمة
ستبدو بيانات الإدخال لدينا الآن على النحو التالي.
...
{
"mpg":15,
"horsepower":165,
},
{
"mpg":18,
"horsepower":150,
},
{
"mpg":16,
"horsepower":150,
},
...
وهدفنا هو تدريب نموذج يأخذ رقمًا واحدًا، وهو القوة الحصانية، ويتعلّم كيفية التنبؤ برقم واحد، بالميل لكل غالون. تذكر أن التخطيط واحدًا لواحد، حيث سيكون مهمًا للقسم التالي.
سوف نستغّل هذه الأمثلة، كالقوة الحصانية ومعدّل الميل ميل في الغالون، إلى شبكة عصبية تتعلم من هذه الأمثلة معادلة (أو دالة) للتنبؤ بمقدار القوة الحصانية استنادًا إلى القوة الحصانية. يُطلق على هذا التعلُّم من الأمثلة التي لدينا إجابات صحيحة لها اسم التعلُّم المُوجّه.
4. تحديد بنية النموذج
سنكتب في هذا القسم تعليمات برمجية لوصف بنية النموذج. بنية النموذج هي مجرد طريقة رائعة للتعبير عن "الوظائف التي سيتم تشغيل النموذج عند تنفيذها"، أو بدلاً من ذلك، "ما الخوارزمية التي سيستخدمها نموذجنا لحساب إجاباته".
نماذج تعلُّم الآلة هي خوارزميات تأخذ مدخلات وتُنتج المخرجات. عند استخدام الشبكات العصبية، تكون الخوارزمية عبارة عن مجموعة من طبقات الخلايا العصبية ذات "الأوزان" (الأرقام) التي تحكم مخرجاتها. وتتعلم عملية التدريب القيم المثالية لتلك الأوزان.
أضِف الدالة التالية إلى
script.js
لتحديد بنية النموذج.
function createModel() {
// Create a sequential model
const model = tf.sequential();
// Add a single input layer
model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));
// Add an output layer
model.add(tf.layers.dense({units: 1, useBias: true}));
return model;
}
هذا هو واحد من أبسط النماذج التي يمكننا تعريفها في tensorflow.js، دعنا نقسم كل سطر قليلاً.
إنشاء مثيل للنموذج
const model = tf.sequential();
ينشئ هذا مثيلاً للعنصر tf.Model
. هذا النموذج هو sequential
لأنّ مدخلاته تتدفق مباشرةً إلى المخرجات. يمكن أن يكون للأنواع الأخرى من النماذج فروع، أو حتى عدة مدخلات ومخرجات، ولكن في كثير من الحالات ستكون نماذجك متسلسلة. تتميّز النماذج التسلسلية أيضًا بسهولة أكبر في الاستخدام.
إضافة طبقات
model.add(tf.layers.dense({inputShape: [1], units: 1, useBias: true}));
ويؤدي ذلك إلى إضافة طبقة إدخال إلى شبكتنا، والتي يتم توصيلها تلقائيًا بطبقة dense
مع وحدة مخفية واحدة. طبقة dense
هي نوع من الطبقات تضرب مدخلاتها في مصفوفة (تسمى القيم المرجحة) ثم تضيف رقمًا (يسمى التحيز) إلى النتيجة. بما أن هذه هي الطبقة الأولى في الشبكة، نحتاج إلى تحديد inputShape
. القيمة inputShape
هي [1]
لأنّ لدينا رقم 1
كإدخالنا (القوة الحصانية لسيارة معيّنة).
تحدد units
حجم مصفوفة الوزن في الطبقة. ويعني تعيينهما على 1 هنا أنه سيكون هناك ترجيح واحد لكل ميزة من ميزات إدخال البيانات.
model.add(tf.layers.dense({units: 1}));
الكود أعلاه ينشئ طبقة الإخراج لدينا. قمنا بتعيين units
على 1
لأننا نريد إخراج رقم 1
.
إنشاء مثيل
إضافة الرمز التالي إلى
run
الدالة التي حدّدناها سابقًا.
// Create the model
const model = createModel();
tfvis.show.modelSummary({name: 'Model Summary'}, model);
سيؤدي ذلك إلى إنشاء مثيل للنموذج وإظهار ملخص للطبقات في صفحة الويب.
5- تجهيز البيانات للتدريب
للحصول على مزايا أداء TensorFlow.js التي تجعل نماذج تعلُّم الآلة للتدريب عملية، نحتاج إلى تحويل بياناتنا إلى tensors. سنُجري أيضًا عددًا من عمليات التحويل على بياناتنا التي تمثّل أفضل الممارسات، وهي التشغيل العشوائي والتسوية.
أضف الرمز التالي إلى
ملف واحد (script.js
)
/**
* Convert the input data to tensors that we can use for machine
* learning. We will also do the important best practices of _shuffling_
* the data and _normalizing_ the data
* MPG on the y-axis.
*/
function convertToTensor(data) {
// Wrapping these calculations in a tidy will dispose any
// intermediate tensors.
return tf.tidy(() => {
// Step 1. Shuffle the data
tf.util.shuffle(data);
// Step 2. Convert data to Tensor
const inputs = data.map(d => d.horsepower)
const labels = data.map(d => d.mpg);
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
//Step 3. Normalize the data to the range 0 - 1 using min-max scaling
const inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = labelTensor.max();
const labelMin = labelTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
return {
inputs: normalizedInputs,
labels: normalizedLabels,
// Return the min/max bounds so we can use them later.
inputMax,
inputMin,
labelMax,
labelMin,
}
});
}
دعونا نحلل ما يحدث هنا.
ترتيب البيانات عشوائيًا
// Step 1. Shuffle the data
tf.util.shuffle(data);
هنا نجري ترتيبًا عشوائيًا للأمثلة التي سنمدها بخوارزمية التدريب. الترتيب العشوائي مهم لأنه عادةً أثناء التدريب يتم تقسيم مجموعة البيانات إلى مجموعات فرعية أصغر، تسمى الدفعات، ويتم تطبيق النموذج عليها. يساعد الترتيب العشوائي كل دفعة في الحصول على مجموعة متنوعة من البيانات عبر توزيع البيانات. وهذا يساعدنا على مساعدة النموذج في:
- عدم تعلم الأشياء التي تعتمد فقط على الترتيب الذي تم تغذية البيانات فيه
- عدم الحساسية للبنية في المجموعات الفرعية (على سبيل المثال، إذا رأت سيارات ذات القدرة الحصانية العالية فقط للنصف الأول من تدريبها، فقد تتعرف على علاقة لا تنطبق على باقي مجموعة البيانات).
التحويل إلى موتّرات
// Step 2. Convert data to Tensor
const inputs = data.map(d => d.horsepower)
const labels = data.map(d => d.mpg);
const inputTensor = tf.tensor2d(inputs, [inputs.length, 1]);
const labelTensor = tf.tensor2d(labels, [labels.length, 1]);
نُنشئ هنا صفيفَتين، إحداهما لأمثلة الإدخال (إدخالات القدرة الحصانية)، والأخرى لقيم المخرجات الحقيقية (التي تُعرف باسم التصنيفات في التعلّم الآلي).
ثم نحول كل بيانات صفيفة إلى متنسورة ثنائية الأبعاد. سيكون للمتسلل شكل [num_examples, num_features_per_example]
. لدينا هنا inputs.length
مثال ويحتوي كل مثال على ميزة إدخال 1
(القوة الحصانية).
تسوية البيانات
//Step 3. Normalize the data to the range 0 - 1 using min-max scaling
const inputMax = inputTensor.max();
const inputMin = inputTensor.min();
const labelMax = labelTensor.max();
const labelMin = labelTensor.min();
const normalizedInputs = inputTensor.sub(inputMin).div(inputMax.sub(inputMin));
const normalizedLabels = labelTensor.sub(labelMin).div(labelMax.sub(labelMin));
بعد ذلك، نطبّق أفضل الممارسات الأخرى لتدريب الآلة. نعمل على تسوية البيانات. نعمل هنا على تسوية البيانات في النطاق العددي 0-1
باستخدام التحجيم بالحد الأدنى والأقصى. تعتبر التسوية أمرًا مهمًا لأن العناصر الداخلية للعديد من نماذج التعلم الآلي التي ستقوم بإنشائها باستخدام tensorflow.js مصممة للعمل مع أرقام ليست كبيرة جدًا. النطاقات الشائعة لتسوية البيانات لتشمل 0 to 1
أو -1 to 1
ستحقق المزيد من النجاح في تدريب نماذجك إذا اعتادت على تسوية بياناتك ضمن نطاق معقول.
عرض البيانات وحدود التسوية
return {
inputs: normalizedInputs,
labels: normalizedLabels,
// Return the min/max bounds so we can use them later.
inputMax,
inputMin,
labelMax,
labelMin,
}
نريد الاحتفاظ بالقيم التي استخدمناها للتسوية أثناء التدريب حتى نتمكن من إلغاء تسوية المخرجات لإعادتها إلى مقياسنا الأصلي والسماح لنا بتسوية بيانات المدخلات المستقبلية بنفس الطريقة.
6- تدريب النموذج
من خلال إنشاء مثيل النموذج الخاص بنا وتمثيل بياناتنا في صورة متوترات، نجد كل شيء في المكان المناسب لبدء عملية التدريب.
انسخ الدالة التالية إلى
script.js
.
async function trainModel(model, inputs, labels) {
// Prepare the model for training.
model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ['mse'],
});
const batchSize = 32;
const epochs = 50;
return await model.fit(inputs, labels, {
batchSize,
epochs,
shuffle: true,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
}
دعنا نحلل هذا الأمر.
الاستعداد للتدريب
// Prepare the model for training.
model.compile({
optimizer: tf.train.adam(),
loss: tf.losses.meanSquaredError,
metrics: ['mse'],
});
يجب أن "تجميع" النموذج قبل تدريبه. ولتنفيذ ذلك، ينبغي لنا تحديد عدد من الأمور المهمة للغاية:
optimizer
: هذه هي الخوارزمية التي ستتحكّم في التعديلات على النموذج من خلال الاطّلاع على الأمثلة. هناك العديد من أدوات التحسين في TensorFlow.js. اخترنا هنا أداة تحسين الأداء "آدم" لأنه فعال جدًا من الناحية العملية ولا يتطلب أي تهيئة.loss
: دالة توضّح للنموذج مدى نجاحه في التعرّف على كل دفعة (مجموعات فرعية من البيانات) التي يعرضها النموذج. نستخدم هنا السمةmeanSquaredError
لمقارنة التوقّعات التي يُجريها النموذج بالقيم الصحيحة.
const batchSize = 32;
const epochs = 50;
بعد ذلك، نختار دُفعة واحدة كحزمة وعدد من الحقبات:
- تشير السمة
batchSize
إلى حجم المجموعات الفرعية من البيانات التي سيَظهرها النموذج في كل تكرار للتدريب. وتتراوح الأحجام الشائعة للدُفعات بين 32 و512. لا يوجد حجم دفعة مثالي لجميع المسائل، وتعد وصف الدوافع الرياضية لأحجام الدفعة المختلفة خارج نطاق هذا البرنامج التعليمي. - تشير السمة
epochs
إلى عدد المرّات التي سيتحقّق فيها النموذج من مجموعة البيانات الكاملة التي تقدّمها له. سوف نتناول 50 تكرارًا خلال مجموعة البيانات.
بدء رحلة القطار
return await model.fit(inputs, labels, {
batchSize,
epochs,
callbacks: tfvis.show.fitCallbacks(
{ name: 'Training Performance' },
['loss', 'mse'],
{ height: 200, callbacks: ['onEpochEnd'] }
)
});
model.fit
هي الدالة التي نستدعيها لبدء حلقة التدريب. إنها دالة غير متزامنة، لذلك نعدك بالوعد الذي قدمته لنا حتى يتمكن المتصل من تحديد وقت اكتمال التدريب.
ولمراقبة تقدّم التدريب، نمرّر بعض عمليات الاستدعاء إلى model.fit
. نستخدم tfvis.show.fitCallbacks
لإنشاء دوال ترسم رسومًا بيانية تشير إلى قيمة "الخسارة". و"mse" المقياس الذي حددناه سابقًا.
وضع كل العناصر معًا
علينا الآن استدعاء الدوال التي حدّدناها من دالة run
.
أضف الرمز التالي إلى أسفل
run
.
// Convert the data to a form we can use for training.
const tensorData = convertToTensor(data);
const {inputs, labels} = tensorData;
// Train the model
await trainModel(model, inputs, labels);
console.log('Done Training');
عند إعادة تحميل الصفحة، من المفترض أن تظهر الرسومات البيانية التالية بعد بضع ثوانٍ.
ويتم إنشاؤها بواسطة عمليات معاودة الاتصال التي أنشأناها سابقًا. وتعرض نسبة الخسارة والمليمتر المتساوية في المتوسط على مجموعة البيانات بأكملها في نهاية كل حقبة.
عند تطبيق أي نموذج، نريد رؤية انخفاض الخسارة. في هذه الحالة، ونظرًا لأن مقياسنا هو مقياس للخطأ، فإننا نريد أن نلاحظ انخفاضه أيضًا.
7. إجراء تنبؤات
والآن بعد أن تم تدريب النموذج، نريد إجراء بعض التنبؤات. لنقيّم النموذج من خلال رؤية ما يتنبأ به لنطاق موحد من الأعداد الحصانية المنخفضة إلى العالية.
أضِف الدالة التالية إلى ملف script.js.
function testModel(model, inputData, normalizationData) {
const {inputMax, inputMin, labelMin, labelMax} = normalizationData;
// Generate predictions for a uniform range of numbers between 0 and 1;
// We un-normalize the data by doing the inverse of the min-max scaling
// that we did earlier.
const [xs, preds] = tf.tidy(() => {
const xsNorm = tf.linspace(0, 1, 100);
const predictions = model.predict(xsNorm.reshape([100, 1]));
const unNormXs = xsNorm
.mul(inputMax.sub(inputMin))
.add(inputMin);
const unNormPreds = predictions
.mul(labelMax.sub(labelMin))
.add(labelMin);
// Un-normalize the data
return [unNormXs.dataSync(), unNormPreds.dataSync()];
});
const predictedPoints = Array.from(xs).map((val, i) => {
return {x: val, y: preds[i]}
});
const originalPoints = inputData.map(d => ({
x: d.horsepower, y: d.mpg,
}));
tfvis.render.scatterplot(
{name: 'Model Predictions vs Original Data'},
{values: [originalPoints, predictedPoints], series: ['original', 'predicted']},
{
xLabel: 'Horsepower',
yLabel: 'MPG',
height: 300
}
);
}
هناك بعض الأشياء التي يجب ملاحظتها في الدالة أعلاه.
const xsNorm = tf.linspace(0, 1, 100);
const predictions = model.predict(xsNorm.reshape([100, 1]));
ننشئ 100 "مثال" جديد لإدخالها على النموذج. model.predict هو الطريقة التي ندخل بها هذه الأمثلة في النموذج. يُرجى العِلم أنّه يجب أن يكون لهذه الأشكال شكلاً مشابهًا ([num_examples, num_features_per_example]
) عندما أجرينا التدريب.
// Un-normalize the data
const unNormXs = xsNorm
.mul(inputMax.sub(inputMin))
.add(inputMin);
const unNormPreds = predictions
.mul(labelMax.sub(labelMin))
.add(labelMin);
لإعادة البيانات إلى نطاقنا الأصلي (بدلاً من 0-1)، نستخدم القيم التي حسبناها أثناء التسوية، ولكن نعكس العمليات فحسب.
return [unNormXs.dataSync(), unNormPreds.dataSync()];
.dataSync()
هي طريقة يمكننا استخدامها للحصول على typedarray
من القيم المخزّنة في متنور. ويسمح لنا ذلك بمعالجة تلك القيم في لغة JavaScript العادية. هذه نسخة متزامنة من طريقة .data()
المفضّلة بشكل عام.
وأخيرًا نستخدم tfjs-vis لرسم البيانات الأصلية والتنبؤات من النموذج.
أضف الرمز التالي إلى
run
.
// Make some predictions using the model and compare them to the
// original data
testModel(model, data, tensorData);
يُرجى إعادة تحميل الصفحة من المفترض أن يظهر لك ما يلي بعد انتهاء النموذج من تدريبه.
تهانينا! لقد درّبت للتو نموذجًا بسيطًا للتعلم الآلي. وهو ينفذ حاليًا ما يُعرف باسم الانحدار الخطي الذي يحاول ملاءمة خط مع الاتجاه الوارد في بيانات الإدخال.
8. النقاط الرئيسية المستخلصة
تشمل خطوات تدريب أحد نماذج تعلُّم الآلة ما يلي:
صياغة مهمتك:
- هل هي مشكلة انحدار أم مشكلة تصنيف؟
- هل يمكن تحقيق ذلك من خلال التعلّم المُوجّه أو التعلّم غير المُوجّه؟
- ما شكل البيانات المدخلة؟ كيف ينبغي أن تبدو بيانات الإخراج؟
إعداد بياناتك:
- تنظيف البيانات وفحصها يدويًا بحثًا عن الأنماط عندما يكون ذلك ممكنًا
- ترتيب بياناتك عشوائيًا قبل استخدامها في التدريب
- قم بتسوية بياناتك في نطاق معقول للشبكة العصبية. عادةً ما تكون 0-1 أو -1-1 نطاقات جيدة للبيانات الرقمية.
- تحويل البيانات إلى متسابقات
إنشاء النموذج وتشغيله:
- حدِّد النموذج باستخدام
tf.sequential
أوtf.model
ثم أضِف طبقات إليه باستخدامtf.layers.*
. - اختَر محسِّنًا ( adam هو عادةً خيار جيد)، ومَعلمات مثل حجم الدُفعة وعدد الفترات.
- اختر دالة فقدان مناسبة لمشكلتك، ومقياس دقة للمساعدة في تقييم التقدم.
meanSquaredError
هي دالة الخسارة الشائعة في مسائل الانحدار. - راقِب التدريب لمعرفة ما إذا كانت الخسارة تنخفض.
تقييم النموذج
- اختر مقياس تقييم لنموذجك يمكنك مراقبته أثناء التدريب. بعد تدريبه، حاول إجراء بعض التنبؤات الاختبارية للحصول على فكرة عن جودة التنبؤ.
9. رصيد إضافي: إجراءات يمكن تجربتها
- تجربة تغيير عدد الفترات. كم عدد الفترات التي تحتاج إليها قبل أن يستقر الرسم البياني.
- تجربة زيادة عدد الوحدات في الطبقة المخفية.
- جرِّب إضافة المزيد من الطبقات المخفية بين الطبقة المخفية الأولى التي أضفناها وطبقة الإخراج النهائية. يجب أن تبدو التعليمات البرمجية لهذه الطبقات الإضافية على النحو التالي.
model.add(tf.layers.dense({units: 50, activation: 'sigmoid'}));
وأهم شيء جديد في هذه الطبقات المخفية هو أنها توفر دالة تنشيط غير خطية، وهي في هذه الحالة التفعيل السيني. لمزيد من المعلومات حول وظائف التفعيل، يمكنك الاطّلاع على هذه المقالة.
تحقق مما إذا كان بإمكانك جعل النموذج ينتج عنه مخرجات كما في الصورة أدناه.