Met TensorFlow, een van de meest populaire machine learning frameworks die tegenwoordig beschikbaar zijn, kunt u eenvoudig diepe modellen creëren en trainen - ook vaak aangeduid als diepe feed-forward neurale netwerken - die een verscheidenheid aan complexe problemen kunnen oplossen, zoals beeldclassificatie, object detectie en natuurlijke taalbegrip. TensorFlow Mobile is een bibliotheek die is ontworpen om u te helpen die modellen in uw mobiele apps te gebruiken.
In deze zelfstudie laat ik u zien hoe u TensorFlow Mobile kunt gebruiken in Android Studio-projecten.
Als je deze zelfstudie wilt kunnen volgen, heb je het volgende nodig:
Voordat we TensorFlow Mobile gaan gebruiken, hebben we een getraind TensorFlow-model nodig. Laten we er nu een maken.
Ons model zal heel basic zijn. Het zal zich gedragen als een XOR-poort, twee ingangen nemend, die beide nul of één kunnen zijn, en één uitgang produceren, die nul zal zijn als beide ingangen identiek zijn en één anders. Bovendien, omdat het een diep model zal zijn, zal het twee verborgen lagen hebben, één met vier neuronen en één met drie neuronen. Je bent vrij om het aantal verborgen lagen en de aantallen neuronen die ze bevatten te veranderen.
Om deze tutorial kort te houden, gebruiken we in plaats van de low-level TensorFlow API's direct, TFLearn, een populair wrapper-framework voor TensorFlow met meer intuïtieve en beknopte API's. Als u het nog niet hebt, gebruikt u de volgende opdracht om het in uw virtuele TensorFlow-omgeving te installeren:
pip installeer tflearn
Maak een Python-script met de naam om te beginnen met het maken van het model create_model.py, bij voorkeur in een lege map en open deze met je favoriete teksteditor.
In het bestand moeten we eerst de TFLearn API's importeren.
importeer tflearn
Vervolgens moeten we de trainingsgegevens maken. Voor ons eenvoudige model zullen er slechts vier mogelijke in- en uitgangen zijn, die lijken op de inhoud van de waarheidstabel van de XOR-poort.
X = [[0, 0], [0, 1], [1, 0], [1, 1]] Y = [[0], # Gewenste uitgang voor ingangen 0, 0 [1], # Gewenste uitgang voor ingangen 0, 1 [1], # Gewenste uitgang voor ingangen 1, 0 [0] # Gewenste uitgang voor ingangen 1, 1]
Het is meestal een goed idee om willekeurige waarden te gebruiken die zijn gekozen uit een uniforme verdeling, terwijl begingewichten worden toegewezen aan alle neuronen in de verborgen lagen. Gebruik de. Om de waarden te genereren uniform ()
methode.
weight = tflearn.initializations.uniform (minval = -1, maxval = 1)
Op dit punt kunnen we beginnen met het maken van de lagen van ons neurale netwerk. Om de invoerlaag te maken, moeten we de invoergegevens()
methode, waarmee we het aantal ingangen kunnen specificeren dat het netwerk kan accepteren. Zodra de invoerlaag gereed is, kunnen we de fully_connected ()
methode meerdere keren om meer lagen aan het netwerk toe te voegen.
# Invoernaag net = tflearn.input_data (shape = [None, 2], name = 'my_input') # Verborgen lagen net = tflearn.fully_connected (net, 4, activation = 'sigmoid', weights_init = weights) net = tflearn. fully_connected (net, 3, activation = 'sigmoid', weights_init = weight) # Output layer net = tflearn.fully_connected (net, 1, activation = 'sigmoid', weights_init = weights, name = 'my_output')
Merk op dat we in de bovenstaande code betekenisvolle namen hebben gegeven aan de invoer- en uitvoerlagen. Dit is belangrijk omdat we ze nodig hebben tijdens het gebruik van het netwerk vanuit onze Android-app. Merk ook op dat de lagen hidden en output de. Gebruiken sigmoid
activeringsfunctie. Je bent vrij om te experimenteren met andere activeringsfuncties, zoals Softmax
, tanh
, en Relu
.
Als laatste laag van ons netwerk moeten we een regressielaag maken met behulp van de regressie ()
functie, die enkele hyperparameters als zijn argumenten verwacht, zoals de leerfrequentie van het netwerk en de optimalisatie- en verliesfuncties die het zou moeten gebruiken. De volgende code laat zien hoe je stochastische gradiëntdaling gebruikt, kortweg SGD, als optimizerfunctie en mean square als verliesfunctie:
net = tflearn.regression (net, learning_rate = 2, optimizer = 'sgd', loss = 'mean_square')
Vervolgens, om het TFLearn-framework te laten weten dat ons netwerkmodel eigenlijk een diep neuraal netwerkmodel is, moeten we het DNN ()
functie.
model = tflearn.DNN (netto)
Het model is nu klaar. Alles wat we nu moeten doen, is het trainen met behulp van de trainingsgegevens die we eerder hebben gemaakt. Dus bel de fit ()
methode van het model en geef, samen met de trainingsgegevens, het aantal trainingsperioden op dat moet worden uitgevoerd. Omdat de trainingsgegevens erg klein zijn, heeft ons model duizenden tijdvakken nodig om redelijke nauwkeurigheid te bereiken.
model.fit (X, Y, 5000)
Zodra de training is voltooid, kunnen we bellen met voorspellen()
methode van het model om te controleren of het de gewenste outputs genereert. De volgende code toont u hoe u de uitgangen voor alle geldige ingangen kunt controleren:
print ("1 XOR 0 =% f"% model.predict ([[1,0]]). item (0)) print ("1 XOR 1 =% f"% model.predict ([[1,1] ]). item (0)) print ("0 XOR 1 =% f"% model.predict ([[0,1]]). item (0)) print ("0 XOR 0 =% f"% model. voorspellen ([[0,0]]). artikel (0))
Als je nu het Python-script uitvoert, zou je uitvoer moeten zien die er zo uitziet:
Houd er rekening mee dat de uitgangen nooit precies 0 of 1 zijn. In plaats daarvan zijn dit drijvende-kommawaarden die bijna nul of bijna één zijn. Daarom zou je tijdens het gebruik van de uitgangen misschien Python's willen gebruiken ronde()
functie.
Tenzij we het model expliciet opslaan nadat het is getraind, verliezen we het zodra het script is beëindigd. Gelukkig, met TFLearn, een eenvoudige oproep aan de opslaan()
methode slaat het model op. Om het opgeslagen model met TensorFlow Mobile te kunnen gebruiken voordat we het opslaan, moeten we ervoor zorgen dat we alle trainingsgerelateerde bewerkingen verwijderen die aanwezig zijn in de tf.GraphKeys.TRAIN_OPS
verzameling, die ermee verbonden is. De volgende code laat zien hoe je dit doet:
# Verwijder trein ops met net.graph.as_default (): del tf.get_collection_ref (tf.GraphKeys.TRAIN_OPS) [:] # Bewaar het model model.save ('xor.tflearn')
Als u het script opnieuw uitvoert, ziet u dat het een controlepuntbestand, een metadatabestand, een indexbestand en een gegevensbestand genereert, die allemaal samen gebruikt kunnen worden om snel ons getrainde model opnieuw te maken..
Naast het opslaan van het model, moeten we het bevriezen voordat we het met TensorFlow Mobile kunnen gebruiken. Het proces van het bevriezen van een model, zoals je misschien al geraden hebt, houdt in dat alle variabelen geconverteerd worden in constanten. Bovendien moet een bevroren model een enkel binair bestand zijn dat overeenkomt met het serialisatieformaat van de Google Protocol-buffers.
Maak een nieuw Python-script met de naam freeze_model.py en open het met een teksteditor. We zullen alle code schrijven om ons model in dit bestand te bevriezen.
Omdat TFLearn geen functies heeft voor het bevriezen van modellen, moeten we de TensorFlow-API's nu direct gebruiken. Importeer ze door de volgende regel toe te voegen aan het bestand:
import tensorflow als tf
In het hele script gebruiken we een enkele TensorFlow-sessie. Gebruik de constructor van de sessie om de sessie te maken Sessie
klasse.
met tf.Session () als sessie: # Rest van de code komt hier
Op dit punt moeten we een maken spaarder
object door de import_meta_graph ()
functie en geeft de naam van het metadatabestand van het model door. Naast het retourneren van een spaarder
object, de import_meta_graph ()
functie voegt ook automatisch de grafiekdefinitie van het model toe aan de grafiekdefinitie van de sessie.
Zodra de spaarder is gemaakt, kunnen we alle variabelen die in de grafiekdefinitie aanwezig zijn initialiseren door de herstellen()
methode, die het pad van de map met het nieuwste controlepuntbestand van het model verwacht.
my_saver = tf.train.import_meta_graph ('xor.tflearn.meta') my_saver.restore (session, tf.train.latest_checkpoint ('.'))
Op dit punt kunnen we de convert_variables_to_constants ()
functie om een bevroren grafiekdefinitie te maken waarin alle variabelen van het model worden vervangen door constanten. Als functie verwacht de functie de huidige sessie, de grafiekdefinitie van de huidige sessie en een lijst met de namen van de uitvoerlagen van het model.
frozen_graph = tf.graph_util.convert_variables_to_constants (session, session.graph_def, ['my_output / Sigmoid'])
Oproep aan de SerializeToString ()
methode van de bevroren grafiekdefinitie geeft ons een binaire protobufrepresentatie van het model. Door gebruik te maken van de basisbestand I / O-voorzieningen van Python, raad ik aan om het op te slaan als een bestand met de naam frozen_model.pb.
met open ('frozen_model.pb', 'wb') als f: f.write (frozen_graph.SerializeToString ())
U kunt het script nu uitvoeren om het bevroren model te genereren.
We hebben nu alles wat we nodig hebben om TensorFlow Mobile te gebruiken.
De bibliotheek van TensorFlow Mobile is beschikbaar op JCenter, dus we kunnen deze direct toevoegen als een implementatie
afhankelijkheid in de app
module build.gradle het dossier.
implementatie 'org.tensorflow: tensorflow-android: 1.7.0'
Om het bevroren model aan het project toe te voegen, plaatst u de frozen_model.pb bestand in het project middelen map.
TensorFlow Mobile biedt een eenvoudige interface die we kunnen gebruiken om te communiceren met ons bevroren model. Gebruik de constructor van de interface om de interface te maken TensorFlowInferenceInterface
klasse, die een verwacht Vermogensbeheerder
instantie en de bestandsnaam van het bevroren model.
thread val tfInterface = TensorFlowInferenceInterface (assets, "frozen_model.pb") // Meer code hier
In de bovenstaande code kunt u zien dat we een nieuwe thread gebruiken. Dit wordt weliswaar niet altijd noodzakelijk, maar wordt aanbevolen om te zorgen dat de gebruikersinterface van de app reageert.
Om er zeker van te zijn dat TensorFlow Mobile erin is geslaagd het bestand van ons model correct te lezen, proberen we nu de namen van alle bewerkingen die in de grafiek van het model aanwezig zijn, af te drukken. Om een verwijzing naar de grafiek te krijgen, kunnen we de graph ()
methode van de interface, en om alle bewerkingen te krijgen, de activiteiten()
methode van de grafiek. De volgende code laat zien hoe:
val graph = tfInterface.graph () graph.operations (). forElke println (it.name ())
Als u de app nu uitvoert, kunt u meer dan een dozijn bewerkingsnamen zien die zijn afgedrukt in Android Studio's logcat venster. Tussen al die namen kunt u, als er geen fouten waren tijdens het bevriezen van het model, de namen van de invoer- en uitvoerlagen vinden: my_input / X en my_output / Sigmoid.
Om voorspellingen te doen met het model, moeten we gegevens in de invoerlaag plaatsen en gegevens ophalen uit de uitvoerlaag. Gebruik de. Om gegevens in de invoerlaag te plaatsen voeden()
methode van de interface, die de naam van de laag verwacht, een array met de ingangen en de afmetingen van de array. De volgende code laat zien hoe u de nummers verzendt 0
en 1
naar de invoerlaag:
tfInterface.feed ("mijn_invoer / X", floatArrayOf (0f, 1f), 1, 2)
Na het laden van gegevens in de invoerlaag, moeten we een gevolgtrekkingsbewerking uitvoeren met behulp van de rennen()
methode, die de naam van de uitvoerlaag verwacht. Nadat de bewerking is voltooid, bevat de uitvoerlaag de voorspelling van het model. Om de voorspelling in een Kotlin-array te laden, kunnen we de ophalen ()
methode. De volgende code laat zien hoe je dit doet:
tfInterface.run (arrayOf ("my_output / Sigmoid")) val output = floatArrayOf (-1f) tfInterface.fetch ("my_output / Sigmoid", output)
Hoe u de voorspelling gebruikt, is natuurlijk aan u. Voor nu, ik stel voor dat je het gewoon afdrukt.
println ("Output is $ output [0]")
U kunt de app nu uitvoeren om te zien of de voorspelling van het model correct is.
U kunt de getallen die u invoert naar de invoerlaag wijzigen om te bevestigen dat de voorspellingen van het model altijd correct zijn.
U weet nu hoe u een eenvoudig TensorFlow-model kunt maken en dit met TensorFlow Mobile kunt gebruiken in Android-apps. Je hoeft je echter niet altijd te beperken tot je eigen modellen. Met de vaardigheden die je vandaag hebt geleerd, zou je geen problemen moeten hebben met het gebruik van grotere modellen, zoals MobileNet en Inception, die beschikbaar zijn in de dierentuin van het TensorFlow-model. Houd er echter rekening mee dat dergelijke modellen zullen leiden tot grotere APK's, wat problemen kan veroorzaken voor gebruikers met low-end apparaten.
Raadpleeg de officiële documentatie voor meer informatie over TensorFlow Mobile.