بدون شهادة دكتوراه من خلال TensorFlow وKeras والتعلّم المتعمق

1. نظرة عامة

تمّ تحديث هذا الدليل التعليمي لاستخدام Tensorflow 2.2 !.

74f6fbd758bf19e6.png

ستتعلم في هذا الدرس التطبيقي كيفية إنشاء وتدريب شبكة عصبية تتعرّف على الأرقام المكتوبة بخط اليد. وخلال مسيرتك، أثناء تحسين شبكتك العصبية لتحقيق دقة 99%، ستكتشف أيضًا الأدوات التجارية التي يستخدمها متخصّصو التعليم المعمّق لتدريب نماذجهم بكفاءة.

يستخدم هذا الدرس التطبيقي حول الترميز مجموعة بيانات MNIST، وهي مجموعة من 60,000 رقم مصنَّف حافظت على انشغال أجيال من شهادات الدكتوراه لمدة عقدَين تقريبًا. ستحل المشكلة باستخدام أقل من 100 سطر من رموز Python / TensorFlow.

ما ستتعرَّف عليه

  • ما هي الشبكة العصبية وكيف يتم تدريبها
  • كيفية بناء شبكة عصبية أساسية من طبقة واحدة باستخدام tf.keras
  • كيفية إضافة المزيد من الطبقات
  • كيفية إعداد جدول زمني لمعدّل التعلّم
  • كيفية إنشاء شبكات عصبية التفافية
  • كيفية استخدام أساليب التسوية: التسرب والتسوية على دفعات
  • ما هو فرط التخصيص؟

المتطلبات

مجرد متصفح. يمكن إدارة ورشة العمل هذه بالكامل باستخدام Google Colaboratory

الملاحظات

يُرجى إخبارنا بما إذا لاحظت أمرًا غير صحيح في هذا التمرين المعملي أو إذا كنت تعتقد أنه ينبغي تحسينه. نتعامل مع الملاحظات والآراء من خلال مشاكل GitHub [ feedback link].

2. دليل البدء السريع لخدمة Google Colaboratory

تستخدم هذه الميزة الاختبارية Google Colaboratory ولا تتطلّب أي إعداد من جانبك. ويمكنك تشغيلها من جهاز Chromebook. يُرجى فتح الملف أدناه وتنفيذ الخلايا للتعرّف على أوراق ملاحظات Colab.

c3df49e90e5a654f.png Welcome to Colab.ipynb

في ما يلي تعليمات إضافية:

اختيار واجهة خلفية لوحدة معالجة الرسومات

hsy7H7O5qJNvKcRnHRiZoyh0IznlzmrO60wR1B6pqtfdc8Ie7gLsXC0f670zsPzGsNy3QAJuZefYv9CwTHmjiMyywG2pTpnMCE6Slkf3K1BeVmfpsYVw6omItm1ZneqdE31F8re-dA

في قائمة Colab، اختَر وقت التشغيل >. غيِّر نوع بيئة التشغيل ثم اختَر "وحدة معالجة الرسومات". سيتم الاتصال ببيئة التشغيل تلقائيًا عند التنفيذ الأول، أو يمكنك استخدام الزر "اتصال" في أعلى الجانب الأيسر.

تنفيذ ورقة الملاحظات

evlBKSO15ImjocdEcsIo8unzEe6oDGYnKFe8CoHS_7QiP3sDbrs2jB6lbyitEtE7Gt_1UsCdU5dJA-_2IgBWh9ofYf4yVDE740PwJ6kiQwuXNOLkgktzzf0E_k5VN5mq29ZXI5wb7Q

نفِّذ الخلايا واحدة تلو الأخرى عن طريق النقر على خلية واستخدام Shift-ENTER. يمكنك أيضًا تشغيل ورقة الملاحظات بالكامل باستخدام "بيئة التشغيل" > تنفيذ الكل

جدول المحتويات

OXeYYbtKdLCNnw_xovSMeMwSdD7CL_w25EfhnpRhhhO44bYp3zZpU72J5tKaSuo8wpas0GK5B2sTBlIMiFmdGxFRQ9NmwJ7JIRYy5XtpWKQCPdxQVRPy_0J_LshGIKjtw8P9fXozaA

تحتوي جميع أوراق الملاحظات على جدول محتويات. يمكنك فتحه باستخدام السهم الأسود على اليمين.

الخلايا المخفية

GXTbXUO8xpPFKiGc6Q-cFwFHxHvOa105hHg3vk77EDpStyhU4AQMN3FYenbiBusHXUSk-yGXbRDcK-Cwx18XbDtyqB5WRr3_2jhnLvFxW8a7H_4cGvVDKrEMto_QxhfTeO0hwmrfng

لن تعرض بعض الخلايا إلا عناوينها. هذه ميزة خاصة بأوراق الملاحظات في Colab. يمكنك النقر مرّتين عليها لرؤية الرمز بداخلها، ولكن عادةً لا يكون ذلك مثيرًا للاهتمام. عادةً ما تكون دوال الدعم أو التصورات. لا تزال بحاجة إلى تشغيل هذه الخلايا حتى يتم تحديد الدوال داخلها.

3- تدريب شبكة عصبية

سوف نشاهد أولاً قطار الشبكة العصبونية. يُرجى فتح الدفتر أدناه واجتياز جميع الخلايا. لا تنتبه إلى التعليمة البرمجية الآن، سنبدأ في شرحها لاحقًا.

c3df49e90e5a654f.png keras_01_mnist.ipynb

أثناء تنفيذ دفتر الملاحظات، ركز على التصورات. انظر أدناه للاطّلاع على التفسيرات.

بيانات التدريب

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

ad83f98e56054737.png

تصنف الشبكة العصبية التي سننشئها الأرقام المكتوبة بخط اليد في فئاتها العشر (0، ..، 9). ويعتمد ذلك على المعلَمات الداخلية التي تحتاج إلى قيمة صحيحة للتصنيف ليعمل بشكل جيد. هذه "القيمة الصحيحة" من خلال عملية تدريب تتطلب "مجموعة بيانات مصنفة" مع الصور والإجابات الصحيحة المرتبطة بها.

كيف نعرف ما إذا كانت الشبكة العصبية المدربة تعمل بشكل جيد أم لا؟ سيكون استخدام مجموعة بيانات التدريب لاختبار الشبكة بمثابة الغش. وقد رأى بالفعل مجموعة البيانات هذه عدة مرات أثناء التدريب ومن المؤكد أنها فعالة للغاية فيها. نحتاج إلى مجموعة بيانات مصنفة أخرى، لم نرَها أثناء التدريب، لتقييم "العالم الحقيقي" أداء الشبكة. يُطلق عليها "مجموعة بيانات التحقق من الصحة"

التدريب

ومع تقدّم التدريب، يتمّ تعديل دُفعة واحدة من بيانات التدريب في كل مرة، ويتم تعديل مَعلَمات النموذج الداخلي، وتحسين أداء النموذج في التعرّف على الأرقام المكتوبة بخط اليد. يمكنك رؤية ذلك على الرسم البياني للتدريب:

3f7b405649301ea.png

على اليمين، تشير "الدقة" ببساطة هو النسبة المئوية للأرقام التي تم التعرف عليها بشكل صحيح. يرتفع مع تقدم التدريب، وهذا أمر جيد.

على اليمين، يمكننا مشاهدة "loss". لدفع التدريب، سنقوم بتعريف "الخسارة" التي تمثل مدى سوء تعرُّف النظام على الأرقام، ومحاولة خفضها. ما تراه هنا هو أن الخسارة تقل في كل من بيانات التدريب وبيانات التحقق من الصحة أثناء تقدم التدريب: هذا أمر جيد. وهذا يعني أن الشبكة العصبية تتعلم.

يمثل المحور س عدد "الحقبات" أو التكرارات عبر مجموعة البيانات بأكملها.

التوقّعات

عندما يتم تدريب النموذج، يمكننا استخدامه للتعرّف على الأرقام المكتوبة بخط اليد. يوضح التصور التالي مدى جودة أدائه على بضعة أرقام معروضة من الخطوط المحلية (السطر الأول) ثم على 10000 رقم من مجموعة بيانات التحقق من الصحة. تظهر الفئة المتنبأ بها أسفل كل رقم باللون الأحمر إذا كانت خاطئة.

c0699216ba0effdb.png

كما ترى، هذا النموذج الأولي ليس جيدًا للغاية ولكنه يتعرّف على بعض الأرقام بشكل صحيح. تبلغ دقة التحقق النهائية حوالي 90٪ وهي ليست سيئة للغاية بالنسبة للنموذج المبسط الذي نبدأ به، ولكن لا يزال يعني أنها تفقد 1000 رقم تحقق من أصل 10000. وهذا أكبر بكثير مما يمكن عرضه، ولهذا السبب يبدو أن جميع الإجابات خاطئة (أحمر).

أجهزة الاستشعار

يتم تخزين البيانات في مصفوفات. تتناسب صورة التدرج الرمادي بحجم 28×28 بكسل مع مصفوفة ثنائية الأبعاد بحجم 28×28. ولكن بالنسبة إلى صورة ملوّنة، نحتاج إلى المزيد من الأبعاد. هناك 3 قيم لون لكل بكسل (أحمر، أخضر، أزرق)، لذا ستحتاج إلى جدول ثلاثي الأبعاد بالأبعاد [28، 28، 3]. ولتخزين مجموعة مكونة من 128 صورة ملونة، نحتاج إلى جدول رباعي الأبعاد بالأبعاد [128، 28، 28، 3].

يُطلق على هذه الجداول متعددة الأبعاد اسم "tensors"، وقائمة أبعادها هي "الشكل".

4. [معلومات]: الشبكات العصبية 101

باختصار

إذا كانت جميع المصطلحات الغامقة في الفقرة التالية معروفة لك بالفعل، يمكنك الانتقال إلى التمرين التالي. إذا كنت في بداية مسيرتك في التعلم المتعمق، فمرحبًا بك، ونرجو مواصلة القراءة.

witch.png

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

model = tf.keras.Sequential([
    tf.keras.layers.Flatten(input_shape=[28, 28, 1]),
    tf.keras.layers.Dense(200, activation="relu"),
    tf.keras.layers.Dense(60, activation="relu"),
    tf.keras.layers.Dense(10, activation='softmax') # classifying into 10 classes
])

# this configures the training of the model. Keras calls it "compiling" the model.
model.compile(
  optimizer='adam',
  loss= 'categorical_crossentropy',
  metrics=['accuracy']) # % of correct answers

# train the model
model.fit(dataset, ... )

688858c21e3beff2.png

طبقة واحدة كثيفة

الأرقام المكتوبة بخط اليد في مجموعة بيانات MNIST هي صور بتدرج رمادي تبلغ 28×28 بكسل. وأبسط طريقة لتصنيفها هي استخدام وحدات بكسل 28x28=784 كمدخلات للشبكة العصبية المكونة من طبقة واحدة.

لقطة شاشة يوم 26-07-2016 في الساعة 12.32.24.png

تقوم كل "خلية عصبية" في أي شبكة عصبية بإجراء مجموع مرجّح لجميع مدخلاتها، ويضيف ثابتًا يسمى "التحيز" ثم خلاصات النتيجة من خلال بعض "دالة التفعيل" غير الخطية. "القيم المرجحة" و"التحيزات" هما مَعلمتان سيتم تحديدهما من خلال التدريب. يتم إعدادها بقيم عشوائية في البداية.

تمثل الصورة أعلاه شبكة عصبية مكونة من طبقة واحدة بها 10 خلايا عصبية المخرجات نظرًا لأننا نريد تصنيف الأرقام إلى 10 فئات (0 إلى 9).

باستخدام عملية ضرب المصفوفات

إليك كيف يمكن تمثيل طبقة الشبكة العصبية، التي تعالج مجموعة من الصور، بضرب المصفوفة:

matmul.gif

باستخدام أول عمود من الأوزان في مصفوفة الترجيحات W، نحسب المجموع المرجح لجميع وحدات البكسل في الصورة الأولى. يتجاوب هذا المجموع مع الخلية العصبية الأولى. باستخدام العمود الثاني من الأوزان، نفعل الشيء نفسه مع الخلية العصبية الثانية وهكذا حتى الخلية العصبية العاشرة. ويمكننا بعد ذلك تكرار العملية للصور الـ 99 المتبقية. إذا استدعينا المصفوفة التي تحتوي على 100 صورة، تكون جميع المبالغ المُرجحة للخلايا العصبية العشرة المحسوبة على 100 صورة هي X.W، وهو ناتج ضرب المصفوفة.

يجب أن تضيف كل خلية عصبية الآن تحيزها (ثابت). نظرًا لأن لدينا 10 خلايا عصبية، فإن لدينا 10 ثوابت تحيز. سنسمي هذا الخط المتجه المكون من 10 قيم b. يجب إضافتها إلى كل سطر من المصفوفة المحسوبة سابقًا. استخدام القليل من السحر يسمى "البث" سنكتب ذلك بعلامة زائد بسيطة.

نُطبق أخيرًا دالة تفعيل، مثل "softmax". (كما هو موضح أدناه) والحصول على المعادلة التي تصف شبكة عصبية مكونة من طبقة واحدة، مطبقة على 100 صورة:

لقطة شاشة يوم 26-07-2016 في الساعة 16.02.36.png

In Keras

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

tf.keras.layers.Dense(10, activation='softmax')

الاطّلاع على التفاصيل

من السهل سلسلة طبقات الشبكة العصبونية. تحسب الطبقة الأولى المجاميع المُرجّحة للبكسل. وتحسب الطبقات اللاحقة المجاميع المرجحة لمخرجات الطبقات السابقة.

fba0638cc213a29.png

الاختلاف الوحيد، بغض النظر عن عدد الخلايا العصبية، هو اختيار وظيفة التفعيل.

دوال التفعيل: relu وsoftmax وsigmoid

ستستخدم عادةً علامة "relu" وظيفة التفعيل لجميع الطبقات ما عدا الأخيرة. أما الطبقة الأخيرة في أي مُصنِّف، فقد تستخدم "softmax" التفعيل.

644f4213a4ee70e5.png

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

يُطلق على دالة التفعيل الأكثر شيوعًا اسم "RELU" للوحدة الخطية المصحَّحة. إنها دالة بسيطة للغاية كما ترون في الرسم البياني أعلاه.

وكانت وظيفة التفعيل التقليدية في الشبكات العصبية هي الوظيفة "سينية" لكن "relu" يحتوي على خصائص تقارب أفضل في كل مكان تقريبًا، ويفضل الآن.

41fc82288c4aff5d.png

تفعيل Softmax للتصنيف

تحتوي الطبقة الأخيرة من الشبكة العصبية على 10 خلايا عصبية لأننا نريد تصنيف الأرقام المكتوبة بخط اليد إلى 10 فئات (0،..9). يجب أن يكون الناتج 10 أرقام بين 0 و1 تمثّل احتمالية أن يكون هذا الرقم 0 أو 1 أو 2 وهكذا. ولهذا السبب، سنستخدم في الطبقة الأخيرة دالة تفعيل تُسمّى "softmax".

يتم تطبيق softmax على متجه من خلال أخذ الأس لكل عنصر ثم تسوية الخط المتجه، عادةً عن طريق قسمته على "L1". (أي مجموع القيم المطلقة) بحيث تضيف القيم التي تمت تسويتها ما يصل إلى 1 ويمكن تفسيرها على أنها احتمالات.

أحيانًا ما يُطلق على ناتج الطبقة الأخيرة قبل التفعيل اسم "logits". إذا كان هذا المتجه هو L = [L0، L1، L2، L3، L4، L5، L6، L7، L8، L9]، فعندئذٍ:

ef0d98c0952c262d.png d51252f75894479e.gif

الخسارة العابرة للإنتروبيا

والآن بعد أن تُنتج شبكتنا العصبية تنبؤات من الصور المدخلة، نحتاج إلى قياس مدى جودتها، أي المسافة بين ما تخبرنا به الشبكة والإجابات الصحيحة، والتي تُعرف غالبًا باسم "التصنيفات". تذكر أن لدينا التسميات الصحيحة لجميع الصور في مجموعة البيانات.

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

6dbba1bce3cadc36.png

انحدار التدرج

"تدريب" الشبكة العصبية تعني في الواقع استخدام صور وتسميات التدريب لضبط الأوزان والتحيزات وذلك لتقليل وظيفة فقدان بين القصور. إليك طريقة عملها.

القصور عبري هو دالة الأوزان والتحيزات ووحدات البكسل للصورة التطبيقية وفئتها المعروفة.

إذا احتسبنا المشتقات الجزئية للإنتروبيا المتداخلة نسبيًا مع جميع معاملات الترجيح وجميع الانحيازات التي حصلنا عليها على "تدرج"، محسوبًا لصورة معينة وتصنيفها والقيمة الحالية للأوزان والانحرافات. تذكر أنه يمكن أن يكون لدينا ملايين الأوزان والتحيزات، وبالتالي فإن حساب التدرج يشبه الكثير من العمل. لحسن الحظ، تُجري TensorFlow تنفيذ هذه الإجراءات نيابةً عنا. الخاصية الرياضية للتدرج هي أنه يشير إلى "لأعلى". وبما أننا نريد أن نتجه إلى حيث يكون القصور المشترك منخفضًا، فإننا نسير في الاتجاه المعاكس. ونقوم بتحديث الأوزان والتحيزات بجزء من التدرج. ثم نكرر الأمر نفسه مرارًا وتكرارًا باستخدام المجموعات التالية من صور التدريب والتصنيفات في حلقة تدريب. ونأمل أن يتلاءم هذا مع مكان يكون فيه القصور عبر الحد الأدنى هو الحد الأدنى، على الرغم من أنه لا يوجد شيء يضمن أن هذا الحد الأدنى فريد من نوعه.

خوارزمية انحدار التدرج2.png

التوزيع الدقيق والزخم

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

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

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

cc544924671fa208.png

صورة توضيحية: نقطة سرج. التدرج هو 0 ولكنه ليس حدًا أدنى في جميع الاتجاهات. (إسناد الصور Wikimedia: من Nicoguaro - عملك الخاص، CC BY 3.0)

الحل هو إضافة بعض الزخم إلى خوارزمية التحسين بحيث يمكنها تجاوز نقاط السرج بدون توقف.

مسرد المصطلحات

دفعة أو دفعة صغيرة: يتم دائمًا إجراء التدريب على دُفعات من بيانات التدريب والتصنيفات. ويساعد ذلك في تقارب الخوارزمية. "الدُفعة" هو البعد الأول لمعرضات البيانات. على سبيل المثال، يحتوي متفرع الشكل [100، 192، 192، 3] على 100 صورة بحجم 192×192 بكسل مع ثلاث قيم لكل بكسل (RGB).

خسارة الإنتروبيا: دالة خسارة خاصة غالبًا ما تُستخدم في المصنِّفات.

الطبقة الكثيفة: طبقة من الخلايا العصبية التي تتصل فيها كل خلية عصبية بجميع الخلايا العصبية في الطبقة السابقة.

الميزات: يُطلق على مدخلات الشبكة العصبية أحيانًا اسم "الميزات". يسمى فن معرفة أي أجزاء من مجموعة البيانات (أو مجموعات من الأجزاء) للتغذية في الشبكة العصبية للحصول على تنبؤات جيدة باسم "هندسة الخصائص".

labels: اسم آخر لـ "classes" الإجابات الصحيحة أو الإجابات الصحيحة في مشكلة تصنيف خاضعة للإشراف

معدّل التعلّم: جزء من التدرج يتم من خلاله تعديل الأوزان والانحيازات في كل تكرار في حلقة التدريب.

logits: تسمى مخرجات طبقة الخلايا العصبية قبل تطبيق دالة التفعيل باسم "logits". يأتي المصطلح من "الدالة اللوجستية" يُعرف أيضًا باسم "الدالة السينية" التي كانت أكثر وظائف التفعيل شيوعًا. "المخرجات العصبية قبل الدالة اللوجستية" تم اختصارها إلى "logits".

الخسارة: دالة الخطأ التي تقارن مخرجات الشبكة العصبونية بالإجابات الصحيحة

الخلية العصبونية: تحسب المجموع المرجّح لمدخلاتها وتضيف انحيازًا وتغذي النتيجة من خلال إحدى وظائف التفعيل.

ترميز واحد فعال: يتم ترميز الفئة 3 من 5 كمتجه مكون من 5 عناصر، جميع الأصفار باستثناء الصف الثالث وهو 1.

relu: وحدة خطية مُصحَّحة وظيفة تفعيل شائعة للخلايا العصبية.

sigmoid: دالة تفعيل أخرى كانت شائعة ولا تزال مفيدة في حالات خاصة.

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

tenor: "تينسور" يشبه المصفوفة ولكن بعدد عشوائي من الأبعاد. المتسلل أحادي البعد هو متجه. والمتسلل الثنائي الأبعاد هو مصفوفة. ومن ثم يمكنك الحصول على متسابقات ذات أبعاد 3 أو 4 أو 5 أو أكثر.

5- لننتقل إلى التعليمات البرمجية

بالعودة إلى دفتر الدراسة، وهذه المرة، هيا نقرأ التعليمة البرمجية.

c3df49e90e5a654f.png keras_01_mnist.ipynb

لنستعرض كل الخلايا في هذا الدفتر.

الخلية "المَعلمات"

يتم تحديد حجم الدُفعة وعدد فترات التدريب وموقع ملفات البيانات هنا. تتم استضافة ملفات البيانات في حزمة Google Cloud Storage (GCS)، ولهذا السبب يبدأ عنوانها بـ gs://.

الخلية "عمليات الاستيراد"

يتم استيراد جميع مكتبات بايثون اللازمة هنا، بما في ذلك TensorFlow وmatplotlib للتصورات.

الخلية "أدوات التصورات [RUN ME]****"

تحتوي هذه الخلية على رمز تصوير غير مثير للاهتمام. يتم تصغيرها تلقائيًا ولكن يمكنك فتحها وإلقاء نظرة على الرمز عندما يكون لديك الوقت عن طريق النقر مرّتين عليه.

الخلية "tf.data.Dataset: تحليل الملفات وإعداد مجموعات بيانات التدريب والتحقق من الصحة"

استخدمت هذه الخلية واجهة برمجة التطبيقات tf.data.Dataset API لتحميل مجموعة بيانات MNIST من ملفات البيانات. ليس من الضروري قضاء الكثير من الوقت في هذه الخلية. إذا كنت مهتمًا بواجهة برمجة التطبيقات tf.data.Dataset API، يمكنك الاطّلاع على هذا الدليل التوجيهي: مسارات بيانات سرعة TPU. في الوقت الحالي، الأساسيات هي:

يتم تخزين الصور والتصنيفات (الإجابات الصحيحة) من مجموعة بيانات MNIST في سجلات ذات طول ثابت في 4 ملفات. يمكن تحميل الملفات باستخدام وظيفة السجلّ الثابت المخصّصة:

imagedataset = tf.data.FixedLengthRecordDataset(image_filename, 28*28, header_bytes=16)

لدينا الآن مجموعة بيانات تضم وحدات بايت الصورة. ويجب فك ترميزها لتحويلها إلى صور. نحدد دالة للقيام بذلك. لا يتم ضغط الصورة، وبالتالي لا تحتاج الدالة إلى فك ترميز أي عنصر (لا يفعل decode_raw أي إجراء أساسي). ويتم بعد ذلك تحويل الصورة إلى قيم النقطة العائمة بين 0 و1. ويمكننا إعادة تشكيلها هنا كصورة ثنائية الأبعاد، ولكننا في الواقع نحتفظ بها كمصفوفة مسطحة من وحدات البكسل بحجم 28*28 لأن هذا هو ما تتوقعه الطبقة الكثيفة الأولية.

def read_image(tf_bytestring):
    image = tf.io.decode_raw(tf_bytestring, tf.uint8)
    image = tf.cast(image, tf.float32)/256.0
    image = tf.reshape(image, [28*28])
    return image

نطبق هذه الدالة على مجموعة البيانات باستخدام .map ونحصل على مجموعة بيانات تضم صورًا:

imagedataset = imagedataset.map(read_image, num_parallel_calls=16)

ونحن نطبق نفس النوع من قراءة وفك الترميز للتصنيفات، ونتعامل مع .zip الصور والتصنيفات معًا:

dataset = tf.data.Dataset.zip((imagedataset, labelsdataset))

لدينا الآن مجموعة بيانات من الأزواج (الصورة، التصنيف). وهذا ما يتوقعه نموذجنا. لسنا مستعدين تمامًا لاستخدامه في دالة التدريب بعد:

dataset = dataset.cache()
dataset = dataset.shuffle(5000, reshuffle_each_iteration=True)
dataset = dataset.repeat()
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(tf.data.experimental.AUTOTUNE)

تحتوي واجهة برمجة التطبيقات tf.data.Dataset API على جميع وظائف الأداة اللازمة لإعداد مجموعات البيانات:

يخزِّن .cache مجموعة البيانات مؤقتًا في ذاكرة الوصول العشوائي (RAM). هذه مجموعة بيانات صغيرة لذا ستعمل. يُجري .shuffle ترتيبًا عشوائيًا له مع مخزن مؤقت يتألف من 5,000 عنصر. من المهم أن يتم ترتيب بيانات التدريب بشكل عشوائي. يكرّر .repeat مجموعة البيانات. سنتدرّب عليها عدة مرات (فترات متعددة). تجمع ميزة ".batch" عدة صور وتصنيفات معًا في مجموعة صغيرة. أخيرًا، يمكن لتطبيق ".prefetch" استخدام وحدة المعالجة المركزية (CPU) لإعداد الدُفعة التالية أثناء تدريب الدفعة الحالية على وحدة معالجة الرسومات.

يتم إعداد مجموعة بيانات التحقق من الصحة بطريقة مماثلة. نحن الآن جاهزون لتحديد نموذج واستخدام مجموعة البيانات هذه لتدريبه.

الخلية "نموذج كيراس"

وستكون جميع نماذجنا عبارة عن تسلسلات مستقيمة من الطبقات كي نتمكّن من استخدام نمط tf.keras.Sequential لإنشائها. في البداية، إنها طبقة واحدة كثيفة. فهي تحتوي على 10 خلايا عصبية لأننا نصنف الأرقام المكتوبة بخط اليد إلى 10 فئات. تستخدم الدالة "softmax" التنشيط لأنه الطبقة الأخيرة في أي مُصنِّف.

يحتاج نموذج Keras أيضًا إلى معرفة شكل مدخلاته. ويمكن استخدام tf.keras.layers.Input لتحديدها. هنا، متجهات الإدخال هي متجهات مسطحة لقيم البكسل التي تبلغ طولها 28*28.

model = tf.keras.Sequential(
  [
    tf.keras.layers.Input(shape=(28*28,)),
    tf.keras.layers.Dense(10, activation='softmax')
  ])

model.compile(optimizer='sgd',
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# print model layers
model.summary()

# utility callback that displays training curves
plot_training = PlotTraining(sample_rate=10, zoom=1)

يتم إعداد النموذج في Keras باستخدام الدالة model.compile. هنا نستخدم المحسِّن الأساسي 'sgd' (انحدار التدرج العشوائي). يتطلب نموذج التصنيف دالة الخسارة عبر القصور المشترك، تُسمى 'categorical_crossentropy' في كيراس. وأخيرًا، نطلب من النموذج احتساب مقياس 'accuracy'، وهو النسبة المئوية للصور المصنّفة بشكل صحيح.

يقدم Keras أداة model.summary() الرائعة التي تطبع تفاصيل النموذج الذي أنشأته. أضاف المعلّم اللطيف أداة PlotTraining (المحدّدة في خلية "برامج خدمات التصور") التي ستعرض منحنيات تدريب مختلفة أثناء التدريب.

الخلية "تدريب النموذج والتحقّق من صحته"

هذا هو المكان الذي يحدث فيه التدريب، من خلال استدعاء model.fit وإدخال كل من مجموعات بيانات التدريب والتحقق من الصحة. بشكل تلقائي، يجري Keras جولة من عمليات التحقق في نهاية كل حقبة.

model.fit(training_dataset, steps_per_epoch=steps_per_epoch, epochs=EPOCHS,
          validation_data=validation_dataset, validation_steps=1,
          callbacks=[plot_training])

في Keras، من الممكن إضافة سلوكيات مخصصة أثناء التدريب باستخدام عمليات الاستدعاء. هكذا تم تنفيذ مخطط التدريب الديناميكي لدنيا لورشة العمل هذه.

الخلية "عرض التوقّعات"

بعد تدريب النموذج، يمكننا الحصول على توقّعات منه من خلال طلب الرقم model.predict():

probabilities = model.predict(font_digits, steps=1)
predicted_labels = np.argmax(probabilities, axis=1)

هنا أعددنا مجموعة من الأرقام المطبوعة المعروضة من الخطوط المحلية، كاختبار. تذكر أن الشبكة العصبية تُرجع متجهًا بـ 10 احتمالات من آخر "softmax". للحصول على التصنيف، ينبغي لنا تحديد الاحتمالية الأعلى. np.argmax من مكتبة numpy يفعل ذلك.

لفهم سبب الحاجة إلى المعلمة axis=1، يُرجى تذكّر أننا قد عالجنا مجموعة من 128 صورة، وبالتالي يعرض النموذج 128 متجهًا للاحتمالات. شكل متّجه الإخراج هو [128, 10]. نحن نحسب قيمة argmax على مستوى الاحتمالات العشرة التي تم إرجاعها لكل صورة، وبالتالي axis=1 (المحور الأول هو 0).

يتعرّف هذا النموذج البسيط على 90% من الأرقام. هذا ليس سيئًا، لكنك ستعمل الآن على تحسينه بشكل كبير.

396c54ef66fad27f.png

6- إضافة طبقات

godeep.png

لتحسين دقة التعرف، سنضيف المزيد من الطبقات إلى الشبكة العصبية.

لقطة شاشة يوم 27-07-2016 في الساعة 15.36.55.png

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

41fc82288c4aff5d.png

على سبيل المثال، قد يبدو النموذج هكذا (لا تنس الفواصل، حيث يأخذ tf.keras.Sequential قائمة من الطبقات مفصولة بفواصل):

model = tf.keras.Sequential(
  [
      tf.keras.layers.Input(shape=(28*28,)),
      tf.keras.layers.Dense(200, activation='sigmoid'),
      tf.keras.layers.Dense(60, activation='sigmoid'),
      tf.keras.layers.Dense(10, activation='softmax')
  ])

انظر إلى "الملخص" نموذجك. وهي الآن تتضمن معلمات أكثر بـ 10 مرات على الأقل. يُفترض أن يكون أفضل 10 مرات! لكن لسبب ما، لا يعد ...

5236f91ba6e07d85.png

ويبدو أنّ الخسارة أصيبت بالمساحة أيضًا. هناك خطأ ما.

7. العناية الخاصة بالشبكات العميقة

لقد جربت للتو الشبكات العصبية، كما اعتاد الناس على تصميمها في الثمانينيات والتسعينيات. لا عجب أنّهم توقفوا عن تنفيذ الفكرة، فأطلقوا ما يُعرف باسم "شتاء الذكاء الاصطناعي". في الواقع، عند إضافة الطبقات، تواجه الشبكات العصبية المزيد من الصعوبات في التقارب.

اتضح أن الشبكات العصبية العميقة التي تحتوي على العديد من الطبقات (20، 50، حتى 100 في الوقت الحالي) يمكن أن تعمل بشكل جيد حقًا، شريطة بعض الحيل الرياضية البسيطة لجعلها متقاربة. إن اكتشاف هذه الحيل البسيطة هو أحد أسباب نهضة التعلم المتعمق في عام 2010.

تفعيل RELU

relu.png

في الواقع، تمثل وظيفة التفعيل السيني مشكلة كبيرة في الشبكات العميقة. وهذا يؤدي إلى تهبط جميع القيم بين 0 و1، وعندما تتكرر، يمكن أن تتلاشى مخرجات الخلايا العصبية وتدرجاتها تمامًا. وقد ورد ذكره لأسباب تاريخية، إلا أنّ الشبكات الحديثة تستخدم الوحدة الخطية المستعجلة (RELU) التي تبدو كما يلي:

1abce89f7143a69c.png

من ناحية أخرى، تضم قناة Relu مشتق 1، على الأقل في جانبها الأيمن. من خلال تفعيل RELU، حتى إذا كانت التدرجات الواردة من بعض الخلايا العصبية صفرًا، سيكون هناك دائمًا البعض الآخر يعطي تدرجًا واضحًا غير صفري ويمكن أن يستمر التدريب بوتيرة جيدة.

أداة تحسين أفضل

في الأماكن ذات الأبعاد العالية للغاية مثل هنا ـــــ ترتيب الأوزان والتحيزات 10 آلاف — "نقاط السرج" متكررين. وهذه النقاط ليست حدًا أدنى محليًا، ولكن لا يكون التدرج فيها صفر على الرغم من ذلك، ويبقى مُحسِّن انحدار التدرج عالقًا هناك. يضم تطبيق TensorFlow مجموعة كاملة من أدوات تحسين الأداء المتاحة، بما في ذلك بعض أدوات تحسين الأداء التي تعمل بقدرٍ من القصور الذاتي وتتجاوز نقاط الحاجز.

عمليات الإعداد العشوائية

فن إعداد تحيزات الأوزان قبل التدريب هو مجال بحث في حد ذاته، مع نشر العديد من الأبحاث حول هذا الموضوع. يمكنك الاطّلاع هنا على جميع أدوات الإعداد المتوفّرة في Keras. لحسن الحظ، ينفّذ Keras الإجراء الصحيح تلقائيًا ويستخدم أداة إعداد 'glorot_uniform'، وهو الخيار الأفضل في جميع الحالات تقريبًا.

لذا، لن تحتاج إلى اتخاذ أي إجراء لأنّ Keras تتّخذ القرار الصحيح.

NaN ؟؟؟

تتضمن معادلة القصور بين اللوغاريتم واللوغاريتم واللوغاريتم(0) ليس رقمًا (NaN، وهو عطل رقمي إذا كنت تفضل ذلك). هل يمكن أن يكون المُدخل إلى القصور المشترك 0؟ يأتي الإدخال من softmax الذي يمثل في الأساس أُسًا لا يكون صفرًا مطلقًا. إذًا، لقد أصبحنا بأمان.

حقًا؟ سنكون في أمان في عالم الرياضيات الجميل، ولكن في عالم الكمبيوتر، تكون الصيغة exp(-150)، التي يتم تمثيلها بتنسيق float32، صفرًا مثل التعطُّل مع تعطُّل القصور بين الإنتروبيا.

لحسن الحظ، لا يوجد شيء لتفعله هنا أيضًا، حيث إن Keras تهتم بذلك وتحسب قيمة softmax متبوعة بالقصور عبر القصور بطريقة حذرة بشكل خاص لضمان الاستقرار العددي وتجنب أرقام NaN المخيفة.

هل تم الإجراء بنجاح؟

e1521c9dd936d9bc.png

يُفترض أن تصل الآن الدقة إلى 97%. إن الهدف من ورشة العمل هذه هو الحصول على أعلى بكثير من% 99، لذا لنواصل التقدم.

إذا واجهتك مشكلة، إليك الحل في هذه المرحلة:

c3df49e90e5a654f.png keras_02_mnist_dense.ipynb

8. تناقص معدل التعلّم

ربما يمكننا محاولة التدرّب بشكل أسرع؟ معدّل التعلّم التلقائي في مُحسِّن آدم هو 0.001. دعونا نحاول زيادته.

يبدو أن العمل السريع لا يساعد كثيرًا في حل المشكلة، فما كل هذا الضجيج؟

d4fd66346d7c480e.png

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

إبطاء.png

الحل الجيد هو البدء بسرعة وتناقص معدل التعلم بشكل كبير. في Keras، يمكنك إجراء ذلك من خلال معاودة الاتصال tf.keras.callbacks.LearningRateScheduler.

رمز مفيد للنسخ واللصق:

# lr decay function
def lr_decay(epoch):
  return 0.01 * math.pow(0.6, epoch)

# lr schedule callback
lr_decay_callback = tf.keras.callbacks.LearningRateScheduler(lr_decay, verbose=True)

# important to see what you are doing
plot_learning_rate(lr_decay, EPOCHS)

لا تنسَ استخدام lr_decay_callback التي أنشأتها. إضافته إلى قائمة معاودة الاتصال في model.fit:

model.fit(...,  callbacks=[plot_training, lr_decay_callback])

تأثير هذا التغيير البسيط هو تأثير مذهل. ستلاحظ أن معظم التشويش قد اختفى، وأصبحت دقة الاختبار الآن أعلى من 98% بطريقة مستدامة.

8c1ae90976c4a0c1.png

9. انسحاب ، فرط التخصيص

ويبدو أنّ النموذج يتقارب بشكل جيد الآن. دعونا نحاول التعمق أكثر.

هل هو مفيد؟

e36c09a3088104c6.png

ليس في الحقيقة، لا تزال الدقة عالقة عند 98٪ والنظر إلى فقدان التحقق. ارتفاع الطلب تعمل خوارزمية التعلم على بيانات التطبيق فقط وتعمل على تحسين فقدان التدريب وفقًا لذلك. ولا ترى أبدًا بيانات التحقق من الصحة، لذا فليس من المستغرب أنه بعد فترة من العمل لم يعد له تأثير على فقدان التحقق الذي يتوقف عن الانخفاض وأحيانًا يرتد مرة أخرى.

هذا لا يؤثر فورًا على إمكانات التعرف على العالم الحقيقي لنموذجك، ولكنه سيمنعك من إجراء العديد من التكرارات وهو علامة بشكل عام على أن التدريب لم يعد له تأثير إيجابي.

dropout.png

عادةً ما يُطلق على هذا الانفصال اسم "فرط التخصيص" وعند ظهوره، يمكنك محاولة تطبيق أسلوب تسوية يُعرف باسم "التسرُّب". يعمل أسلوب الانسحاب على تصوير خلايا عصبية عشوائية في كل تكرار تدريبي.

هل نجح الأمر؟

43fd33801264743f.png

عودة الضوضاء إلى الظهور (بدون دهشة، عند ملاحظة كيفية عمل الانسحاب من السيارة) لم يعد هناك انخفاض في عدد عمليات التحقق من الصحة ويبدو أنه زاد بنسبة أعلى بشكل عام مقارنةً بحالات التوقف. وانخفضت دقة التحقق من الصحة قليلاً. هذه نتيجة مخيبة إلى حد ما.

يبدو أن انقطاع الخدمة لم يكن الحل الصحيح، أو ربما "فرط التخصيص". مفهومًا أكثر تعقيدًا ولا يمكن لبعض أسبابه أن ينسحب إصلاحه؟

ما المقصود بـ "فرط التخصيص"؟ يحدث فرط التخصيص عندما تتعلم الشبكة العصبية "بشكل سيئ"، بطريقة تصلح لأمثلة التدريب ولكنها لا تتعلم بشكل جيد على بيانات العالم الحقيقي. وهناك بعض أساليب التنظيم، مثل التسرّب، يمكن أن تجبره على التعلم بطريقة أفضل، ولكن الإفراط في التوافق له جذور أعمق أيضًا.

overfitting.png

يحدث فرط التخصيص الأساسي عندما يكون للشبكة العصبية درجات كثيرة جدًا من الحرية لمعالجة المشكلة المطروحة. لنفترض أن هناك العديد من الخلايا العصبية التي يمكن للشبكة تخزين جميع صور التدريب فيها ومن ثم التعرف عليها من خلال مطابقة الأنماط. وسيفشل في البيانات الواقعية تمامًا. يجب أن تكون الشبكة العصبية مقيَّدة نوعًا ما بحيث تُجبر على تعميم ما تتعلمه أثناء التدريب.

إذا كان لديك القليل جدًا من بيانات التدريب، يمكن لشبكة صغيرة تعلُّمها عن طريق القلب وستظهر لك "فرط التخصيص". بشكل عام، تحتاج دائمًا إلى الكثير من البيانات لتدريب الشبكات العصبونية.

وأخيرًا، إذا أنجزت كل شيء من خلال الكتاب، فقد جربت أحجامًا مختلفة من الشبكات للتأكد من تقييد درجات الحرية، وتطبيق التسرّب، والتدريب على الكثير من البيانات، فقد تظل عالقًا في مستوى أداء يبدو أنه لا يوجد شيء قادر على تحسينه. وهذا يعني أن شبكتك العصبية، في شكلها الحالي، غير قادرة على استخراج مزيد من المعلومات من بياناتك، كما هو الحال هنا.

هل تتذكر كيف نستخدم صورنا، المسطحة في متجه واحد؟ كانت هذه فكرة سيئة حقًا. تتكون الأرقام المكتوبة بخط اليد من أشكال ويتم تجاهل معلومات الأشكال عندما قمنا بتسوية وحدات البكسل. ومع ذلك، هناك نوع من الشبكات العصبية التي يمكنها الاستفادة من معلومات الأشكال، ألا وهي الشبكات الالتفافية. دعنا نجربها.

إذا واجهتك مشكلة، إليك الحل في هذه المرحلة:

c3df49e90e5a654f.png keras_03_mnist_dense_lrdecay_dropout.ipynb

10. [INFO] الشبكات الالتفافية

باختصار

إذا كانت جميع المصطلحات الغامقة في الفقرة التالية معروفة لك بالفعل، يمكنك الانتقال إلى التمرين التالي. إذا كنت لا تزال في خطواتك الأولى مع الشبكات العصبية الالتفافية، فيُرجى مواصلة القراءة.

convolutional.gif

صورة توضيحية: فلترة صورة باستخدام فلترَين متتاليَين يتألف كلٌّ منهما من 4x4x3=48 ترجيحات قابلة للتعلُّم

هذه هي الطريقة التي تبدو بها الشبكة العصبية الالتفافية البسيطة في Keras:

model = tf.keras.Sequential([
    tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1)),
    tf.keras.layers.Conv2D(kernel_size=3, filters=12, activation='relu'),
    tf.keras.layers.Conv2D(kernel_size=6, filters=24, strides=2, activation='relu'),
    tf.keras.layers.Conv2D(kernel_size=6, filters=32, strides=2, activation='relu'),
    tf.keras.layers.Flatten(),
    tf.keras.layers.Dense(10, activation='softmax')
])

688858c21e3beff2.png

في إحدى طبقات الشبكة الالتفافية، "خلية عصبية" واحدة مجموع مرجّح للبكسل فوقها مباشرةً، عبر منطقة صغيرة من الصورة فقط. فهي تضيف تحيزًا وتغذي المجموع من خلال دالة تنشيط، تمامًا كما تفعل الخلية العصبية في طبقة كثيفة منتظمة. ثم تتكرر هذه العملية على مستوى الصورة بأكملها باستخدام الأوزان نفسها. تذكر أنه في الطبقات الكثيفة، لكل خلية عصبية أوزانها الخاصة. هنا، "تصحيح" واحد تنزلق من الأوزان عبر الصورة في كلا الاتجاهين ("التفاف"). يحتوي الناتج على عدد قيم مماثل لعدد وحدات البكسل في الصورة (مع ذلك، يلزم وجود بعض المساحة المتروكة عند الحواف). أنها عملية تصفية. في الرسم التوضيحي أعلاه، يستخدم فلترًا 4x4x3=48 ترجيحًا.

ومع ذلك، لن يكون 48 ترجيحًا كافيًا. لإضافة المزيد من درجات الحرية، نكرر العملية نفسها مع مجموعة جديدة من الترجيح. وينتج عن ذلك مجموعة جديدة من مخرجات الفلاتر. لنسميها "قناة" للمخرجات عن طريق التشابه مع قنوات R وG وB في صورة الإدخال.

لقطة شاشة يوم 29-07-2016 في الساعة 16.02.37.png

يمكن تلخيص مجموعتي الترجيح (أو أكثر) في صورة متوتر واحد بإضافة بُعد جديد. يعطينا هذا الشكل العام لموتر الأوزان لطبقة التفافية. بما أن عدد قنوات الإدخال والإخراج هو معامل، يمكننا البدء في تكديس وتسلسل الطبقات الالتفافية.

d1b557707bcd1cb9.png

صورة توضيحية: شبكة عصبية التفافية تحوّل "مكعبات" البيانات إلى "مكعبات" أخرى من البيانات

عمليات التفاف ثابتة وأقصى حدّ للتجميع

ومن خلال إجراء عمليات الالتفاف بخطوة 2 أو 3، يمكننا أيضًا تقليص مكعب البيانات الناتج في أبعاده الأفقية. هناك طريقتان شائعتان للقيام بذلك:

  • التفاف موسّع: فلتر يتم تمريره كما هو موضح أعلاه ولكن بخطوة >1
  • الحد الأقصى لتجميع: نافذة منزلق تقوم بتطبيق عملية MAX (عادةً على التصحيحات 2×2، ويتكرر كل 2 بكسل)

2b2d4263bb8470b.gif

صورة توضيحية: يؤدي تحريك نافذة الحوسبة بمقدار 3 بكسل إلى الحصول على قيم إخراج أقل. تُعدّ عمليات الالتفاف المتدرّجة أو الحدّ الأقصى لتجميع البيانات (الحد الأقصى للانزلاق بخطوة 2×2 في نافذة بحجم 2×2) من طرق تقليص مكعب البيانات في الأبعاد الأفقية.

الطبقة النهائية

بعد الطبقة الالتفافية الأخيرة، تكون البيانات على شكل "مكعب". وهناك طريقتان لإطعامها من خلال الطبقة الكثيفة النهائية.

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

بدلاً من استخدام طبقة كثيفة مكلفة، يمكننا أيضًا تقسيم "مكعب" البيانات الواردة في العديد من الأجزاء مثل الفئات، ومتوسط قيمها وتغذيةها من خلال دالة تفعيل softmax. وهذه الطريقة لإنشاء رأس التصنيف تكلف 0 أوزان. في Keras، تتوفّر طبقة لهذا الغرض: tf.keras.layers.GlobalAveragePooling2D().

a44aa392c7b0e32a.png

انتقل إلى القسم التالي لإنشاء شبكة التفافية للمشكلة الماثلة أمامنا.

11. شبكة التفافية

دعنا ننشئ شبكة التفافية للتعرف على الأرقام المكتوبة بخط اليد. سنستخدم ثلاث طبقات التفافية في الأعلى، وهي طبقة قراءة softmax التقليدية في الأسفل ونربطها بطبقة واحدة متّصلة بالكامل:

e1a214a170957da1.png

لاحظ أن الطبقتين الالتفافيتين الثانية والثالثة لهما خطوة واحدة، وهو ما يفسر سبب خفض عدد قيم الإخراج من 28×28 إلى 14×14 ثم 7×7.

هيا نكتب رمز Keras.

ويجب الانتباه بشكل خاص قبل الطبقة الالتفافية الأولى. في الواقع، تتوقع "مكعب" ثلاثي الأبعاد من البيانات، ولكن تم إعداد مجموعة البيانات حتى الآن للطبقات الكثيفة ويتم تسطيح جميع وحدات البكسل في الصور في متجه. نحتاج إلى إعادة تشكيلها إلى صور بحجم 28x28x1 (قناة واحدة للصور بتدرج الرمادي):

tf.keras.layers.Reshape(input_shape=(28*28,), target_shape=(28, 28, 1))

يمكنك استخدام هذا الخط بدلاً من طبقة tf.keras.layers.Input التي تستخدمها حتى الآن.

في Keras، بناء الجملة لطبقة الالتفاف "relu" التي يتم تنشيطها هي:

140f80336b0e653b.png

tf.keras.layers.Conv2D(kernel_size=3, filters=12, padding='same', activation='relu')

للحصول على التفاف موسّع، يمكنك كتابة:

tf.keras.layers.Conv2D(kernel_size=6, filters=24, padding='same', activation='relu', strides=2)

لتسوية مكعب من البيانات في متجه بحيث يمكن استهلاكه من خلال طبقة كثيفة:

tf.keras.layers.Flatten()

وبالنسبة للطبقة الكثيفة، لم تتغير بناء الجملة:

tf.keras.layers.Dense(200, activation='relu')

هل كسر النموذج حاجز الدقة الذي يبلغ 99%؟ قريب جدًا... ولكن انظر إلى منحنى فقدان التحقق من الصحة. هل يذكرك هذا التغيير بجرس؟

ecc5972814885226.png

ننصحك أيضًا بالاطّلاع على التوقّعات. لأول مرة، من المفترض أن تلاحظ أن معظم أرقام الاختبار البالغ عددها 10000 رقم تم التعرف عليها بشكل صحيح. لم يبقَ سوى 41⁄2 صفًا من الأخطاء في الرصد (حوالي 110 أرقام من 10,000)

37e4cbd3f390c89e.png

إذا واجهتك مشكلة، إليك الحل في هذه المرحلة:

c3df49e90e5a654f.png keras_04_mnist_convolutional.ipynb

12. الانسحاب مرة أخرى

تُظهر التدريب السابق علامات واضحة على فرط التخصيص (ولا تزال أقل دقة بنسبة 99٪). هل يجب أن نحاول الانسحاب مرة أخرى؟

كيف سار الأمر هذه المرة؟

63e0cc982cee2030.png

يبدو أنّ عملية الانسحاب قد اكتملت هذه المرة. لم يعد فقدان التحقق من الصحة يرتفع، ويجب أن تكون الدقة النهائية أعلى بكثير من 99٪. تهانينا!

في المرة الأولى التي حاولنا فيها تطبيق الانسحاب، اعتقدنا أنّ هناك مشكلة في فرط التخصيص، في حين كانت المشكلة في الواقع في بنية الشبكة العصبونية. فبدون تطبيق الطبقات الالتفافية، لا يمكن أن نفعل أي شيء حيال ذلك.

هذه المرة، يبدو أن الإفراط في التوافق هو سبب المشكلة وأن التوقف عن العمل قد ساعد في الواقع. تذكر أن هناك العديد من الأشياء التي يمكن أن تسبب فصلاً بين منحنيات فقدان التدريب وفقدان التحقق، مع ازدياد فقدان التحقق من الصحة. فرط التخصيص (درجات حرية كثيرة جدًا، والتي تستخدمها الشبكة بشكل سيئ) هي واحدة منها فقط. وإذا كانت مجموعة البيانات صغيرة جدًا أو كانت بنية الشبكة العصبونية غير كافية، فقد تلاحظ سلوكًا مشابهًا في منحنيات الخسارة، إلا أن الانقطاع لن يفيد في ذلك.

13. تسوية الدفعة

oggEbikl2I6_sOo7FlaX2KLdNeaYhJnVSS8GyG8FHXid75PVJX73CRiOynwpMZpLZq6_xAy69wgyez5T-ZlpuC2XSlcmjk7oVcOzefKKTFhTEoLO3kljz2RDyKcaFtHvtTey-I4VpQ

وأخيرًا، لنحاول إضافة تسوية الدفعة.

هذه هي النظرية، عمليًا، تذكر فقط قاعدتين:

لنقم حاليًا باللعب بالكتاب ونضيف طبقة معيارية مجمّعة على كل طبقة من طبقات الشبكة العصبونية ما عدا الأخيرة. يُرجى عدم إضافته إلى آخر "softmax". الطبقة الخارجية. لن تكون مفيدة هنا.

# Modify each layer: remove the activation from the layer itself.
# Set use_bias=False since batch norm will play the role of biases.
tf.keras.layers.Conv2D(..., use_bias=False),
# Batch norm goes between the layer and its activation.
# The scale factor can be turned off for Relu activation.
tf.keras.layers.BatchNormalization(scale=False, center=True),
# Finish with the activation.
tf.keras.layers.Activation('relu'),

ما مدى الدقة الآن؟

ea48193334c565a1.png

يمكنك تحقيق نسبة 99.5% من خلال بعض التعديلات (BATCH_حجم=64، ومعلَمة تناقص معدل التعلّم 0.666، ومعدل الانسحاب 0.3) والقليل من الحظ. تم إجراء تعديلات على معدّل التعلّم والانسحاب من التطبيق باتّباع "أفضل الممارسات". لاستخدام المعيار المجمّع:

  • تساعد القاعدة المجمّعة في تقارب الشبكات العصبونية وعادة ما تسمح لك بالتدريب بشكل أسرع.
  • معيار الدفعة هو أداة تسوية. ويمكنك عادةً تقليل عدد حالات الانسحاب التي تتعرض لها، أو حتى عدم استخدام هذه الميزة على الإطلاق.

يحتوي دفتر الحل على تدريب بنسبة 99.5٪:

c3df49e90e5a654f.png keras_05_mnist_batch_norm.ipynb

14. تدرَّب في السحابة الإلكترونية على أجهزة فعّالة: AI Platform

d7d0282e687bdad8.png

ستعثر على نسخة من الرمز البرمجي متوافقة مع السحابة الإلكترونية في مجلد mlengine على GitHub، بالإضافة إلى تعليمات حول تشغيلها على Google Cloud AI Platform. قبل تنفيذ هذا الجزء، يجب إنشاء حساب على Google Cloud وتفعيل الفوترة. يجب أن تكون الموارد اللازمة لإكمال التمرين أقل من دولارين أمريكيين (بافتراض أن وقت التدريب على وحدة معالجة رسومات واحدة يستغرق ساعة واحدة). لإعداد حسابك، عليك اتّباع الخطوات التالية:

  1. أنشئ مشروعًا على Google Cloud Platform ( http://cloud.google.com/console).
  2. تفعيل الفوترة
  3. ثبِّت أدوات سطر أوامر Google Cloud Platform ( GCP SDK هنا).
  4. أنشِئ حزمة على Google Cloud Storage (أدخِلها في المنطقة us-central1). سيتم استخدامه لإعداد رمز التدريب وتخزين النموذج المدرَّب.
  5. فعِّل واجهات برمجة التطبيقات الضرورية واطلب الحصص اللازمة (نفِّذ أمر التدريب مرة واحدة وستظهر لك رسائل خطأ تخبرك بالإمكانيات التي يجب تفعيلها).

15. تهانينا!

لقد صممت أول شبكة عصبية لديك ودرّبتها وصولاً إلى الدقة بنسبة 99%. الأساليب التي تم تعلمها طوال العملية ليست خاصة بمجموعة بيانات MNIST، بل تُستخدم على نطاق واسع عند العمل على الشبكات العصبية. كهدية فواصل، ها هي "ملاحظات الجرف" بطاقة للمعمل، في إصدار الرسوم المتحركة. ويمكنك استخدامها لتذكُّر ما تعلمته:

منحدرات الملاحظات tensorflow lab.png

الخطوات التالية

  • بعد الشبكات المتصلة بالكامل والشبكات الالتفافية، من المفترض أن تطّلع على الشبكات العصبونية المتكررة.
  • توفّر Google Cloud منصة الذكاء الاصطناعي لتشغيل التدريب أو الاستنتاج في السحابة الإلكترونية على بنية أساسية موزَّعة.
  • وأخيرًا، نرحِّب بملاحظاتك. يُرجى إخبارنا بما إذا لاحظت أمرًا غير صحيح في هذا التمرين المعملي أو إذا كنت تعتقد أنه ينبغي تحسينه. نتعامل مع الملاحظات والآراء من خلال مشاكل GitHub [ feedback link].

HR.png

معرّف مارتن غورنر صغير.jpgالمؤلف: "مارتن غورنر": @martin_gorner

جميع صور الرسوم المتحركة في حقوق الطبع والنشر في هذا التمرين المعملي: alexpokusay / صور المخزون 123RF