دمج نموذج مخصّص في تطبيقك

1. قبل البدء

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

في هذا الدرس التطبيقي حول الترميز، ستُحدِّث التطبيق من التمرين المعملي الأول بالنموذج من التطبيق الثاني.

يمكنك الحصول على رمز المصدر الكامل للدرس التطبيقي حول الترميز من خلال استنساخ هذا المستودع. ستظهر لك الأدلة الفرعية لنظامَي التشغيل Android وiOS. يتوفّر رمز الدرس التطبيقي السابق باسم ImageClassifierStep1 إذا كنت تريد المتابعة. يتوفّر الرمز النهائي لهذا الدرس التطبيقي باسم ImageClassifierStep2.

المتطلبات الأساسية

  • يجب أن تكون قد أكملت أول درسَين تطبيقيَين حول الترميز في هذا المسار التعليمي.

ما الذي ستبنيه وتتعلمه

  • دمج نموذج مخصّص تم تدريبه في التمرين المعملي السابق في تطبيق Android أو iOS

المتطلبات

  • Android Studio، متاح على developer.android.com/studio لجزء Android من التمرين المعملي
  • Xcode، متوفّر في Apple App Store، لجزء iOS من التمرين المعملي

2. الحصول على تطبيق Starter

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

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

f3703d45d1332d1d.png

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

3- يُرجى تعديل Build.gradle لاستخدام نماذج حزمة تعلُّم الآلة المخصّصة.

  1. باستخدام "استوديو Android"، ابحث عن ملف build.gradle على مستوى التطبيق. أسهل طريقة للقيام بذلك هي مستكشف المشروعات. تأكد من تحديد Android في الجزء العلوي، وسترى مجلدًا لـ Gradle Scripts في الجزء السفلي.
  2. افتح التطبيق المخصّص للوحدة الذي يتضمّن اسم تطبيقك متبوعًا بـ " .app". كما هو موضّح هنا (الوحدة: ImageClassifierStep1.app):

8fe1d04b40610047.png

  1. في أسفل الملف، ابحث عن إعداد التبعيات. ومن المفترض أن يظهر لك هذا السطر:
implementation 'com.google.mlkit:image-labeling:17.0.1'

قد يكون رقم الإصدار مختلفًا. يمكنك دائمًا العثور على أحدث رقم من موقع ML Kit على الرابط: https://developers.google.com/ml-kit/vision/image-labeling/android.

  1. استبدِل هذا بمرجع مكتبة تصنيف الصور المخصّص. يمكنك العثور على رقم الإصدار الخاص بذلك على الرابط: https://developers.google.com/ml-kit/vision/image-labeling/custom-models/android.
implementation 'com.google.mlkit:image-labeling-custom:16.3.1'
  1. بالإضافة إلى ذلك، ستضيف نموذج tflite .الذي أنشأته في التمرين المعملي السابق. لا تريد ضغط هذا النموذج عندما يجمع "استوديو Android" تطبيقك، لذا عليك استخدام هذا الإعداد في قسم Android من ملف build.gradle نفسه:
aaptOptions{
    noCompress "tflite"
}

تأكَّد من أنّها ليست ضمن أي إعداد آخر. ويجب دمجه مباشرةً ضمن العلامة android. وفي ما يلي مثال لذلك:

62d546bff11d2a50.png

4. إضافة نموذج TFLite

في الدرس التطبيقي السابق حول الترميز، أنشأت نموذجك المُخصَّص ونزّلته باسم model.tflite.

في مشروعك، ابحث عن مجلد مواد العرض الذي يحتوي حاليًا على "flower1.jpg". انسخ النموذج إلى هذا المجلد على النحو التالي:

  1. انقر بزر الماوس الأيمن على مجلد مواد العرض في "استوديو Android". في القائمة التي تظهر، انقر على الإظهار في Finder (الباحث). ("العرض في Explorer" على نظام التشغيل Windows، و"العرض في الملفات" على نظام التشغيل Linux).

db30b47e419a326b.png

  1. سيتم نقلك إلى الدليل في نظام الملفات. انسخ الملف model.tflite إلى ذلك الدليل، إلى جانب flower1.jpg..

36de0c51bec1c19e.png

سيتم تحديث "استوديو Android" لإظهار كلا الملفين في مجلد مواد العرض:

e9f4e9f394d9b357.png

يمكنك الآن تعديل الرمز.

5- تحديث الرمز للنموذج المخصّص

تتمثل الخطوة الأولى في إضافة بعض الرموز لتحميل النموذج المخصّص.

  1. في ملف MainActivity، أضِف ما يلي إلى onCreate مباشرةً أسفل السطر التالي: setContentView(R.layout.activity_main).

وسيستخدم هذا النموذج LocalModel للإنشاء من مادة العرض model.tflite. في حال تقديم شكوى من "استوديو Android" من خلال تحويل "LocalModel" الأحمر، اضغط على ALT + Enter لاستيراد المكتبة. من المفترض أن تتم إضافة عملية استيراد إلى com.google.mlkit.common.model.LocalModel نيابةً عنك.

val localModel = LocalModel.Builder()
        .setAssetFilePath("model.tflite")
        .build()

في السابق، كنت تستخدم النموذج التلقائي في معالج btn.setOnClickListener. تم إعداد الجهاز باستخدام الرمز التالي:

val labeler = ImageLabeling.getClient(ImageLabelerOptions.DEFAULT_OPTIONS)

وستستبدلها لاستخدام النموذج المخصص.

  1. إعداد كائن خيارات مخصّصة:
val options = CustomImageLabelerOptions.Builder(localModel)
        .setConfidenceThreshold(0.7f)
        .setMaxResultCount(5)
        .build()

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

يمكنك فلترة النتائج ذات الجودة المنخفضة بشكل فعّال باستخدام حد عالٍ من الثقة. فعلى سبيل المثال، لا يؤدي الضبط على 0.9 إلى عرض أي تصنيف له أولوية أقل من ذلك. يُعد setMaxResultCount() مفيدًا في النماذج التي تحتوي على العديد من الصفوف، ولكن بما أن هذا النموذج يحتوي على 5 فقط، فسوف تتركه عند رقم 5 فقط.

الآن وبعد أن أصبحت لديك خيارات للمصنِّف، يمكنك تغيير مثيل المصنِّف إلى:

val labeler = ImageLabeling.getClient(options)

سيتم تشغيل بقية الرمز بدون تعديل. ننصحك بتجربة ذلك.

dd40c36c4edbb33.png

وهنا يمكنك ملاحظة أنّه قد تمّ التعرّف على هذه الزهرة الآن كزهرة أقحوان باحتمالية 959.

لنفترض أنك أضفت صورة زهرة ثانية، وأعدت عرضها على النحو التالي:

8556a5fbea487842.png

يحددها على أنها وردة.

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

6- الحصول على تطبيق Start (بدء) على أجهزة iOS

  1. عليك أولاً تثبيت التطبيق من أول درس تطبيقي حول الترميز. إذا كنت قد أكملت خطوات التمرين المعملي، سيصبح اسمها ImageClassifierStep1. إذا كنت لا تريد خوض التجربة الاختبارية، يمكنك استنساخ النسخة النهائية من المستودع. يُرجى ملاحظة أنّ المجموعات pod و .xcworkspace غير متوفّرة في المستودع، لذا قبل المتابعة إلى الخطوة التالية، يجب التأكّد من تشغيل pod install. من نفس الدليل مثل xcproject.
  2. افتح ImageClassifierStep1.xcworkspace في Xcode. وتجدُر الإشارة إلى أنّه يجب استخدام .xcworkspace وليس .xcproject لأنّك استخدمت حزمة تعلّم الآلة في مجموعات، وستحمِّل مساحة العمل هذه الملفات.

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

شغِّلها وسيظهر لك شيء على النحو التالي:

9e151ed18f99fb98.png

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

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

7. استخدام مجموعات تصنيف الصور في حزمة تعلّم الآلة المخصّصة

استخدَم التطبيق الأول ملف لوحة للحصول على مكتبات وطرازات أداة تصنيف الصور الأساسية في ML Kit. سيتوجّب عليك تحديث ذلك لكي تتمكن من استخدام مكتبات تصنيف الصور المخصصة.

  1. ابحث عن الملف المسمى podfile في دليل مشروعك. افتحه، وسيظهر لك شيء مثل هذا:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabeling'
end
  1. يمكنك تغيير بيان المجموعة من ImageLabeling إلى ImageLabelingCustom، كما يلي:
platform :ios, '10.0'

target 'ImageClassifierStep1' do
        pod 'GoogleMLKit/ImageLabelingCustom'
end
  1. بعد الانتهاء، استخدِم الوحدة الطرفية للانتقال إلى الدليل الذي يحتوي على ملف podfile (بالإضافة إلى ملف xcworkspace). وشغِّل pod install.

bb5d78eb7c7ab975.png

بعد بضع لحظات، ستتم إزالة مكتبات MLKitImageLabeling وإضافة المكتبات المخصّصة. يمكنك الآن فتح ملف xcworkspace .لتعديل الرمز البرمجي.

8. إضافة نموذج TFLite إلى Xcode

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

  1. مع فتح مساحة العمل في Xcode، اسحب model.tflite إلى مشروعك. من المفترض أن يكون الملف في المجلد نفسه الذي يتضمّن بقية ملفاتك، مثل ViewController.swift أو Main.storyboard.
  2. ينبثق مربع حوار يحتوي على خيارات لإضافة الملف. تأكّد من اختيار إضافة إلى الأهداف، وإلا لن يتم دمج النموذج مع التطبيق عند نشره على أحد الأجهزة.

تجدر الإشارة إلى أنّ خيار "الإضافة إلى الأهداف" سيحتوي الإدخال على ImageClassifierStep1 إذا كنت قد بدأت من ذلك وتستمر في هذا التمرين خطوة بخطوة أو ImageClassifierStep2 (كما هو موضح) إذا انتقلت إلى الرمز النهائي.

5b6a7f40c73f0f1f.png

سيضمن هذا الإجراء تحميل النموذج. يمكنك الاطّلاع على كيفية إجراء ذلك في الخطوة التالية.

9. تحديث الرمز للنموذج المخصّص

  1. افتح ملف ViewController.swift. قد تظهر لك رسالة خطأ عند استيراد ملف MLKitImageLabeling. في الجزء العلوي من الملف. ويرجع ذلك إلى أنّك أزلت مكتبات تصنيف الصور العامة عند تعديل ملف المجموعة. يمكنك حذف هذا السطر وتحديثه بما يلي:
import MLKitVision
import MLKit
import MLKitImageLabelingCommon
import MLKitImageLabelingCustom

قد يكون من السهل أن تقرأ هذه وتعتقد أنها تكرر نفس التعليمة البرمجية! لكنها "شائعة" و"مخصّص" في النهاية!

  1. عليك بعد ذلك تحميل النموذج المخصّص الذي أضفته في الخطوة السابقة. البحث عن تقنية "getLabels()" أسفل السطر المكتوب عليه "visionImage.orientation = image.imageOrientation"، أضِف السطور التالية:
// Add this code to use a custom model
let localModelFilePath = Bundle.main.path(forResource: "model", ofType: "tflite")
let localModel = LocalModel(path: localModelFilePath!)
  1. ابحث عن الرمز لتحديد خيارات عنصر ImageLabeler العام. قد يرجع ذلك إلى خطأ بسبب إزالة هاتين المكتبات:
let options = ImageLabelerOptions()

استبدِلها بهذا الرمز البرمجي لاستخدام CustomImageLabelerOptions والذي يحدد النموذج المحلي:

let options = CustomImageLabelerOptions(localModel: localModel)

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

238cd21748a97cf4.png

لنفترض أنك أضفت صورة زهرة ثانية، وأعدت عرضها على النحو التالي:

75f3970a6b509bfe.png

رصَد التطبيق بنجاح أنّ هذه الصورة تطابق التصنيف "ورود".

10. تهانينا!

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

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

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