![]() |
إنَّ الفكرة الأساسية لهذه التقنية هي الإستفادة من بعض النماذج المشهورة والمدربة على مجموعة بيانات كبيرة جداً قد تصل بعض الأحيان إلى ملايين الصور حيث تتكون هذه الصور من مجموعة كبيرة من الأصناف (Classes) قد تصل إلى (1000) صنف وبعض هذه الأصناف تكون مشابهة كثيراً للأصناف التي نرغب في تدريب نموذجنا عليها.
إذا نظرنا إلى معمارية أي نموذج يقوم بمهمة تصنيف الصور (Image Classification) فإننا سوف نكتشف بأنَّ هذا النموذج يتكون من جزئين رئيسيين هما |
تقنية نقل التعلم
(Transfer learning)
الجزء الأول
المهندس
حسن فنجان عداي
بسم إلله الرحمن الرحيم
إنَّ الفكرة الأساسية لهذه التقنية هي الإستفادة من بعض النماذج المشهورة والمدربة على مجموعة بيانات كبيرة جداً قد تصل بعض الأحيان إلى ملايين الصور حيث تتكون هذه الصور من مجموعة كبيرة من الأصناف (Classes) قد تصل إلى (1000) صنف وبعض هذه الأصناف تكون مشابهة كثيراً للأصناف التي نرغب في تدريب نموذجنا عليها.
إذا نظرنا إلى معمارية أي نموذج يقوم بمهمة تصنيف الصور (Image Classification) فإننا سوف نكتشف بأنَّ هذا النموذج يتكون من جزئين رئيسيين هما:
1 - إستخلاص الخصائص (Features Extraction) ويتمثل عادة بالطبقات التي تحتوي على مصفوفات الخصائص (Feature maps), أي الطبقات الإلتفافية (Convolutional layers) وما بينها من طبقات ثانوية مثل (Pooling layers) أو (Dropout layers).
2 – التصنيف (Classification), حيث يتمثل هذا الجزء بآخر طبقتين وبالخصوص طبقة الإخراج (Output layer).
نستطيع الإستفادة من أحد النماذج المشهورة المدربة على مجموعة أصناف بعضها يكون قريباً من الأصناف التي ننوي تدريب نموذجنا عليها, وذلك بأخذ هذا النموذج والتخلص من طبقاته الأخيرة والإبقاء على طبقاته التي تشكل جزء إستخلاص الخصائص (Features Extraction) ومن ثم نقوم بإضافة الطبقات الأخيرة التي تقوم بعملية التصنيف (Classification) بما يتناسب ومتطلبات نموذجنا.
نقوم بعدها بعملية تدريب للطبقات التي قمنا بإضافتها فقط.
هذا ملخص لما يتم من عمليات في هذه التقنية والتي سوف نرى فائدتها الكبيرة حيث إننا نستطيع تدريب نموذجنا بإستخدام مجموعة بيانات صغيرة كذلك تساعدنا هذه التقنية كثيراً في تقليل زمن التدريب وكذلك تمكننا من الحصول على دقة عالية جداً في أداء النماذج.
سوف نقوم بإستخدام النموذج المشهور (VGG16) والذي قام بتطويره العالمان كارن سيمونيان و أندرو زيسيرمان في العام (2014), وقد وقع الإختيار عليه لسهولته وأن معماريته يمكن فهمها بسهولة لأنها تشبه كثيراً معمارية النماذج التي نقوم بإنشاءها على الرغم من إنه قديم بعض الشيء. علماً بأنَّ هناك نماذج احدث منه ممكن الإستفادة منها في هذا المجال.
هناك آليتان لتنفيذ هذه التقنية هما:
1 - إستخلاص الميزات أو الخصائص (Feature Extraction).
2 - الضبط الدقيق (Fine Tuning).
ولنبدأ الآن بالآلية الأولى:
إستخلاص الخصائص (Feature Extraction)
إستخلاص الخصائص هي عملية تطبيق الفلاتر المدربة (Filters or kernels) في طبقة إلتفافية معينة على البيانات القادمة إليها من الطبقة التي تسبقها وذلك لأجل إستخلاص بعض المزايا أو الخصائص من هذه البيانات, علماً بأنَّ البيانات القادمة إلى هذه الطبقة ممكن أن تكون بيانات صورة في حالة كون هذه الطبقة هي الأولى بعد طبقة الإدخال, أو تكون هذه البيانات هي بيانات مأخوذة من مصفوفة خصائص (Feature map) قادمة من طبقة سابقة.
في هذه الطريقة نقوم بإستخدام النموذج المدرب مسبقاً وفي حالتنا يكون هو النموذج (VGG16) حيث نقوم أولاً بالتخلص من الطبقات الأخيرة التي تشكل مرحلة التصنيف (Classification) ونستبدلها بطبقات جديدة خاصة بنا ثم نقوم بإدخال مجموعة البيانات الخاصة بنا على النموذج (VGG16) ونستخدمه في طور التوقع (Prediction) ونحصل على الخصائص (Features) ونعتبرها بيانات (Dataset) لتدريب مرحلة التصنيف (Classifier) الذي ضفناه. والرسم التالي يوضح هذه الطريقة:
حيث نلاحظ في الصورة أعلاه وفي الخطوة رقم (1) النموذج في حالته الإعتيادية حيث يتكون من مرحلتين, أما في الخطوة رقم (2) فقد قمنا بالتخلص من مرحلة التصنيف (Classification) وأبقينا على مرحلة إستخلاص الخصائص أو مايسمى (Trained convolutional base), أما في الخطوة رقم (3) فقد قمنا بإضافة مرحلة التصنيف الخاصة بنا وقد أعطيناها قيم إبتدائية عشوائية لغرض تدريبها لاحقاً أما بقية أقسام النموذج الأصلي فقد قمنا بتجميده إي جعلناه غير قابل للتدريب (Frozen).
إنَّ البيانات التي تحويها مصفوفات الخصائص (Feature maps) الموجودة في الطبقات الإلتفافية (Convolutional layers) تتضمن معلومات عن كل خاصية توجد في كل صورة وكذلك معلومات عن هذه الخاصية من حيث موقعها بالنسبة إلى الصورة وغير ذلك حيث إنها تكون عامة يمكن إستخدامها في نماذج تصنيف مختلفة, أما البيانات التي تحويها الطبقات التابعة إلى مرحلة التصنيف (Classification) فتتضمن بيانات محددة تتعلق بإحتمالية كل صنف (Class) من الأصناف التي تم تدريب النموذج على تصنيفها, لذلك تكون أكثر خصوصية ولايمكن الإستفادة منها في النماذج الأخرى.
كذلك فإنه في بعض مشكلات الرؤية الحاسوبية يكون موقع الخاصية بالنسبة للصورة مهم لأننا نعلم إن النموذج المدرب على تصنيف الصور يمكن إستخدامه في مجالات مختلفة من مجالات الرؤية الحاسوبية مثل موضوع كشف الأشياء (Object detection) وكذلك في تقطيع الصور (Image segmentation) حيث يكون موقع الخاصية بالنسبة للصورة مهماً, غير أنَّ الطبقات الموجودة في مرحلة التصنيف (Classification) لاتحتوي على مثل هذه البيانات وبالتالي لايمكن الإستفادة منها هنا.
إنَّ درجة العمومية للخصائص التي تحويها مصفوفات الخصائص (Feature maps) في كل طبقة تعتمد على عمق الطبقة وموقعها بالنسبة إلى طبقات النموذج, فالطبقات الأولى من النموذج تستخلص الخصائص المحلية الأكثر عمومية (مثل الحواف, الألوان و الشكل), أما الطبقات الأكثر عمقاً في النموذج فإنها تقوم بإستخلاص الخصائص الأكثر خصوصية (مثل آذان القطط أو عيون الكلاب مثلاً), لذلك إذا كنَا نريد إنشاء نموذج لتصنيف الصور وهذه الصور تختلف إختلافاً جذرياً عن تلك التي تم تدريب النموذج الأصلي عليها فيجب علينا إستخدام الطبقات الأولى فقط من هذا النموذج لأنها الأكثر عمومية, ماعدا ذلك يمكننا إستخدام جميع الطبقات التابعة لمرحلة إستخلاص الخصائص والتي تتكون من جميع الطبقات الإلتفافية للنموذج (Entire convolutional base).
إنَّ مجموعة البيانات المسماة (ImageNet) والتي تم تدريب النموذج الأصلي عليها تحتوي أيضاً على الكلاب والقطط من بين أصنافها, لذلك يمكننا في حالتنا هذه إستخدام طبقات مرحلة التصنيف (Classification) ماعدا طبقة الإخراج (Output layer) لكننا فضلنا عدم إستخدامها هنا لأجل أن يكون شرح الموضوح أكثر عمومية.
والآن سوف نبدأ بتطبيق ماتطرقنا إليه من خلال إنشاء مشروع نستخدم فيه مرحلة إستخلاص الخصائص (Features Extraction) للنموذج المشهور (VGG16) والمدرب مسبقاً على مجموعة البيانات المسماة (ImageNet) لأجل إستخلاص الخصائص من صور الكلاب والقطط ومن ثم إستخدام هذه الخصائص في تدريب مرحلة التصنيف (dogs vs cats classifier) الخاصة بنا والتي سوف نضيفها إلى مرحلة إستخلاص الخصائص الأصلية.
السطر رقم (1): لإستدعاء الكلاس (VGG16) والذي بواسطته نقوم بإنشاء معمارية النموذج (vgg16) والذي سوف نستخدمه في تطبيقنا.
السطر رقم (2): لإستدعاء الكلاس (ImageDataGenerator) والذي سوف نستخدمه لتحويل بيانات الصور إلى مصفوفة من البيانات الجاهزة لإدخالها على النموذج.
الأسطر من (1) لغاية (14): للإعلان عن القيم الثابتة في التطبيق الغير قابلة للتحديث (Hyper parameters).
السطر رقم (1): لإنشاء النموذج الأصلي وذلك بإستخدام الدالة (VGG16) مع إدخال البيانات التالية لها:
1 – مجموعة البيانات التي تم تدريب النموذج عليها مسبقا, وقد إخترنا مجموعة البيانات المسماة (imagenet).
2 – لكي نتخلص من مرحلة التصنيف (Classification) الخاصة به فقد إخترنا (include_top=False), حيث إنَّ الطبقات العليا هي الطبقات الأخيرة والتي تشمل طبقة الإخراج (Output layer) وباقي طبقات مرحلة التصنيف.
3 – شكل طبقة الإدخال للنموذج الأصلي حيث إخترنا (input_shape=(150, 150, 3)).
عند تنفيذ هذا الكود قد يأخذ بعض الوقت لأجل تحميل ملف الأوزان (Weights) عبر الأنترنت ومن ثم إضافته إلى معمارية النموذج.
نستطيع الآن أن نتعرف على معمارية النموذج (model) والذي يشبه كثيراً معمارية النماذج المختلفة التي قمنا بإنشائها سابقاً, مع فارق مهم وهو عدم إحتوائه على طبقة مسطحة (Flatten layer), وكذلك عدم إحتوائه على طبقات كثيفة (Dense layer) لأننا سوف نقوم لاحقاً بإضافتها من ضمن مرحلة التصنيف (Classifier) الخاص بنا. الشكل التالي يبين الطبقات الأخيرة التي إخترناها من هذا النموذج:
من خلال معمارية النموذج أعلاه نلاحظ أن آخر طبقة من طبقاته تحتوي على (512) من مصفوفات الخصائص (Feature maps), حيث إننا سوف نقوم بإنشاء مصنف الصور (Classifier) الخاص بنا ودمجه مع هذه الطبقة من النموذج الأصلي بعد تدريبه ليشكلان معاً النموذج النهائي الخاص بنا.
لتدريب طبقات مرحلة التصنيف (Classifier layers) الخاصة بنا هناك طريقتان لتحقيق ذلك:
الطريقة الأولى لتنفيذ إستخلاص الخصائص:
نقوم بإدخال مجموعة البيانات الخاصة بنا إلى النموذج الأصلي (model) ونأخذ البيانات الخارجة منه ثم تحويلها إلى مصفوفة من نوع (Numpy) ثم نقوم بحفظها لكي نجعلها بيانات تدريب للمصنف (Classifier) الخاص بنا. من مزايا هذه الطريقة هي سرعتها ولا تستهلك وقتاً ولكن بنفس الوقت لانستطيع إستخدام تقنية الزيادة (Augmentation).
ولنبدأ الآن بتنفيذ هذه الطريقة:
حيث إننا سوف نقوم بإدخال بيانات الصور إلى النموذج (model) عن طريق الكلاس (ImageDataGenerator), حيث يكون هذا النموذج في وضع التوقع أو التنبؤ (Prediction).
السطر رقم (1): إنشاء نسخة أو كائن (Object) من الكلاس (ImageDataGenerator) حيث مررنا إليه معامل واحد هو (rescale) لتحويل بيانات الصور من الصيغة (255 <-- 0) إلى الصيغة (1.0 <-- 0.0).
الأسطر من (1) لغاية (10): لإنشاء دالة تقوم بقراءة بيانات الصور وتحويلها إلى مصفوفة بإستخدام الكائن (generator) الذي قمنا بنسخه من الكلاس (ImageDataGenerator), ثم تقوم بإدخال هذه البيانات إلى النموذج الأصلي (model) وأخذ البيانات الخارجة منه لإستخدامها لاحقاً كبيانات إدخال لمرحلة التصنيف (Classification) الخاصة بنا. هذه الدالة تحتاج إلى معاملين هما المعامل (Directory) الذي يمثل المسار الموضوعة فيه ملفات الصور, وكذلك تحتاج إلى المعامل (steps) الذي يمثل عدد الدفعات التي تتوزع عليها بيانات الصور.
السطر رقم (9): إدخال بيانات الصور (images) التي حصلنا عليها من السطر رقم (2) إلى النموذج الأصلي (model) والذي يكون في حالة التوقع (Prediction) من لأجل الحصول على الخصائص الخارجة من طبقته الأخيرة وإستخدامها لاحقاً في تدريب وإختبار مرحلة التصنيف (Classification) الخاصة بنا.
السطر رقم (1): لإنشاء بيانات الصور الخاصة بتدريب مرحلة التصنيف الخاصة بنا وهذه البيانات هي عبارة عن خصائص خارجة من الطبقة الأخيرة من النموذج (model), وذلك عن طريق إستدعاء الدالة (extract_features) والتي قمنا بإنشائها سابقاً, حيث نقوم بتمرير المسار الذي توجد فيه ملفات الصور الخاصة بالتدريب, وكذلك نمرر لها عدد الدفعات التي تقسم بها بيانات الصور.
السطر رقم (2): لإنشاء بيانات الصور الخاصة بمراقبة صحة مسار التدريب (Validation).
السطر رقم (3): لإنشاء بيانات الصور الخاصة بإختبار وتقييم مرحلة التصنيف الخاصة بنا.
(Ones). حيث إن َّ الرقم (0) يمثل القطط والآخر للكلاب.
السطر رقم (2): إنشاء مصفوفة التسمية (Labels) لبيانات صحة المسار (Validation).
السطر رقم (3): إنشاء مصفوفة التسمية (Labels) لبيانات الإختبار (Testing).
الأسطر من (1) لغاية (5): لإنشاء نموذج هو عبارة عن مرحلة تصنيف (Classification) خاصة بنا حيث نقوم بتدريبه لاحقاً بإستخدام بيانات الخصائص التي حصلنا عليها من النموذج الأصلي ونستخدمها كبيانات تدريب.
السطر رقم (1): لإنشاء نواة للنموذج عن طريق الكلاس (Sequential).
السطر رقم (2): لإضافة طبقة نوع (Flatten). وتعتبر هذه الطبقة هي الطبقة الأولى في نموذجنا حيث يتم إدخال الخصائص التي حصلنا عليها سابقاً كبيانات صور, وكما مر بنا فإن شكل خصائص التدريب (train_features) مثلاً هو (2000, 4, 4, 512), أي أنَّ هناك مصفوفات خصائص عددها (512), وكل مصفوفة من هذه المصفوفات تتكون من (16) وحدة (Unit), فإذا أردنا حساب عدد الوحدات لجميع مصفوفات الخصائص يصبح العدد (4 x 4 x 512 = 8192 units), أي أنَّ الطبقة المستوية (Flatten) التي أنشأناها سوف تتكون من نفس هذا العدد من الوحدات.
السطر رقم (3): لإضافة طبقة كثيفة (Dense) إلى النموذج يحتوي على (1024) من الوحدات, ودالة التنشيط المستخدمة هي (Relu activation function).
السطر رقم (4): لإضافة طبقة إهمال (Dropout) تقوم بإهمال نسبة من الوحدات (Units) حسب الحاجة لتجاوز مشكلة الإفراط في التدريب (Overfitting), وقد حددنا لها نسبة الإهمال (30 %).
السطر رقم (5): إنشاء طبقة إخراج (Output layer) من النوع الكثيف (Dense), وتحتوي هذه الطبق وحدتين (Two units) لأن عدد الأصناف لدينا هي إثنتان (Cats and Dogs). إستخدمنا هنا دالة التنشيط نوع (Softmax).
السطر رقم (1): تهيئة النموذج للتدريب وذلك عن طريق الدالة (compile) وتجهيز النموذج بما يحتاجه من أدوات, حيث نقوم بتمرير أداة حساب قيمة الفقد (Loss) وقد إخترنا الخوارزمية المسماة
(ٍSparse Categorical Crossentropy) حيث إنَّ هذه الخوارزمية تغنينا عن تحويل بيانات التسمية (Label) إلى صيغة (One-hot encoding).
كذلك نمرر لها أداة التحسين (Optimizer), وقد إخترنا الخوارزمية المعروفة تحت إسم (Adam), حيث إخترنا معدل التعلم (Learning rate) المناسب وهو (0.0000065) وذلك عن طريق التجربة.
كذلك مررنا لها نوع المقياس الذي يظهر إثناء التدريب وهو مقياس الدقة (Accuracy).
السطر رقم (6): لعرض نبذه عن معمارية النموذج.
السطر رقم (1): البدأ بعملية تدريب النموذج الخاص بنا (my_model) وذلك عن طريق الدالة (fit) حيث نمرر لها المعاملات التالية:
1 – بيانات صور التدريب وقد إستخدمنا بيانات الخصائص التي حصلنا عليها من النموذج الأصلي.
2 – بيانات التسمية (Labels) الخاصة باتدريب.
3 – حجم كل دفعة من البيانات.
4 – عدد مرات تكرار نفس البيانات (Epochs).
5 – بيانات تقييم صحة مسار التدريب (Validation) والتي أيضاً حصلنا عليها من النموذج الأصلي.
السطر رقم (1): لتقييم النموذج (Model Evaluation) وذلك عن طريق الدالة (evaluate), ونقوم بتمرير المعاملات التالية لها:
1 – بيانات صور الإختبار والتي هي عبارة عن بيانات خصائص حصلنا عليها من النموذج الأصلي.
2 – بيانات تسميات الإختبار (test_labels).
3 – حجم الدفعة من البيانات.
4 – الإطناب في عرض مايدور إثناء عملية التقييم.
السطر رقم (5): لطباعة قيمة الفقد (Loss).
السطر رقم (6): لطباعة قيمة الدقة (Accuracy).
من خلال الصورة أعلاه نلاحظ أننا قد حصلنا على دقة (90.5 %) تقريباً بإستخدام هذه التقنية بالرغم من أننا قد إستخدمنا مجموعة صغيرة جداً من البيانات تشكل نسبة (10 %) من البيانات التي إستخدمناها في النموذج الذي أنشأناه في الفقرة السابقة.
وفي حالة إستخدامنا النموذج المشهور المسمى (ResNet101V2) فإننا سوف نحصل على دقة تصل إلى أكثر من (97 %).
أما في حالة إستخدامنا النموذج (MobileNetV2) فإننا سوف نحصل على دقة (95.5 %) تقريباً.
أما إذا إستخدمنا النموذج (InceptionV3) فإننا سوف نحصل على دقة (95.9 %) تقريباً.
ملاحظة: في حالة إستخدامنا لهذه النماذج فإنَّ الكود السابق يبقى على وضعه ماعدا الكود الخاص بإنشاء النموذج وكما مبين أدناه:
تعليقات
إرسال تعليق