Slik bruker du TensorFlow Mobile i Android Apps

Med TensorFlow, en av de mest populære maskinlæringsrammene som er tilgjengelige i dag, kan du enkelt lage og trene dype modeller - også ofte referert til som dype feed-forward nevrale nettverk - som kan løse en rekke komplekse problemer, for eksempel bildeklassifisering, objekt gjenkjenning og naturlig språkforståelse. TensorFlow Mobile er et bibliotek designet for å hjelpe deg med å utnytte disse modellene i mobilappene dine.

I denne veiledningen viser jeg deg hvordan du bruker TensorFlow Mobile i Android Studio-prosjekter.

Forutsetninger

For å kunne følge denne opplæringen må du:

  • Android Studio 3.0 eller høyere
  • TensorFlow 1.5.0 eller høyere
  • en Android-enhet som kjører API-nivå 21 eller høyere
  • og en grunnleggende forståelse av TensorFlow-rammen

1. Opprette en modell

Før vi begynner å bruke TensorFlow Mobile, trenger vi en utdannet TensorFlow-modell. La oss lage en nå.

Vår modell skal være veldig grunnleggende. Det vil oppføre seg som en XOR-gate, med to innganger, som begge kan være null eller en, og produsere en utgang, som vil være null hvis begge inngangene er identiske og en ellers. I tillegg, fordi det kommer til å være en dyp modell, vil den ha to skjulte lag, en med fire nevroner, og en annen med tre nevroner. Du er fri til å endre antall skjulte lag og antall neuroner de inneholder.

For å holde denne opplæringen kort, i stedet for å bruke TensorFlow API-ene på lavt nivå, bruker vi TFLearn, et populært innpakningsramme for TensorFlow, som tilbyr mer intuitive og konsise APIer. Hvis du ikke allerede har det, bruker du følgende kommando for å installere den i ditt virtuelle TensorFlow-miljø:

pip installere tflearn

For å begynne å lage modellen, opprett et Python-skript som heter create_model.py, helst i en tom mappe, og åpne den med din favoritt tekstredigerer.

Inne i filen, er det første vi trenger å importere TFLearn APIer.

importere tflearn

Deretter må vi opprette opplæringsdataene. For vår enkle modell vil det bare være fire mulige innganger og utganger, som ligner innholdet i XOR-portens sannhetstabell.

X = [[0, 0], [0, 1], [1, 0], [1, 1]] Y = [[0], # Ønsket utgang for innganger 0, 0 [1], # Ønsket utgang for innganger 0, 1 [1], # Ønsket utgang for innganger 1, 0 [0] # Ønsket utgang for innganger 1, 1]

Det er vanligvis en god ide å bruke tilfeldige verdier plukket fra en jevn fordeling mens du tilordner innledende vekter til alle nevronene i de skjulte lagene. For å generere verdiene, bruk uniform() metode.

vekter = tflearn.initializations.uniform (minval = -1, maxval = 1)

På dette tidspunktet kan vi begynne å lage lagene i vårt nevrale nettverk. For å lage inngangslaget må vi bruke input_data () metode som lar oss spesifisere antall innganger nettverket kan akseptere. Når inngangslaget er klart, kan vi ringe til fully_connected () Metode flere ganger for å legge til flere lag i nettverket.

# Inndata lag netto = tflearn.input_data (form = [Ingen, 2], navn = 'my_input') # Skjulte lag net = tflearn.fully_connected (net, 4, activation = 'sigmoid', weights_init = vekter) net = tflearn. full_connected (netto, 3, activation = 'sigmoid', weights_init = vekter) # Output layer net = tflearn.fully_connected (netto, 1, aktivering = 'sigmoid', weights_init = vekter, navn = 'my_output')

Merk at i ovennevnte kode har vi gitt meningsfulle navn til inngangs- og utgangslagene. Å gjøre det er viktig fordi vi trenger dem mens du bruker nettverket fra Android-appen vår. Vær også oppmerksom på at skjulte og utgående lag bruker sigmoid aktiveringsfunksjon. Du er fri til å eksperimentere med andre aktiveringsfunksjoner, for eksempel Softmaxtanh, og Relu.

Som det siste laget av nettverket må vi opprette et regresjonslag ved hjelp av regresjon () funksjon, som forventer noen få hyperparametere som sine argumenter, for eksempel nettverks læringsfrekvens og optimerings- og tapsfunksjoner den skal bruke. Følgende kode viser hvordan du bruker stokastisk gradient nedstigning, SGD for kort, som optimaliseringsfunksjonen og gjennomsnittlig firkant som tapfunksjonen:

net = tflearn.regression (netto, learning_rate = 2, optimizer = 'sgd', tap = 'mean_square')

For å kunne la TFLearn-rammeverket vite at vår nettverksmodell faktisk er en dyp neural nettverksmodell, må vi ringe til DNN- () funksjon.

modell = tflearn.DNN (netto)

Modellen er nå klar. Alt vi trenger å gjøre nå er å trene det ved hjelp av treningsdataene vi opprettet tidligere. Så ring til passe() modellens metode og, sammen med treningsdataene, spesifiser antall treningsperioder for å kjøre. Fordi treningsdataene er svært små, trenger modellen tusenvis av epoker for å oppnå rimelig nøyaktighet.

model.fit (X, Y, 5000)

Når treningen er fullført, kan vi ringe til spå() Metode for modellen for å kontrollere om den genererer de ønskede utgangene. Følgende kode viser deg hvordan du kontrollerer utgangene for alle gyldige innganger:

skriv ut ("1 XOR 0 =% f"% model.predict ([[1,0]]) element (0)) print ("1 XOR 1 =% f"% model.predict ([[1,1] ] (0) 0 (0)) print ("0 XOR 1 =% f"% model.predict ([[0,1]]). element (0)) print ("0 XOR 0 =% f"% modell. forutsi ([[0,0]]). punkt (0))

Hvis du kjører Python-skriptet nå, bør du se utgang som ser slik ut:

Merk at utgangene aldri er nøyaktig 0 eller 1. I stedet er de flytende punktnumre som er enten nær null eller nær en. Derfor kan du bruke Python til å bruke utgangene rund() funksjon.

Med mindre vi eksplisitt lagrer modellen etter å ha trent det, vil vi miste det så snart skriptet avsluttes. Heldigvis, med TFLearn, en enkel samtale til lagre() Metoden sparer modellen. For å kunne bruke den lagrede modellen med TensorFlow Mobile, før vi lagrer den, må vi imidlertid sørge for at vi fjerner alle treningsrelaterte operasjoner som er tilstede i tf.GraphKeys.TRAIN_OPS samling, knyttet til den. Følgende kode viser hvordan du gjør det:

# Fjern tog ops med net.graph.as_default (): del tf.get_collection_ref (tf.GraphKeys.TRAIN_OPS) [:] # Lagre modellen model.save ('xor.tflearn')

Hvis du kjører skriptet igjen, vil du se at det genererer en kontrollpunktsfil, en metadatafil, en indeksfil og en datafil, som alle sammen kan brukes til å gjenopprette vår opplærte modell.

2. Frysning av modellen

I tillegg til å lagre modellen må vi fryse den før vi kan bruke den med TensorFlow Mobile. Prosessen med å fryse en modell, som du kanskje har gjettet, innebærer å konvertere alle dens variabler til konstanter. I tillegg må en frosset modell være en enkelt binærfil som samsvarer med serielliseringsformatet for Google-protokollbuffere.

Opprett et nytt Python-skript som heter freeze_model.py og åpne den ved hjelp av en tekstredigerer. Vi skriver hele koden for å fryse vår modell i denne filen.

Fordi TFLearn ikke har noen funksjoner for frysemodeller, må vi bruke TensorFlow-APIene nå. Importer dem ved å legge til følgende linje i filen:

importere tensorflow som tf

Gjennom skriptet bruker vi en enkelt TensorFlow-økt. For å opprette økten, bruk konstruktøren til Økt klasse.

med tf.Session () som økt: # Resten av koden går her

På dette punktet må vi opprette en Saver objekt ved å ringe import_meta_graph () funksjon og passere navnet på modellens metadatafil til det. I tillegg til å returnere a Saver objekt, den import_meta_graph () funksjonen legger også automatisk grafdefinisjonen til modellen til grafdefinisjonen for økten.

Når sparer er opprettet, kan vi initialisere alle variablene som er til stede i grafdefinisjonen ved å ringe restaurere() metode, som forventer banen til katalogen som inneholder modellens siste kontrollpunktfil.

my_saver = tf.train.import_meta_graph ('xor.tflearn.meta') my_saver.restore (økt, tf.train.latest_checkpoint ('.'))

På dette punktet kan vi ringe til convert_variables_to_constants () funksjon for å lage en frosset grafdefinisjon der alle variablene av modellen er erstattet med konstanter. Som innganger, forventer funksjonen den nåværende økten, den nåværende øktens grafdefinisjon og en liste som inneholder navnene på modellens utgangslager.

frozen_graph = tf.graph_util.convert_variables_to_constants (økt, session.graph_def, ['my_output / Sigmoid'])

Ringer på SerializeToString () Metoden for den frosne grafdefinisjonen gir oss en binær protobuf-representasjon av modellen. Ved å bruke Pythons grunnleggende fil I / O-anlegg, foreslår jeg at du lagrer det som en fil som heter frozen_model.pb.

med åpen ('frozen_model.pb', 'wb') som f: f.write (frozen_graph.SerializeToString ())

Du kan kjøre skriptet nå for å generere den frosne modellen.

Vi har nå alt vi trenger for å begynne å bruke TensorFlow Mobile.

3. Android Studio Project Setup

TensorFlow Mobile-biblioteket er tilgjengelig på JCenter, så vi kan legge den direkte til som en gjennomføring avhengighet i app modulens build.gradle fil.

implementering 'org.tensorflow: tensorflow-android: 1.7.0'

For å legge til den frosne modellen til prosjektet, plasser du frozen_model.pb fil i prosjektets eiendeler mappe.

4. Initialisere TensorFlow-grensesnittet

TensorFlow Mobile tilbyr et enkelt grensesnitt vi kan bruke til å samhandle med vår frosne modell. For å opprette grensesnittet, bruk konstruktøren til TensorFlowInferenceInterface klassen, som forventer en Kapitalforvalter forekomst og filnavn for den frosne modellen.

tråd val tfInterface = TensorFlowInferenceInterface (eiendeler, "frozen_model.pb") // Mer kode her

I ovennevnte kode kan du se at vi gyter en ny tråd. Det anbefales at du gjør det, selv om det ikke alltid er nødvendig, for at du skal være sikker på at appens brukergrensesnitt forblir responsivt.

For å være sikker på at TensorFlow Mobile har klart å lese modellens fil på riktig måte, la oss nå prøve å skrive ut navnene på alle operasjonene som er til stede i modellens graf. For å få en referanse til grafen, kan vi bruke kurve() metode for grensesnittet, og for å få alle operasjonene, operasjoner () metode for grafen. Følgende kode viser deg hvordan:

val graph = tfInterface.graph () graph.operations () .forEach println (it.name ())

Hvis du kjører appen nå, bør du kunne se over et dusin operasjonsnavn som er skrevet ut i Android Studio logcat vindu. Blant alle disse navnene, hvis det ikke fantes feil under frysing av modellen, kan du finne navnene på inngangs- og utgangslagene: my_input / X og my_output / Sigmoid.

5. Bruk av modellen

For å gjøre forutsigelser med modellen må vi sette data inn i inngangslaget og hente data fra utgangslaget. For å sette data inn i inngangslaget, bruk mate() Metode for grensesnittet, som forventer navnet på laget, en matrise som inneholder inngangene og dimensjonene av arrayet. Følgende kode viser deg hvordan du sender tallene 0 og 1 til inngangslaget:

tfInterface.feed ("my_input / X", floatArrayOf (0f, 1f), 1, 2)

Etter at du har lastet inn data i inngangslaget, må vi kjøre en inngangsoperasjon ved hjelp av løpe() metode, som forventer navnet på utgangslaget. Når operasjonen er fullført, vil utgangslaget inneholde prediksjon av modellen. For å laste inn prediksjonen til et Kotlin-array, kan vi bruke hente () metode. Følgende kode viser hvordan du gjør det:

tfInterface.run (arrayOf ("my_output / Sigmoid")) valutgang = floatArrayOf (-1f) tfInterface.fetch ("my_output / Sigmoid", utgang)

Hvordan du bruker prediksjonen, er selvfølgelig opp til deg. For nå foreslår jeg at du bare skriver ut den.

println ("Output er $ output [0]")

Du kan kjøre appen nå for å se at modellens prediksjon er riktig.

Du er velkommen til å endre tallene du legger inn i innskriftslaget for å bekrefte at modellens spådommer alltid er korrekte.

Konklusjon

Du vet nå hvordan du lager en enkel TensorFlow-modell og bruker den med TensorFlow Mobile i Android-apper. Du trenger ikke alltid å begrense deg selv til dine egne modeller. Med ferdighetene du lærte i dag, burde du ikke ha problemer med å bruke større modeller, for eksempel MobileNet og Inception, tilgjengelig i TensorFlow-modell zoo. Vær imidlertid oppmerksom på at slike modeller vil føre til større APKer, noe som kan skape problemer for brukere med lav-end-enheter.

For å lære mer om TensorFlow Mobile, se den offisielle dokumentasjonen.