كيفية التعرف على الصور والنصوص على هاتفك باستخدام ML Kit


قبل عامين ، قال Sundar Pichai ، رئيس Google ، إن الشركة من mobile-first تصبح AI-first وتركز على التعلم الآلي. بعد مرور عام ، تم إصدار مجموعة أدوات التعلم الآلية - وهي مجموعة من الأدوات التي يمكنك من خلالها استخدام ML على iOS و Android بشكل فعال.


هناك الكثير من الحديث حول ML Kit في الولايات المتحدة الأمريكية ، ولكن لا توجد معلومات باللغة الروسية تقريبًا. وبما أننا نستخدمها في بعض المهام في Yandex.Money ، فقد قررت مشاركة تجربتي مع أمثلة حول كيفية استخدامها للقيام بأشياء مثيرة للاهتمام.


اسمي Yura في العام الماضي ، كنت أعمل في فريق Yandex.Money على محفظة نقالة. سنتحدث عن التعلم الآلي على الهاتف المحمول.




تقريبا. الافتتاحية: هذا المنشور عبارة عن إعادة سرد لتقرير يوري شيشتكن "من الجوال أولاً إلى الذكاء الاصطناعي أولاً" من Yandex.Money Android Paranoid mitap.


ما هي مجموعة ML؟


هذا هو SDK للأجهزة المحمولة من Google والذي يجعل من السهل استخدام التعلم الآلي على أجهزة Android و iOS. ليس من الضروري أن تكون خبيرًا في ML أو في الذكاء الاصطناعي ، لأنه في بضعة سطور من التعليمات البرمجية يمكنك تنفيذ أشياء معقدة للغاية. علاوة على ذلك ، ليس من الضروري معرفة كيفية عمل الشبكات العصبية أو تحسين النماذج.


ماذا يمكن أن تفعل ML Kit؟


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


استخدمنا بالفعل التعرف على رمز الاستجابة السريعة في تطبيق Yandex.Money.


هناك أيضا مجموعة ML


  1. التعرف على المعالم
  2. تعريف اللغة التي يتم بها كتابة النص ؛
  3. ترجمة النصوص على الجهاز ؛
  4. الرد السريع على رسالة أو رسالة.

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


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


1


التعرف على النص


المهمة: إعطاء صورة ، تحتاج إلى الحصول على نص دائري في مستطيل.


نبدأ بالتبعية في Gradle. يكفي توصيل تبعية واحدة ، ونحن مستعدون للعمل.


dependencies { // ... implementation'com.google.firebase:firebase-ml-vision:20.0.0' } 

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


 <application ...> ... <meta-data android:name="com.google.firebase.ml.vision.DEPENDENCIES" android:value="ocr" /> <!-- To use multiple models: android:value="ocr,model2,model3" --> </application> 

بعد تكوين المشروع ، تحتاج إلى تعيين قيم الإدخال. يعمل ML Kit مع نوع FirebaseVisionImage ، لدينا خمس طرق ، التوقيع الذي كتبته أدناه. إنهم يحولون الأنواع المعتادة من Android و Java إلى أنواع ML Kit ، والتي من السهل التعامل معها.


 fun fromMediaImage(image: Image, rotation: Int): FirebaseVisionImage fun fromBitmap(bitmap: Bitmap): FirebaseVisionImage fun fromFilePath(context: Context, uri: Uri): FirebaseVisionImage fun fromByteBuffer( byteBuffer: ByteBuffer, metadata: FirebaseVisionImageMetadata ): FirebaseVisionImage fun fromByteArray( bytes: ByteArray, metadata: FirebaseVisionImageMetadata ): FirebaseVisionImage 

انتبه للأخيرتين - تعملان مع مجموعة من وحدات البايت ومع مخزن مؤقت للبايت ، ونحن بحاجة إلى تحديد البيانات الأولية حتى يفهم ML Kit كيفية التعامل معها كلها. في الواقع ، تصف البيانات الوصفية ، في هذه الحالة ، العرض والارتفاع ، التنسيق الافتراضي ، IMAGE_FORMAT_NV21 والدوران.


 val metadata = FirebaseVisionImageMetadata.Builder() .setWidth(480) .setHeight(360) .setFormat(FirebaseVisionImageMetadata.IMAGE_FORMAT_NV21) .setRotation(rotation) .build() val image = FirebaseVisionImage.fromByteBuffer(buffer, metadata) 

عندما يتم جمع بيانات الإدخال ، أنشئ كاشف يتعرف على النص.


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


 //  onDevice val detector = FirebaseVision.getInstance().getOnDeviceTextRecognizer() // onCloud with options val options = FirebaseVisionCloudTextRecognizerOptions.Builder() .setLanguageHints(arrayOf("en", "ru")) .build() val detector = FirebaseVision.getInstance().getCloudTextRecognizer(options) 

يزيد عدد اللغات المدعومة عن 20 لغة ، وكلها على الموقع الرسمي. في مثالنا ، فقط الإنجليزية والروسية.


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


 val result: Task<FirebaseVisionText> = detector.processImage(image) .addOnSuccessListener { result: FirebaseVisionText -> // Task completed successfully // ... } .addOnFailureListener { exception: Exception -> // Task failed with an exception // ... } 

كيفية العمل مع نوع FirebaseVisionText؟


وهي تتألف من كتل نصية (TextBlock) ، وتتألف تلك بدورها من خطوط (Line) وخطوط عناصر (Element). فهي متداخلة في بعضها البعض.


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


 FirebaseVisionText contains a list of FirebaseVisionText.TextBlock which contains a list of FirebaseVisionText.Line which is composed of a list of FirebaseVisionText.Element. fun getBoundingBox(): Rect // axis-aligned bounding rectangle of the detected text fun getConfidence(): Float // confidence of the recognized text fun getCornerPoints(): Array<Point> // four corner points in clockwise direction fun getRecognizedLanguages(): List<RecognizedLanguage> // a list of recognized languages fun getText(): String //recognized text as a string 

ما هذا؟


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


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


التعرف على الأشياء في الصورة


2


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


 // onDevice val detector: FirebaseVisionImageLabeler = FirebaseVision .getInstance() .getOnDeviceImageLabeler() // onCloud with minimum confidence val options = FirebaseVisionCloudImageLabelerOptions.Builder() .setConfidenceThreshold(0.7f) .build() val detector: FirebaseVisionImageLabeler = FirebaseVision .getInstance() .getCloudImageLabeler(options) 

هارولد يختبئ السعادة


3


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


4


من السهل إلى السهل ، ولكن أكثر تعقيدا قليلا. نماذج مخصصة.


المهمة: تصنيف ما هو مبين في الصورة.


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


7


عند العمل مع الطرز المخصصة ، يمكننا أيضًا العمل معهم على الجهاز وعبر السحاب.


إذا عملنا عبر السحابة ، فأنت بحاجة إلى الانتقال إلى Firebase Console ، إلى علامة التبويب ML Kit ، والنقر المخصص ، حيث يمكننا تحميل النموذج الخاص بنا إلى TensorFlow Lite ، لأن ML Kit يعمل مع الطرز بهذا القرار. إذا استخدمناه على جهاز ، فيمكننا ببساطة وضع النموذج في أي جزء من المشروع كأصل.


6


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


 <uses-permission android:name="android.permission.INTERNET" /> dependencies { // ... implementation 'com.google.firebase:firebase-ml-model-interpreter:19.0.0' } 

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


 android { // ... aaptOptions { noCompress "tflite" // Your model's file extension: "tflite" } } 

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


 var conditionsBuilder: FirebaseModelDownloadConditions.Builder = FirebaseModelDownloadConditions.Builder().requireWifi() if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // Enable advanced conditions on Android Nougat and newer. conditionsBuilder = conditionsBuilder .requireCharging() .requireDeviceIdle() } val conditions: FirebaseModelDownloadConditions = conditionsBuilder.build() 

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


 val cloudSource: FirebaseRemoteModel = FirebaseRemoteModel.Builder("my_cloud_model") .enableModelUpdates(true) .setInitialDownloadConditions(conditions) .setUpdatesDownloadConditions(conditions) .build() FirebaseModelManager.getInstance().registerRemoteModel(cloudSource) 

نحن نقوم بنفس الخطوات الخاصة بالنموذج المحلي ، ونحدد اسمه ، والمسار إلى النموذج ، ونقوم بتسجيله في Firebase Model Manager.


 val localSource: FirebaseLocalModel = FirebaseLocalModel.Builder("my_local_model") .setAssetFilePath("my_model.tflite") .build() FirebaseModelManager.getInstance().registerLocalModel(localSource) 

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


 val options: FirebaseModelOptions = FirebaseModelOptions.Builder() .setRemoteModelName("my_cloud_model") .setLocalModelName("my_local_model") .build() val interpreter = FirebaseModelInterpreter.getInstance(options) 

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


بيانات الإدخال عبارة عن مصفوفة متعددة الأبعاد ، حيث تمثل 1 عدد الصور ، و 224 × 224 هي الدقة ، و 3 عبارة عن صورة RGB ثلاثية القنوات. حسنًا ، نوع البيانات بايت.


 val input = intArrayOf(1, 224, 224, 3) //one 224x224 three-channel (RGB) image val output = intArrayOf(1, 1000) val inputOutputOptions = FirebaseModelInputOutputOptions.Builder() .setInputFormat(0, FirebaseModelDataType.BYTE, input) .setOutputFormat(0, FirebaseModelDataType.BYTE, output) .build() 

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


الآن وضعنا قيم الإدخال. نأخذ صورة نقطية ، نضغطها إلى 224 في 224 ، ونحولها إلى ByteBuffer وننشئ قيم إدخال باستخدام FirebaseModelInput باستخدام أداة إنشاء خاصة.


 val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true) val imgData = convertBitmapToByteBuffer(bitmap) val inputs: FirebaseModelInputs = FirebaseModelInputs.Builder() .add(imageData) .build() 

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


 interpreter.run(inputs, inputOutputOptions) .addOnSuccessListener { result: FirebaseModelOutputs -> val labelProbArray = result.getOutput<Array<ByteArray>>(0) //handle labelProbArray } .addOnFailureListener( object : OnFailureListener { override fun onFailure(e: Exception) { // Task failed with an exception } }) 

يوم واحد التنفيذ


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


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


والأهم من ذلك - دعم النماذج المخصصة التي يمكن استخدامها كما تريد لأي مهمة.


روابط مفيدة


ML Kit الوثائق
Github ML Kit Demo Project
التعلم الآلي للجوال باستخدام Firebase (Google I / O'19)
SDK Learning Machine لمطوري الأجهزة المحمولة (Google I / O'18)
إنشاء ماسح بطاقة ائتمان باستخدام Firebase ML Kit (Medium.com)

Source: https://habr.com/ru/post/ar461867/


All Articles