عزيزي القارئ هذه المقالة المقالة الأولى في سلسلة من ثلاث مقالات سنتعلم من خلالها كيفية استخدام النماذج المدرّبة مسبقاً pre-trained models على قواعد بيانات كبيرة الحجم مثل قاعدة بيانات إيمج-نت ImageNet لحل مسألة تصنيف الصور. سنتعلم أيضاً كيف يمكننا استخدام هذه النماذج من أجل حل مهام أو مسائل أخرى غير المهام التي تدربت عليها سابقاَ، وذلك إمّا عن طريق تدريب مُصنّف يعتمد على أشعة المزايا المستخرجة من النماذج المدربة مسبقاً وهذا ما يسمى بنقل التعلّم Transfer Learning أو عن طريق تدريب مُصنّف يقوم بتعديل أوزان النماذج المدربة مسبقاً وهذا ما يسمى بالضبط الدقيق Fine-tuning.
إذا كنت جاهز عزيزي القارئ فلنبدأ مقالتنا الأولى.
المحتويات
ما هي قاعدة بيانات إيمج-نت
إيمج-نت هي مشروع بحثي يتم من خلاله تطوير قاعدة بيانات ضخمة تحتوي على صور معنونة (مجموعة كبيرة من الصور مرفقة مع وصفها). تتألف إيمج-نت من أكثر من 14 مليون صورة تنتمي لأكثر من 2000 صنف. توفر إيمج-نت أيضا عنونة مربعات إحاطة bounding box annotations لأكثر من مليون صورة يمكن استخدامها في مهمات تحديد الأغراض Object Localization. ومع تزايد شعبيتها والإعتماد عليها، أصبحت قاعدة البيانات إيمج-نت منذ عام 2010 الأساس والمرجع لتحدي تصنيف الصور المعروف باسم تحدّي إيمج-نت للتعرُّف البصري واسع النطاق للرؤية الحاسوبية ILSVRC Imagenet Large Scale Visual Recognition Challenge.
ما هو تحدي إيمج-نت للتعرُّف البصري واسع النطاق للرؤيّة الحاسوبيّة ILSVRC
هو مسابقة سنوية يتم تنظيمها من قبل فريق إيمج-نت منذ عام 2010 ويعتبر بمثابة معيار مقارنة وقياس للأداء في مهام تصنيف واكتشاف الأغراض. يشترك في هذه المسابقة العديد من الباحثين والمؤسسات البحثية، و يتنافسون فيما بينهم لتمييز الأفضل في تقديم نموذج قادر على تحقيق أفضل نتيجة لتصنيف الأغراض في صور مجموعة اختبار معرفة مسبقاً.
ولكن بدايةً دعونا نجيب على التساؤل التالي: ما هي الفائدة من استخدام النماذج المُدرّبة مسبقاً؟
دعنا عزيزي القارئ نتخيّل معاً القصَة القصيرة التالية:
قام كلاً من السيد المدرّب “م” والسيد الرياضي “ر” بالتسجيل في نفس الوقت لدى أحد المراكز التدريبية للتدرّب على لعب كرة القدم. كل منهما لم يلعب كرة القدم من قبل وبالتالي فهما لا يملكان المهارات الضرورية مثل دحرجة الكرة و التمرير و ركل الكرة وتسجيل الأهداف … الخ.
إن صديقنا السيد المدرّب “م” بحكم مهنته لا يركض كثيراً ولا يبذل مجهوداً بدنياً كبيراً، أظن أنكم الآن تتوقعون ما هي المهارات التي يمتلكها السيد الرياضي “ر”. نعم هذا صحيح فهو يملك مهارات مثل الركض و التحمل … وهذا هو الاختلاف الأساسي والجوهري بينهما حتى قبل بدء التدريب في المركز.
فمن الواضح الآن عزيزي القارئ أنّ المهارات التي طورها السيد الرياضي “ر” كونه رياضي (كطاقة التحمل والسرعة والموهبة الرياضية) ستكون مفيدة جداً له في تعلم كرة القدم حتى لو أنه لم يلعبها أو يتدرب عليها من قبل. فالسيد الرياضي “ر” استفاد من تَدَرُّبه المسبق.
إنّ ما تمّ ذكره عزيزي القارئ ينطبق على النماذج المُدرّبة في مجال الشبكات العصبية. حيث يتم تدريب النموذج المُدرّب مسبقاً على مهمة أو مسألة مختلفة عن تلك التي يتم العمل عليها حاليّاً، ولكنّه يُشكّل نقطة بداية مفيدة جداً على اعتبار أنّ المزايا التي تم تعلُّمها أثناء التدريب على المهمة القديمة سيكون مفيداً جداً للمهمة الجديدة.
تمتلك الشبكات العصبية عدداً كبيراً (يقدّر بالملايين) من المُعاملات غير المعروفة، والهدف من عملية تدريب هذه الشبكات هو إيجاد القيم المُثلى لتلك المُعاملات باستخدام بيانات التدريب. نعلم من الجبر الخطي أننا نحتاج إلى ثلاث معادلات (بيانات) من أجل حل معادلة بثلاثة مُعاملات غير معروفة (ثلاثة مجاهيل). فإذا كنا نعلم حل معادلتين فقط فإنّه يمكننا الحصول على القيم الفعلية لمُعاملين اثنين والقيمة التقديرية للمُعامل المجهول الثالث.
وبشكل مشابه نحتاج إلى الكثير من البيانات (ملايين البيانات) من أجل أن نوجد بدقة المُعاملات غير المعروفة للشبكة العصبية. سنحصل على قيم تقريبية فقط لأغلب المُعاملات، إذا كان لدينا عدد قليل من البيانات وهذا ما لا نريده.
وهنا وصلنا أيها القارئ الكريم إلى القاعدة الذهبية:
ولكنّ المشكلة هي صعوبة الحصول على هذا المقدار من البيانات المُعنْوَنة labeled dataset من أجل تدريب الشبكة العصبية. وهناك مشكلة أخرى أيضاً تتعلّق بالشبكات العصبيّة العميقة وهي حاجتنا إلى الكثير من الوقت (مئات الساعات) لتدريب الشبكة حتى لو استطعنا تأمين مجموعة بيانات ضخمة, وبالتالي لتدريب شبكة عصبية عميقة بشكل ناجح يلزمنا الكثير من الوقت والمال والجهد.
لحسن الحظ يمكننا التغلب على المشاكل المذكورة أعلاه عن طريق الاستفادة من نماذج مدرّبة مسبقاً على كمية كبيرة من البيانات لحل المسائل الصعبة (آلاف الأصناف). كما تقوم العديد من المجموعات البحثية بتدريب مثل تلك النماذج (تتم عملية التدريب باستخدام وحدات معالجة الرسومات قوية GPU على ملايين الصور و تستمر لمئات الساعات) وإتاحتها للاستخدام في مسابقات عالمية مثل تحدي التعرُّف البصري واسع النطاق للرؤية الحاسوبية. يقوم الباحثون والمطورون باستخدام هذه النماذج المدرّبة مسبقاً كنقطة بداية في عملية التدريب بدلاً من تدريب نماذج جديدة من الصفر.
أعتقد أنّك أصبحت متشوّقاً لمعرفة كيف يمكن استخدام النماذج المدرّبة مسبقاً لتصنيف الصور. إذا كنت كذلك عزيزي القارئ، أنصحك بمتابعة القراءة!
النماذج المدرّبة مسبقاً باستخدام كيراس Keras
يوجد العديد من النماذج المدرّبة مسبقاً متاحة للاستخدام بشكل مفتوح المصدر للباحثين والمطوّرين. فإذا كنا نريد حل مهمة ما، يمكننا اختيار أحد النماذج المتاحة من قبل الرابحين في مسابقة التعرُّف البصري واسع النطاق للرؤية الحاسوبية على سبيل المثال (شبكة أليكس AlexNet، شبكة VGG، شبكة جوجل انسبشن Inception، شبكة الرواسب ResNet، وغيرها الكثير. يمكن أيضاً اختيار نماذج مُدرّبة على مهام مشابهة ومتاحة من قبل مجموعات بحثية مثل شبكة موبايل MobileNet والشبكة المضغوطة SqueezeNet وغيرها.
تم تدريب الشبكات المذكورة أعلاه من أجل تصنيف الصور إلى صنف واحد من 1000 صنف.
تضم مكتبة كيراس العديد من النماذج المدرّبة مسبقاً ويتألف كل نموذج منها من قسمين بنية النموذج و أوزان النموذج. كما لا تأتي ملفات الأوزان مرفقة مع مكتبة كيراس بسبب كبر حجمها، ولكن يتم تحميلها (أول مرة فقط) بشكل آلي عند استدعاء النموذج عن طريق ضبط معامل مصدر الأوزان ليكون “imagenet”. فيما يلي بعض النماذج المدرّبة مسبقاً والتي يمكن استدعاؤها في مكتبة كيراس (الإصدار 2.1.2 على سبيل المثال):
- VGG16
- InceptionV3
- ResNet
- MobileNet
- Xception
- InceptionResNetV2
تحميل نموذج في كيراس
يمكن تحميل النماذج المذكورة عن طريق استدعائها بالإسم من مكتبة تطبيقات كيراس keras.applications كما هو واضح في الشيفرة البرمجية التالية:
import keras
import numpy as np
from keras.applications import vgg16, inception_v3, resnet50, mobilenet
#Load the VGG model
vgg_model = vgg16.VGG16(weights='imagenet')
#Load the Inception_V3 model
inception_model= inception_v3.InceptionV3(weights='imagenet')
#Load the ResNet50 model
resnet_model = resnet50.ResNet50(weights='imagenet')
#Load the MobileNet model
mobilenet_model= mobilenet.MobileNet(weights='imagenet')
بعد تنفيذ الأسطر البرمجية السابقة، سيتم تحميل بنية النماذج المدرّبة إضافة إلى أوزانها. أمّا في حال أردنا عدم تهيئة النماذج بأوزان شبكة الصور إيمج-نت عندها يجب إسناد القيمة None لمعامل الأوزان. الآن بعد تحميل النماذج المدرّبة لنقم بتحميل ومعالجة الصور.
تحميل ومعالجة الصور
يمكن تحميل الصور في لغة البرمجة بايثون باستخدام عدد من المكتبات مثل المكتبة مفتوحة المصدر للرؤية الحاسوبية OpenCv، بيل PIL، سايكت-إيمج skimage وغيرها. كما تؤمّن مكتبة كيراس وحدة خاصّة بالصور image module تحتوي على عدد من الدّوال البرمجيّة كاستيراد الصور، وتطبيق بعض عمليات المعالجة المسبقة الأساسيّة عليها قبل تمريرها إلى الشبكة للقيام بعمليّة التنبؤ. سأقوم في هذه التدوينة باستخدام مكتبة كيراس للتعامل مع الصور وإجراء العمليّات التالية:
- تحميل الصورة: يتم ذلك باستخدام الدّالة load_img. يستخدم كيراس مكتبة بيل من أجل تحميل الصور، وبالتالي يتم تحميل الصور بصيغة (عرض x ارتفاع x عدد القنوات).
- تحويل صيغة الصورة المُحمّلة من صيغة بيل إلى صيغة مكتبة بايثون العددية Numpy (ارتفاع x عرض x عدد القنوات) باستخدام الدالّة image_to_array.
- على اعتبار أنّ دخل الشبكات العصبونيّة يجب أن يكون شعاع/مصفوفة متعدد الأبعاد Tensor رباعي الأبعاد وفق الشكل (حجم الدفعة، ارتفاع x عرض x عدد القنوات), فإنّه يتم إضافة البُعد الرابع باستخدام الدالّة expand_dims من مكتبة بايثون العدديّة.
from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.imagenet_utils import decode_predictions
import matplotlib.pyplot as plt
%matplotlib inline
filename = 'images/cat.jpg'
# load an image in PIL format
original = load_img(filename, target_size=(224, 224))
print('PIL image size',original.size)
plt.imshow(original)
plt.show()
# convert the PIL image to a numpy array
# IN PIL - image is in (width, height, channel)
# In Numpy - image is in (height, width, channel)
numpy_image = img_to_array(original)
plt.imshow(np.uint8(numpy_image))
plt.show()
print('numpy array size',numpy_image.shape)
# Convert the image / images into batch format
# expand_dims will add an extra dimension to the data at a particular axis
# We want the input matrix to the network to be of the form (batchsize, height, width, channels)
# Thus we add the extra dimension to the axis 0.
image_batch = np.expand_dims(numpy_image, axis=0)
print('image batch size', image_batch.shape)
plt.imshow(np.uint8(image_batch[0]))
بعد تنفيذ المقطع البرمجي السّابق، نحصل على الخرج التالي:
(‘PIL image size’, (224, 224))
(‘numpy array size’, (224, 224, 3))
(‘image batch size’, (1, 224, 224, 3))
التنبؤ بصنف الصورة
بعد أن قمنا بمعالجة الصورة وتحويلها إلى الصيغة المناسبة لكيراس، يمكننا الآن تمريرها كدخل إلى الشبكة العصبونيّة من أجل الحصول على التنبؤات. ولابد من الإشارة إلى أنّه يجب تطبيق عمليّة التقييس على الصورة عن طريق طرح قيمة المتوسط الحسابي لبيانات إيمج-نت منها وذلك لأنّه تمّ تدريب الشبكة العصبونيّة بالأساس على صور إيمج-نت بعد تطبيق نفس عمليّة التقييس. تمّ تطبيق الخطوات التّالية من أجل الحصول على نتائج عمليّة التصنيف:
- تطبيق عمليّة المعالجة المسبقة على الدّخل عن طريق طرح قيمة المتوسط الحسابي من كل قناة من قنوات صور الدّفعة الواحدة. يتم الحصول على مصفوفة المتوسط الحسابي – مصفوفة ثلاثية الأبعاد – عن طريق حساب المتوسّط الحسابي لبكسلات كل من قنوات الألوان الأحمر R والأخضر G والأزرق B لكل صور قاعدة بيانات إيمج-نت. يمكن تحقيق ذلك باستخدام الدالّة preprocess_input. فعلى سبيل المثال، تُعطى مصفوفة المتوسط لجميع صور إيمج-نت بالشكل التالي [103.939, 116.779, 123.68]، حيث تُعبّر القيمة 103.939 عن متوسط البكسلات الحمراء لجميع الصور، و تٌعبّر القيمة 116.779 عن متوسط البكسلات الخضراء و 123.68 متوسط البكسلات الزرقاء. عند تطبيق عملية المُعالجة المسبقة، سيتم طرح متوسط البكسلات الحمراء لجميع صور قاعدة البيانات إيمج-نت من جميع بكسلات قناة اللون الأحمر من صورة الدخل، ويتم تطبيق نفس العملية على قنوات الألوان الأخرى. يمكن تحقيق ذلك في بايثون على الشكل التالي:
image[:,:,0] -= 103.939 #R
image[:,:,1] -= 116.779 #G
image[:,:,2] -= 123.68 #B
- الحصول على نتيجة التصنيف، وهي عبارة عن مصفوفة متعددة الأبعاد Tensor له الأبعاد التالية (حجم الدفعة x عدد الأصناف). وفي حالتنا إنّ عدد الأصناف هو 1000. كما يمكن تحقيق ذلك باستخدام الدالّة predict.
- تحويل نتيجة التصنيف إلى عناوين نصيّة قابلة للقراءة من قبل الإنسان، وذلك لأنّ شعاع الخرج (نتيجة التصنيف) الناتج عن الخطوة السابقة يحتوي على عدد كبير (مساوي لعدد الأصناف) من القيم العدديّة التي لا يمكن تفسيرها بشكل واضح كعناوين أصناف. تتم عمليّة التحويل باستخدام الدالّة decode_predictions من مكتبة كيراس والتي تأخذ المصفوفة الناتجة عن التصنيف كدخل وتقوم أولاً بترتيبها حسب قيم عامل ثقة التنبؤ prediction confidence ثم تقوم بإرجاع اسم الصنف ذو عامل الثقة الأعلى. يمكننا أيضاً تحديد عدد الأصناف التي نريد إرجاعها (أعلى k صنف في مصفوفة نتيجة التصنيف) عن طريق استخدام المعامل top في الدالّة السابقة.
يوضّح المقطع البرمجي التالي آلية تطبيق الخطوات الثلاثة السّابقة من أجل الحصول على نتائج عمليّة التصنيف:
# prepare the image for the VGG model
processed_image= vgg16.preprocess_input(image_batch.copy())
# get the predicted probabilities for each class
predictions = vgg_model.predict(processed_image)
# print predictions
# convert the probabilities to class labels
# We will get top 5 predictions which is the default
label = decode_predictions(predictions)
print (label)
[[(u’n02123597′, u’Siamese_cat’, 0.30934173),
(u’n01877812′, u’wallaby’, 0.080341272),
(u’n02326432′, u’hare’, 0.075098492),
(u’n02325366′, u’wood_rabbit’, 0.050530687),
(u’n03223299′, u’doormat’, 0.048173629)]]
مقارنة نتائج تصنيف عدة نماذج مدرّبة مسبقاً
عزيزي القارئ، سنقوم في هذه الفقرة بتطبيق النماذج التاليّة (VGG، موبايل نت، انسبشن، شبكة الرواسب) على نفس الصور ثم رؤية نتيجة تصنيف كل واحد منها.
لنبدأ بصورة قطة مثلاً سنحصل عند تمريرها كدخل للنماذج الأربعة على نتائج التصنيف الموضّحة على الصورة التاليّة
أما عند تمرير صورة كلب كدخل للنماذج، سنحصل على الخرج التالي:
بالنسبة لصورة برتقال، سنحصل على الخرج التالي
من أجل صورة بندورة، سنحصل على الخرج التالي:
من أجل صورة جبس (البطيخ الأحمر)، نحصل على الخرج التالي:
يمكنك عزيزي القارئ تجريب الشيفرة البرمجية بنفسك من هنـــا
من الواضح من خلال التجربة السابقة أنّ النماذج المدرّبة مسبقاّ على قاعدة بيانات إيمج-نت (نماذج تحدي التعرُّف البصري واسع النطاق للرؤية الحاسوبية) لم تستطع التعرف على البندورة والجبس. كما سنتعرف لاحقاً على كيفيّة التدريب المُصنّف بالاعتماد على نفس النماذج المدرّبة مسبقاّ (التي استخدمناها في هذا المقال) ولكن باستخدام بيانات خاصّة بنا من أجل التعرّف على أي مجموعة أخرى من الأغراض غير الموجودة في قاعدة بيانات تحدي التعرُّف البصري واسع النطاق للرؤية الحاسوبية. عزيزي القارئ، إذا كانت لديك الرغبة في معرفة آلية التدريب كما في هذه المصنّفات، فذلك سيكون موضوع المقالين القادمين, أرجو أن تبقى مترقبّاً.
تعليقان