القائمة الرئيسية

الصفحات

التعلم العميق وإستخداماته في الرؤية الحاسوبية - الجزء الثامن

التعلم العميق وإستخداماته في الرؤية الحاسوبية - الجزء الثامن
يتضمن هذا الجزء أنشاء تصنيف الأرقام المكتوبة بخط اليد Handwritten digits بأستخدام مكتبة keras






التعلم العميق وإستخداماته في الرؤية الحاسوبية - الجزء الثامن

Deep Learning for Computer Vision- part 8












المهندس حسن فنجان عداي



بسم إلله الرحمن الرحيم

بدأنا في المقالة السابقة بإستعراض أحد المواضيع المهمة من مواضيع الرؤية الحاسوبية ألا وهو موضوع التصنيف (Classification) حيث تناولناه بشيءٍ من التوضيح وقمنا بإنشاء أحد التطبيقات الخاصة بتصنيف الأرقام المكتوبة بخط اليد (Handwritten digits classifier) وشرحنا الكود الخاص به شرحاً وافياً, حيث إستخدمنا مكتبة (tensorflow) في كتابة الكود, ولاحظنا دقة النموذج (Accuracy) التي حصلنا عليها وكانت مايقارب (98%), في هذه المقالة سوف نقوم إن شاء ألله بإنشاء وتنفيذ تطبيق يقوم بتصنيف الأرقام العربية المكتوبة بخط اليد.


تصنيف الأرقام العربية المكتوبة بخط اليد:

(Classification of handwritten Arabic numerals)

سوف نقوم بإنشاء نموذج (Model) يتكون من عدة طبقات عصبية إصطناعية (Layers) وبإسلوب التعلم العميق (Deep Learning), حيث يقوم هذا النموذج بمهمة تصنيف أرقام عربية (من صفر إلى تسعة) مكتوبة بخط اليد وبنفس الأسلوب الذي إتبعناه في تصنيف الأرقام الإنكليزية في المقالة السابقة.

لاتوجد مجموعة بيانات (Dataset) لهذه الأرقام مرتبة بالشكل الذي عليه مجموعة الأرقام الإنكليزية (MNIST dataset), بل توجد على هيئة مجموعة ملفات لصور ذات إمتداد (png), أو على شكل ملفات (Exel) ذات إمتداد (csv), لذلك يجب علينا أولاً أن نقوم بإنشاء مجموعة البيانات من أحد هذين المصدرين.

أولاً: إنشاء مجموعة البيانات بإستخدام ملفات الصور:

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


شرح الكود:

الأسطر من (1) إلى (8): لإستدعاء المكتبات والكلاسات والدوال الضرورية لإنشاء وتدريب النموذج.

السطر رقم (1): للإعلان عن عدد الأصناف التي سوف يقوم النموذج بترتيب الأرقام بموجبها.

الأسطر من (1) إلى (15): لإنشاء الدالة التي تقوم بتهيئة مجموعة البيانات التي سوف نستخدمها في تدريب وفحص النموذج. تحتاج هذه الدالة غلى معامل (Parameter) واحد وهو المسار الذي توجد فيه ملفات الصور.

السطر رقم  (2): للإعلان عن مصفوفة نوع (List) لكي نقوم بإيداع بيانات الصور فيها بشكل مؤقت.

السطر رقم  (3):  للإعلان عن مصفوفة إعتيادية خاصة لإيداع بيانات التسميات (Labels) فيها.

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

السطر رقم  (5): جملة شرطية تشترط أن يكون إسم الملف ذو إمتداد (png).

السطر رقم  (6): لقراءة بيانات الصورة لكل ملف وإيداعه مؤقتاً في متغير إسمه (im) وذلك عن طريق الدالة (open) حيث نمرر لها مسار الملفات وإسم كل ملف تباعاً.

السطر رقم  (7): نقوم بتحويل بيانات الصورة المستحصلة من الخطوة السابقة إلى مصفوفة نوع (Numpy) لكي يمكننا إجراء بعض التعديلات عليها وتكون منسجمة مع مكتبة (Tensorflow).

السطر رقم  (8): لإيداع المصفوفة (sampleimage) التي حصلنا عليها من الخطوة السابقة في المصفوفة (images)  التي أعلنا عنها في البداية لكي نقوم بتجميع كل بيانات الصور فيها.

السطر رقم  (9): لإستخلاص تسمية كل ملف (Label) من إسم الملف وإيداعه مؤقتاً في متغير إسمه (label).

السطر رقم  (10): لإيداع التسمية التي حصلنا عليها من الخطوة السابقة في المصفوفة (label_list) التي أعلنا عنها في بداية الدالة لكي نقوم بتجميع كل تسميات الصور فيها.

السطر رقم  (11): بعد إنتهاء الحلقة التكرارية وبعد قراءة بيانات جميع الصور وحفظها في المصفوفة (images) نقوم بتحويل هذه المصفوفة إلى أخرى من نوع (Numpy) وإيداعها في مصفوفة إسمها (x_created).

السطر رقم  (12): نقوم بتغيير شكل بيانات الصور من متجه (Vector) ذات بعد واحد إلى شكلها الطبيعي (28 x 28) بيكسل يضاف لها عدد الصور والذي يشكل البعد الثالث.

السطر رقم  (13): إضافة بعد رابع إلى المصفوفة (x_created) والذي يمثل عدد الألوان (Channels) للصورة علماً بأن الصور التي لدينا هي غير ملونة (تدرج رمادي) وبالتالي يكون البعد الرابع هو (1).

السطر رقم  (14): لتحويل بيانات المصفوفة (label_list) التي تضم التسميات إلى بيانات مشفرة من نوع (One-hot encoding).

السطر رقم  (15): إختار القيم الراجعة للدالة.

السطر رقم  (1): إستدعاء الدالة (create_img_mat_and_label) وتمرير مسار ملفات الصور الخاصة بالتدريب لأجل الحصول على مجموعة البيانات الخاصة بتدريب النموذج.

السطر رقم  (2): إستدعاء الدالة وتمرير مسار ملفات الصور الخاصة بالفحص لأجل الحصول على مجموعة البيانات الخاصة بفحص النموذج.


ثانياً: إنشاء مجموعة البيانات بإستخدام ملفات إكسل (csv Files):

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

الأسطر من (1) إلى (4): إستدعاء المكتبات الضرورية للعمل, ونلاحظ أننا إستدعينا دالة جديدة هي (train_test_split) التابعة إلى المكتبة (scikit-learn) وذلك لحاجتنا إليها من أجل إستخلاص جزء من بيانات التدريب لتشكيل بيانات خاصة لمراقبة سير التدريب (Validation).

السطر رقم (1): للإعلان عن عدد ثابت يمثل عدد الأصناف (Classes) أي عدد الأرقام في تطبيقنا (من الرقم صفر إلى الرقم تسعة).

الأسطر من (1) إلى (4): لقراءة البيانات الموجودة في الملفات نوع (csv) الخاصة لبيانات التدريب وبيانات الفحص ويتم إيداع تلك البيانات في متغيرات بشكل مؤقت, علماً إنَّ هذه البيانات تكون على هيئة مصفوفات ذات بعدين, البعد الأول يمثل عدد الصور والبعد الثاني يمثل بيانات الصور أو بيانات التسميات (Labels).

الأسطر من (1) إلى (5): لتحويل بيانات الصور (Images) وبيانات التسميات (Labels) الخاصة بالتدريب والفحص إلى مصفوفات من نوع (Numpy) لكي يمكن التعامل معها من حيث المعالجات وكذلك لكي تنسجم مع مكتبة (Tensorflow).

السطرين (7) و (8): لطباعة شكل (Shape) مصفوفتي بيانات الصور الخاصتين بالتدريب والفحص.

الأسطر من (1) إلى (6): لإنشاء مصفوفة تقوم بعملية تصحيح لبيانات الصور لأن هذه البيانات قد تم التلاعب بها لكي لاتكون صالحة للإستخدام إلا بعد إجراء عملية التصحيح عليها. هذه الدالة تحتاج إلى معاملين (Parameters) هما بيانات الصور وكذلك عدد هذه الصور.

السطر رقم (2): لتغيير شكل مصفوفة بيانات الصور من مصفوفة ذات بعدين إلى أخرى ذات ثلاثة أبعاد, حيث أنَّ البعد الأول يمثل عدد الصور والبعدين الثاني والثالث يمثلان إرتفاع وعرض كل صورة. قمنا بهذا الإجراء لكي يتبين لنا ماهو التصحيح المطلوب وذلك من خلال رؤية نماذج من الصور.

السطر رقم (3): إنشاء حلقة تتكرر بمقدار عدد الصور.

السطر رقم (4): لقلب الصورة أفقياً (أي اليمين يحل محل اليسار وبالعكس) بواسطة الدالة (flip) وقد إخترنا الرقم (1) لهذا الغرض.

السطر رقم (5): لتدوير الصورة (90 درجة ) عكس إتجاه عقرب الساعة.

الأسطرمن (1) إلى (9): إنشاء دالة تقوم بعملية تطبيع (Normalization) لبيانات الصور لكي تكون مناسبة لعملية التدريب وكذلك لعملية الفحص, حيث تقوم هذه الدالة بتحويل قيم نقاط الصورة (Pixles) إلى قيم تتراوح مابين صفر إلى واحد بدلا من أن تتراوح مابين (صفر إلى 255), وهذا يقتضي تحويلها أولاً إلى قيم من نوع (Float), ثم تتم قسمتها على العدد (255).

السطر رقم (1): لإجراء عملية التصحيح على بيانات الصور لمجموعة التدريب (Training) عن طريق إستدعاء الدالة (image_correction) والتي قمنا بإنشائها لهذا الغرض.

السطر رقم (2): للقيام بعملية إنتقاء (6000) صورة من مجموعة صور التدريب لغرض إستخدامها في عملية مراقبة صحة سير التدريب (Validation).

السطر رقم (6): لإجراء عملية التصحيح على بيانات الصور لمجموعة الفحص (Testing).

السطران (8) و (9): لتشفير قيم مصفوفتي التسميات (Labels) لكل من بيانات التدريب والفحص, والتشفير المستخدم هو من نوع (One-hot encoding).

الأسطر من (11) إلى (13): للقيام بعملية التطبيع لبيانات الصور عن طريق الدالة (normalization_data).

وبهذا نكون قد إنتهينا من عملية تهيئة البيانات المناسبة للنموذج لكي نقوم بعمليات التدريب والفحص والتقييم.

والآن نقوم بإنشاء النموذج وكما يلي:


السطر رقم  (2): إنشاء نواة النموذج عن طريق الدالة (Sequential).

الأسطر من (3) إلى (10): لإضافة بعض الطبقات الضرورية للنموذج.

السطر رقم  (12): لإظهار مخطط يلخص مكونات النموذج.




السطر رقم  (2): نقوم بتهيئة النموذج قبل عملية التدريب وذلك عن طريق الدالة (compile) حيث نقوم بإختيار دالة الفقد (Loss function) وكذلك تقنية التحسين (Optimizer).

سطر رقم  (2):  للقيام بعملية التدريب وذلك عن طريق الدالة (fit) حيث نقوم بتزويدها بمجموعة بيانات التدريب وكذلك بيانات الفحص التي تستخدم هنا للفحص المستمر (أي بعد كل حقبة من التدريب) لأجل مراقبة صحة مسيرة التدريب (Validation), وكذلك نقوم بتحديد عدد حقب التدريب (Epochs) وكذلك حجم كل دفعة من بيانات التدريب (Batch size).

السطر رقم  (10): إعطاء الإيعاز من أجل حفظ البيانات الخاصة بالنموذج المدرب في ملف مستقل ذو إمتداد (h5).


السطر رقم  (2): لإجراء عملية التقييم للنموذج المدرب عن طريق الدالة (evaluate) حيث نقوم بتزويدها بالبيانات الخاصة بالفحص, ثم نقوم بطباعة النتائج.

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


إستعادة النموذج  وإستخدامه في عملية التوقع 

نقوم الآن بعملية إستعادة نموذجنا الذي قمنا بتدريبه وحفظه في ملف ذو إمتداد (h5), وسوف نستخدم هذا النموذج بعد إستعادته من الملف في عملية التوقع (Prediction) وذلك بإدخال بعض الصور الجديدة التي لم يتدرب عليها ومعرفة مايقوم به من أداء لتصنيفها وإعطائنا الأصناف التي تنتمي إليها الأرقام الموجودة في هذه الصور, حيث نقوم أولاً بعملية تهيئة لهذه البيانات المدخلة إلى النموذج وكما يلي:

الأسطر من (1) إلى (4): إستدعاء المكتبات الضرورية للعمل.

السطر رقم (1): لإستعادة نموذجنا الذي قمنا بتدريبه وذلك عن طريق الدالة (load_model) حيث قمنا بتمرير المسار الموجود فيه الملف الذي يحتوي على النموذج وفي حالتنا هو موجود في مجلد المشروع.

السطر رقم (2): لعرض ملخص لمكونات النموذج المستعاد.

نلاحظ إن البيانات لهذا النموذج المستعاد مطابقة تماماً لبيانات النموذج الأصلي.

نقوم الآن بعملية تهيئة للصور المراد إدخالها إلى النموذج لمعرفة توقعاته, حيث نقوم أولاً بتحويل هذه الصور إلى بيانات تتطابق مع بيانات الإدخال المدرب عليها النموذج, علماً إننا لانحتاج هنا إلى بيانات تسمية (Labels) لأنَّ النموذج سوف يعمل في طور التوقع (Prediction).



السطر رقم (1): تحديد المساحة التي سوف نقوم بعرض نتائج التوقع فيها.

السطر رقم (2): تحديد عدد الصور التي نريد إدخالها إلنموذج.

السطر رقم (3): العبارة التي تمثل الصنف الذي يتوقعه النموذج.

السطر رقم (4): إنشاء حلقة تتكرر بعدد الصور المدخلة.

السطر رقم (5): لقراءة بيانات الصور الواحدة تلو الأخرى وإيداع بيانات الصورة الواحدة في متغير إسمه (img) بشكل مؤقت ويتم قراءة بيانات الصورة عن طريق الدالة (open) العائدة إلى مكتبة (Pillow), حيث نمرر لها مسارالمجلد الموضوعة فيه ملفات الصور وإسم كل ملف تباعاً. نقوم بعدها بتحويل بيانات الصورة إلى تدرج رمادي (Gray scale) أي مصفوفة ذات بعدين فقط وذلك عن طريق الدالة (convert) وإعطائها العبارة (L’) والتي ترمز إلى التدرج الرمادي.

السطر رقم (6): تقليص حجم الصورة إلى قياس (28 x 28) بما يتناسب مع الصور التي تدرب عليها النموذج.

السطر رقم (7): تحويل بيانات الصورة إلى مصفوفة من نوع (Numpy) ليسهل علينا إضافة بعدين آخرين.

السطر رقم (8): تغيير شكل المصفوفة التي تحوي بيانات الصورة من مصفوفة ذات بعدين (28 x 28) إلى مصفوفة ذات أربعة أبعاد (1 x 28 x 28 x 1) لكي تنسجم مع مايحتاجه النموذج.

السطر رقم (9): إدخال بيانات الصورة إلى النموذج لأجل الحصول على التوقع (Prediction), أي إعطاء الصورة المدخلة صنفها المتوقع وذلك بإستخدام الدالة (predict_classes) وتمرير بيانات الصورة إليها وإيداع التوقع في متغير إسمه (y_pred).

السطر رقم (11): لتحديد مكان إظهار الصورة وذلك عن طريق الدالة (subplot) العائدة للمكتبة (Matplotlib) حيث إننا سوف نقوم بإظهار الصور على شكل شبكة متكونة من (4) صفوف و (7) أعمدة.

السطر رقم (12): لإظهار الصورة حسب موقعها الذي حددناه في الخطوة السابقة وذلك عن طريق الدالة (imshow) وقد إخترنا أن تظهر الصورة على شكل تدرج رمادي وذلك عن طريق العبارة (gray).

السطر رقم (13): تحويل نتيجة التوقع إلى متغير نوع (String) لكي يمكن إظهاره مع الصورة التي يخصها.

السطر رقم (14): إضافة نتيجة التوقع على شكل عنوان (Title) إلى الصورة.

وعند تنفيذ الكود نحصل على النتيجة التالية:

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


ملاحظة:

إذا أردنا إدخال صور بخلفية بيضاء وكتابة سوداء نقوم بكتابة كود إضافي إلى الكود السابق وكما يلي:

حيث إنَّ الكود المضاف هو الذي داخل المستطيل الأصفر, حيث نقوم بإجراء عملية قلب للصورة ذات الخلفية البيضاء. وعند تنفيذ الكود نحصل على مايلي:


وبهذا نكون قد إنتهينا من هذه المقالة آملين أن تكون مفيدة لمتابعي موقعنا وشكراً لمتابعتكم.





المهندس حسن فنجان عداي











هل اعجبك الموضوع :

تعليقات

تعليقان (2)
إرسال تعليق

إرسال تعليق