الشبكات العصبية في Android و Google ML Kit وليس فقط

لذا ، قمت بتطوير وتدريب شبكتك العصبية لأداء نوع من المهام (على سبيل المثال ، التعرف على الكائن نفسه من خلال الكاميرا) وتريد دمجها في تطبيق Android الخاص بك؟ ثم مرحبا بكم في كات!

بادئ ذي بدء ، يجب أن يكون من المفهوم أن Android حاليًا يعرف فقط كيفية العمل مع شبكات تنسيق TensorFlowLite ، مما يعني أننا بحاجة إلى إجراء بعض التلاعبات مع الشبكة المصدر. افترض أن لديك شبكة مدربة بالفعل على إطار Keras أو Tensorflow. يجب حفظ الشبكة بتنسيق pb.

لنبدأ بالحالة عندما تكتب على Tensorflow ، فإن كل شيء أسهل قليلاً.

saver = tf.train.Saver() tf.train.write_graph(session.graph_def, path_to_folder, "net.pb", False) tf.train.write_graph(session.graph_def, path_to_folder, "net.pbtxt", True) saver.save(session,path_to_folder+"model.ckpt") 

إذا كنت تكتب في Keras ، فأنت بحاجة إلى إنشاء كائن جلسة جديد ، وحفظ ارتباط إليه في بداية الملف حيث تقوم بتدريب الشبكة ، وتمريرها إلى وظيفة set_session

 import keras.backend as K session = K.get_session() K.set_session(session) 

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

 freeze_graph --input_binary=false --input_graph=net.pbtxt --output_node_names=result/Softmax --output_graph=frozen_graph.pb --input_checkpoint=model.ckpt 

لاحظ أنك بحاجة إلى معرفة اسم موتر الإخراج. في tensorflow ، يمكنك تعيينه بنفسك ، في حالة استخدام Keras - قم بتعيين الاسم في مُنشئ الطبقة

 model.add(Dense(10,activation="softmax",name="result")) 

في هذه الحالة ، عادة ما يبدو اسم الموتر مثل "النتيجة / Softmax"

إذا لم يكن الأمر كذلك ، فيمكنك العثور على الاسم على النحو التالي

 [print(n.name) for n in session.graph.as_graph_def().node] 

يبقى لتشغيل البرنامج النصي الثاني

 toco --graph_def_file=frozen-graph.pb --output_file=model.tflite --output_format=TFLITE --inference_type=FLOAT --input_arrays=input_input --output_arrays=result/Softmax --input_shapes=1,784 

مرحى! الآن لديك نموذج TensorFlowLite في مجلدك ، والأمر متروك لك لدمجه بشكل صحيح في تطبيق Android الخاص بك. يمكنك القيام بذلك باستخدام مجموعة أدوات Firebase ML الجديدة ، ولكن هناك طريقة أخرى تتعلق بها بعد ذلك بقليل. أضف تبعية إلى ملف التدرج الخاص بنا

 dependencies { // ... implementation 'com.google.firebase:firebase-ml-model-interpreter:16.2.0' } 

تحتاج الآن إلى تحديد ما إذا كنت ستحتفظ بالنموذج في مكان ما على الخادم أم ستشحنه مع التطبيق.

خذ بعين الاعتبار الحالة الأولى: نموذج على الخادم. بادئ ذي بدء ، لا تنس أن تضيف إلى البيان

 <uses-permission android:name="android.permission.INTERNET" /> 

  //      ,   /  FirebaseModelDownloadConditions.Builder conditionsBuilder = new FirebaseModelDownloadConditions.Builder().requireWifi(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { conditionsBuilder = conditionsBuilder .requireCharging(); } FirebaseModelDownloadConditions conditions = conditionsBuilder.build(); //   FirebaseCloudModelSource ,   (    ,  //   Firebase) FirebaseCloudModelSource cloudSource = new FirebaseCloudModelSource.Builder("my_cloud_model") .enableModelUpdates(true) .setInitialDownloadConditions(conditions) .setUpdatesDownloadConditions(conditions) .build(); FirebaseModelManager.getInstance().registerCloudModelSource(cloudSource); 

إذا كنت تستخدم النموذج المدرج في التطبيق محليًا ، فلا تنس إضافة الإدخال التالي إلى ملف build.gradle بحيث لا يتم ضغط ملف النموذج

 android { // ... aaptOptions { noCompress "tflite" } } 

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

 FirebaseLocalModelSource localSource = new FirebaseLocalModelSource.Builder("my_local_model") .setAssetFilePath("mymodel.tflite") .build(); FirebaseModelManager.getInstance().registerLocalModelSource(localSource); 

يفترض الرمز أعلاه أن نموذجك موجود في مجلد الأصول ، إن لم يكن ، بدلاً من ذلك

  .setAssetFilePath("mymodel.tflite") 

استخدام

  .seFilePath(filePath) 

ثم نقوم بإنشاء كائنات جديدة FirebaseModelOptions و FirebaseModelInterpreter

 FirebaseModelOptions options = new FirebaseModelOptions.Builder() .setCloudModelName("my_cloud_model") .setLocalModelName("my_local_model") .build(); FirebaseModelInterpreter firebaseInterpreter = FirebaseModelInterpreter.getInstance(options); 

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

كل شيء تقريبًا ، يبقى إنشاء صفائف لبيانات الإدخال / الإخراج وتشغيل!

 FirebaseModelInputOutputOptions inputOutputOptions = new FirebaseModelInputOutputOptions.Builder() .setInputFormat(0, FirebaseModelDataType.BYTE, new int[]{1, 640, 480, 3}) .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 784}) .build(); byte[][][][] input = new byte[1][640][480][3]; input = getYourInputData(); FirebaseModelInputs inputs = new FirebaseModelInputs.Builder() .add(input) // add() as many input arrays as your model requires .build(); Task<FirebaseModelOutputs> result = firebaseInterpreter.run(inputs, inputOutputOptions) .addOnSuccessListener( new OnSuccessListener<FirebaseModelOutputs>() { @Override public void onSuccess(FirebaseModelOutputs result) { // ... } }) .addOnFailureListener( new OnFailureListener() { @Override public void onFailure(@NonNull Exception e) { // Task failed with an exception // ... } }); float[][] output = result.<float[][]>getOutput(0); float[] probabilities = output[0]; 

إذا كنت لا تريد استخدام Firebase لسبب ما ، فهناك طريقة أخرى ، وهي استدعاء مترجم tflite وتزويده بالبيانات مباشرة.

أضف خطًا لبناء / تدرج

  implementation 'org.tensorflow:tensorflow-lite:+' 

إنشاء مترجم ومصفوفات

  Interpreter tflite = new Interpreter(loadModelFile(getContext(), "model.tflite")); //     inputs tflite.run(inputs,outputs) 

الرمز في هذه الحالة أقل بكثير ، كما ترى.

هذا كل ما تحتاجه لاستخدام شبكتك العصبية في android.

روابط مفيدة:

من أرصفة ML Kit
Tensorflow Lite

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


All Articles