Sto cercando di capire il flusso di lavoro per la formazione e la distribuzione di un modello Tensorflow su Android. Sono a conoscenza delle altre domande simili a questa su StackOverflow, ma nessuno di loro sembra affrontare i problemi che ho incontrato.Esecuzione di un modello Tensorflow su Android
Dopo aver studiato l'esempio Android dal repository tensorflow, questo è quello che penso il flusso di lavoro dovrebbe essere:
- costruire e formare tensorflow modello in Python.
- Creare un nuovo grafico e trasferire tutti i nodi rilevanti (ovvero non i nodi responsabili dell'addestramento) a questo nuovo grafico. Le variabili di peso addestrate vengono importate come costanti in modo che l'API C++ possa leggerle.
- Sviluppare la GUI Android in Java, utilizzando la parola chiave nativa per eseguire una chiamata al modello Tensorflow.
- Eseguire javah per generare il codice stub C/C++ per la chiamata nativa di Tensorflow.
- Completare lo stub utilizzando l'API C++ di Tensorflow per leggere e accedere al modello addestrato/serializzato.
- Utilizzare Bazel per costruire ENTRAMBI l'app Java, l'interfaccia nativa di Tensorflow (come file .so) e generare l'APK.
Utilizzare adb per distribuire l'APK.
Il passaggio 6 è il problema. Bazel compilerà felicemente un nativo (su OSX) .dylib che posso chiamare da Java tramite JNI. Allo stesso modo, Android Studio genererà un sacco di codice XML che rende la GUI che voglio. Tuttavia, Bazel vuole che tutto il codice dell'app java sia nella directory di primo livello "WORKSPACE" (nel repository Tensorflow), e Android Studio collega immediatamente tutti i tipi di librerie esterne dall'SDK per creare GUI (lo so perché il mio L'esecuzione di compilazione di Bazel fallisce quando non riesce a trovare queste risorse). L'unico modo che riesco a trovare per forzare Bazel a compilare a croce un file .so è rendendolo una regola dipendente di una regola Android. La cross-compilazione diretta di una lib nativa è ciò che preferirei per il porting della mia A.S. codice per un progetto Bazel.
Come si piazza questo? Apparentemente Bazel compilerà il codice Android, ma Android Studio genera codice che Bazel non può compilare. Tutti gli esempi di Google ti danno semplicemente il codice da un pronti contro termine senza alcun indizio su come è stato generato. Per quanto ne so, l'XML che fa parte di un'app Android Studio dovrebbe essere generato, non creato a mano. Se può essere fatto a mano, come evitare la necessità di tutte quelle librerie esterne?
Forse sto sbagliando il flusso di lavoro o ci sono alcuni aspetti di Bazel/Android Studio che non capisco. Qualsiasi aiuto apprezzato.
Grazie!
Edit:
C'erano molte cose che ho finito per fare che potrebbero aver contribuito alla costruzione delle biblioteche con successo:
- ho aggiornato all'ultima Bazel.
- Ho rigenerato TensorFlow dalla sorgente.
ho implementato il Bazel consigliato build di seguito, con alcune aggiunte (tratti dalla esempio Android):
cc_binary( name = "libName.so", srcs = ["org_tensorflowtest_MyActivity.cc", "org_tensorflowtest_MyActivity.h", "jni.h", "jni_md.h", ":libpthread.so"], deps = ["//tensorflow/core:android_tensorflow_lib", ], copts = [ "-std=c++11", "-mfpu=neon", "-O2", ], linkopts = ["-llog -landroid -lm"], linkstatic = 1, linkshared = 1, ) cc_binary( name = "libpthread.so", srcs = [], linkopts = ["-shared"], tags = [ "manual", "notap", ], )
non ho verificato che questa libreria può essere caricato e utilizzato in Android ancora; Android Studio 1.5 sembra essere molto schizzinoso nel riconoscere la presenza di librerie native.
Creare un .dylib non è di alcuna utilità, poiché Android non è OSX- dylib è un formato solo OSX. È linux, è necessario creare un .so (che è più o meno la stessa funzione di funzionalità, ma un diverso formato di file). Inoltre, l'XML in Android è tutto fatto a mano NON generato. Praticamente non viene generato nulla in nessuno degli esempi di Google. Il fatto che ti aspetti che sia probabilmente è parte del tuo problema. –
Inoltre, a meno che il software Tensorflow non debba utilizzare Bazel, non ho mai sentito di utilizzarlo per il lavoro su Android. Gradle è il nuovo standard e Ant è lo standard legacy. Se stai usando Bazel, stai sanguinando o stai facendo tutto da solo. –
@amm Eri in grado di eseguirlo su Android qual è la dimensione dell'app che hai costruito? – sau