لذا ، قمت بتطوير وتدريب شبكتك العصبية لأداء نوع من المهام (على سبيل المثال ، التعرف على الكائن نفسه من خلال الكاميرا) وتريد دمجها في تطبيق 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" />
إذا كنت تستخدم النموذج المدرج في التطبيق محليًا ، فلا تنس إضافة الإدخال التالي إلى ملف 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)
إذا كنت لا تريد استخدام Firebase لسبب ما ، فهناك طريقة أخرى ، وهي استدعاء مترجم tflite وتزويده بالبيانات مباشرة.
أضف خطًا لبناء / تدرج
implementation 'org.tensorflow:tensorflow-lite:+'
إنشاء مترجم ومصفوفات
Interpreter tflite = new Interpreter(loadModelFile(getContext(), "model.tflite"));
الرمز في هذه الحالة أقل بكثير ، كما ترى.
هذا كل ما تحتاجه لاستخدام شبكتك العصبية في android.
روابط مفيدة:
من أرصفة ML KitTensorflow Lite