Bevezetés a Tensorflow for Java-ba
1. Áttekintés
A TensorFlow egy nyílt forráskódú könyvtár adatfolyam-programozáshoz. Ezt eredetileg a Google fejlesztette ki, és számos platform számára elérhető. Habár a TensorFlow egyetlen magra képes dolgozni, képes arra is könnyen élvezheti az elérhető több CPU, GPU vagy TPU előnyeit.
Ebben az oktatóanyagban áttekintjük a TensorFlow alapjait és a Java használatát. Felhívjuk figyelmét, hogy a TensorFlow Java API egy kísérleti API, ezért semmilyen stabilitási garancia nem vonatkozik rá. Később az oktatóanyagban kitérünk a TensorFlow Java API használatának lehetséges felhasználási eseteire.
2. Alapismeretek
A TensorFlow számítás alapvetően körül forog két alapvető fogalom: Graph és Session. Gyorsan menjünk át rajtuk, hogy megszerezzük az oktatóanyag többi részének átvételéhez szükséges hátteret.
2.1. TensorFlow grafikon
Először is, értsük meg a TensorFlow programok alapvető építőköveit. A számítások grafikonként vannak ábrázolva a TensorFlow-ban. A grafikon általában a műveletek és az adatok irányított aciklikus grafikonja, például:
A fenti kép a következő egyenlet számítási grafikonját mutatja:
f (x, y) = z = a * x + b * y
A TensorFlow számítási grafikon két elemből áll:
- Tensor: Ezek a TensorFlow adatainak fő egységei. Szélként vannak ábrázolva egy számítási grafikonon, amely az adatok áramlását ábrázolja a grafikonon. A tenzor alakja tetszőleges számú dimenzióval rendelkezhet. A tenzor dimenzióinak számát általában rangjának nevezik. Tehát a skalár egy 0. rangú tenzor, a vektor egy 1. rangú tenzor, a mátrix egy 2. rangú tenzor, és így tovább és így tovább.
- Művelet: Ezek a számítási grafikon csomópontjai. A számítások sokféleségére utalnak, amelyek a művelet során táplálkozó tenzorokon történhetnek. Gyakran tenzorokat is eredményeznek, amelyek a műveletből származnak egy számítási grafikonon.
2.2. TensorFlow munkamenet
Most egy TensorFlow gráf csupán a vázlata a számításnak, amely valójában nem tartalmaz értékeket. Ilyen egy gráfot kell futtatni az úgynevezett TensorFlow munkameneten belül az értékelendő grafikon tenzorai számára. A munkamenet egy csomó tenzort vehet igénybe, hogy a grafikonból kiindulási paraméterként értékelje. Ezután visszafut a grafikonon, és lefuttatja az összes tenzort, amelyek szükségesek a tenzorok értékeléséhez.
Ezzel a tudással készen állunk erre, és alkalmazzuk a Java API-ra!
3. Maven Setup
Felállítunk egy gyors Maven projektet a TensorFlow grafikon létrehozására és futtatására Java-ban. Csak szükségünk van a tensorflow függőség:
org.tensorflow tensorflow 1.12.0
4. A grafikon létrehozása
Most próbáljuk meg megépíteni az előző szakaszban tárgyalt grafikont a TensorFlow Java API segítségével. Pontosabban, ehhez az oktatóanyaghoz a TensorFlow Java API-t fogjuk használni a következő egyenlet által képviselt függvény megoldására:
z = 3 * x + 2 * y
Az első lépés egy grafikon deklarálása és inicializálása:
Grafikon = új grafikon ()
Most meg kell határoznunk az összes szükséges műveletet. Emlékezz arra a TensorFlow-ban végzett műveletek nulla vagy annál több tenzort fogyasztanak. Ezenkívül a grafikon minden csomópontja olyan művelet, amely konstansokat és helyőrzőket tartalmaz. Ez ellentmondónak tűnhet, de viselje el egy pillanatra!
Osztály Grafikon általános funkciója van opBuilder () bármilyen műveletet kiépíteni a TensorFlow-on.
4.1. Állandók meghatározása
Először is definiáljuk az állandó műveleteket a fenti grafikonunkon. Vegye figyelembe, hogy a az állandó működéshez tenzor szükséges az értéke:
Az a = graph.opBuilder ("Const", "a") .setAttr ("dtype", DataType.fromClass (Double.class)) .setAttr ("value", Tensor.create (3.0, Double.class)) művelet. épít(); B művelet = graph.opBuilder ("Const", "b") .setAttr ("dtype", DataType.fromClass (Double.class)) .setAttr ("value", Tensor.create (2.0, Double.class)). épít();
Itt definiáltunk egy Művelet állandó típusú, táplálkozás a Tenzor val vel Kettős értékek 2,0 és 3,0. Lehet, hogy eleve kevéssé elsöprőnek tűnik, de egyelőre csak ez van a Java API-ban. Ezek a konstrukciók sokkal tömörebbek az olyan nyelvekben, mint a Python.
4.2. Helyőrzők meghatározása
Míg értékeket kell szolgáltatnunk az állandóinknak, a helyőrzőknek nincs szükségük értékre a meghatározás idején. A helyőrzőknek szóló értékeket meg kell adni, amikor a grafikon egy munkameneten belül fut. Ezt a részt később áttekintjük az oktatóanyagban.
Most nézzük meg, hogyan definiálhatjuk helyőrzőinket:
X művelet = graph.opBuilder ("Placeholder", "x") .setAttr ("dtype", DataType.fromClass (Double.class)) .build (); Y = graph.opBuilder ("Placeholder", "y") .setAttr ("dtype", DataType.fromClass (Double.class)) .build () művelet;
Ne feledje, hogy nem kellett semmilyen értéket megadnunk a helyőrzőink számára. Ezeket az értékeket a következőként adjuk meg Tenzorok amikor fut.
4.3. Funkciók meghatározása
Végül meg kell határoznunk egyenletünk matematikai műveleteit, nevezetesen szorzást és összeadást az eredmény elérése érdekében.
Ezek megint nem más, mint Művelets a TensorFlow-ban és Graph.opBuilder () még egyszer hasznos:
Művelet ax = graph.opBuilder ("Mul", "ax") .addInput (a.output (0)) .addInput (x.output (0)) .build (); A = graph.opBuilder ("Mul", "by") művelete .addInput (b.output (0)) .addInput (y.output (0)) .build (); Z = graph.opBuilder ("Add", "z") .addInput (ax.output (0)) .addInput (by.output (0)) .build () művelet;
Itt meghatároztuk Művelet, kettő az inputjaink szorzására, az utolsó pedig a köztes eredmények összegzésére. Ne feledje, hogy az itteni műveletek tenzorokat kapnak, amelyek nem más, mint korábbi műveleteink eredményei.
Felhívjuk figyelmét, hogy megkapjuk a kimenetet Tenzor tól Művelet a „0” index használatával. Ahogy korábban megbeszéltük, an Művelet egy vagy több eredményezhet Tenzor és ezért a fogantyú lekérése közben meg kell említenünk az indexet. Mivel tudjuk, hogy működésünk csak egyet hoz vissza Tenzor, A '0' remekül működik!
5. A grafikon megjelenítése
Nehéz tabulát tartani a grafikonon, mivel növekszik a mérete. Ez teszi fontos valamilyen módon megjeleníteni. Mindig létrehozhatunk olyan kézi rajzot, mint a korábban létrehozott kis gráf, de nagyobb grafikonoknál nem praktikus. A TensorFlow a TensorBoard nevű segédprogramot biztosítja ennek elősegítésére.
Sajnos a Java API nem képes eseményfájlok létrehozására, amelyeket a TensorBoard fogyaszt. De az API-k használatával a Pythonban létrehozhatunk egy eseményfájlt, például:
író = tf.summary.FileWriter ('.') ...... író.add_graph (tf.get_default_graph ()) író.flush ()
Kérjük, ne zavarja, ha ennek nincs értelme a Java-kontextusban, ezt csak a teljesség kedvéért adtuk hozzá, és nem szükséges folytatni az oktatóanyagot.
Most betölthetjük és vizualizálhatjuk az eseményfájlt a TensorBoard-ba, például:
tensorboard --logdir.
A TensorBoard a TensorFlow telepítés része.
Vegye észre ennek és a kézzel rajzolt grafikon közötti hasonlóságot korábban!
6. Munka a Session-szel
Most létrehoztunk egy számítási grafikont az egyszerű egyenletünkhöz a TensorFlow Java API-ban. De hogyan futtassuk? Mielőtt ezzel foglalkoznánk, nézzük meg, mi az állapota Grafikon most hoztunk létre ezen a ponton. Ha megpróbáljuk kinyomtatni a döntőnk kimenetét Művelet „Z”:
System.out.println (z.output (0));
Ez olyasmit eredményez, mint:
Nem erre számítottunk! De ha felidézzük, amit korábban megbeszéltünk, ennek tulajdonképpen van értelme. A Grafikon amit éppen definiáltunk, még nem futott, így az ott szereplő tenzorok valójában nem rendelkeznek tényleges értékkel. A fenti kimenet csak azt mondja, hogy ez a Tenzor típusú Kettős.
Most definiáljuk a Ülés hogy a mi Grafikon:
Munkamenet = új munkamenet (grafikon)
Végül készen állunk a grafikonunk futtatására és a várt kimenet megszerzésére:
Tenzor tenzor = sess.runner (). Fetch ("z"). Feed ("x", Tensor.create (3.0, Double.class)) .feed ("y", Tensor.create (6.0, Double.class) ) .run (). get (0) .expect (Double.class); System.out.println (tensor.doubleValue ());
Szóval mit csinálunk itt? Meglehetősen intuitívnak kell lennie:
- Kap egy Futó tól Ülés
- Határozza meg a Művelet a „z” nevével elhozni
- Töltsön be tenzorokat az „x” és „y” helyőrzőink számára
- Futtassa a Grafikon ban,-ben Ülés
És most látjuk a skalár kimenetet:
21.0
Erre számítottunk, nem igaz!
7. A Java API használati esete
Ezen a ponton a TensorFlow túlzottnak tűnhet az alapvető műveletek végrehajtása során. De természetesen, A TensorFlow sokkal nagyobb grafikonok futtatására szolgál mint ez.
Ezenkívül a tenzorok, amelyekkel a valós modellekben foglalkozik, sokkal nagyobb méretűek és rangúak. Ezek azok a tényleges gépi tanulási modellek, ahol a TensorFlow megtalálja valódi használatát.
Nem nehéz belátni, hogy a TensorFlow alapvető API-jával való munka nagyon nehézkessé válhat, ahogy a grafikon mérete növekszik. Eddig a végéig, A TensorFlow olyan magas szintű API-kat biztosít, mint a Keras, komplex modellekkel való együttműködéshez. Sajnos egyelőre alig vagy egyáltalán nincs hivatalos támogatás a Keras javára a Java-on.
Megtehetjük azonban használja a Pythont komplex modellek definiálásához és képzéséhez vagy közvetlenül a TensorFlow-ban, vagy olyan magas szintű API-k segítségével, mint a Keras. Ezt követően megtehetjük képzett modell exportálása és Java-ban történő használata a TensorFlow Java API használatával.
Most miért akarunk ilyesmit csinálni? Ez különösen hasznos azokban a helyzetekben, amikor gépi tanulással engedélyezett szolgáltatásokat szeretnénk használni a Java-on futó meglévő kliensekben. Például felirat ajánlása felhasználói képekhez Android-eszközön. Ennek ellenére számos olyan eset van, amikor egy gépi tanulási modell kimenete érdekel minket, de nem feltétlenül akarjuk ezt a modellt Java-ban létrehozni és betanítani.
Itt találja meg a TensorFlow Java API használatának nagy részét. A következő szakaszban áttekintjük, hogyan lehet ezt elérni.
8. Mentett modellek használata
Most már megértjük, hogyan menthetünk egy modellt a TensorFlow fájlban a fájlrendszerbe, és azt esetleg teljesen más nyelven és platformon tölthetjük vissza. A TensorFlow API-kat biztosít a modellfájlok protokoll- puffer nevű nyelvi és platform-semleges felépítéséhez.
8.1. Modellek mentése a fájlrendszerbe
Először meghatározzuk ugyanazt a grafikont, amelyet korábban a Pythonban készítettünk, és mentettük a fájlrendszerbe.
Lássuk, ezt megtehetjük a Pythonban:
tensorflow importálása tf grafikonként = tf.Graph () builder = tf.saved_model.builder.SavedModelBuilder ('./ model') a graph.as_default () névvel: a = tf.constant (2, name = "a") b = tf.constant (3, név = "b") x = tf.placeholder (tf.int32, name = "x") y = tf.placeholder (tf.int32, name = "y") z = tf.math. add (a * x, b * y, név = "z") sess = tf.Session () sess.run (z, feed_dict = {x: 2, y: 3}) builder.add_meta_graph_and_variables (sess, [tf. saved_model.tag_constants.SERVING]) builder.save ()
Ennek az oktatóanyagnak a fókuszában a Java-ban, ne fordítsunk különös figyelmet a Python Python kódjának részleteire, kivéve azt a tényt, hogy az létrehoz egy „saved_model.pb” nevű fájlt. Ne feledje, hogy átadja a Java-hoz hasonló grafikon meghatározásának rövidségét!
8.2. Modellek betöltése a fájlrendszerből
Most betöltjük a „saved_model.pb” fájlt a Java-ba. A Java TensorFlow API rendelkezik SavedModelBundle a mentett modellekkel való munkavégzéshez:
SavedModelBundle model = SavedModelBundle.load ("./ modell", "szolgálja"); Tenzor tenzor = model.session (). Runner (). Fetch ("z"). Feed ("x", Tensor.create (3, Integer.class)) .feed ("y", Tensor.create (3, Integer.class)) .run (). Get (0) .expect (Integer.class); System.out.println (tensor.intValue ());
Mostanra meglehetősen intuitívnak kell lennie annak megértéséhez, hogy a fenti kód mit csinál. Egyszerűen betölti a modell gráfot a protokollpufferből, és elérhetővé teszi a benne lévő munkamenetet. Innentől kezdve nagyjából bármit megtehetünk ezzel a gráffal, ahogy egy helyileg definiált gráfnál tettük volna.
9. Következtetés
Összefoglalva, ebben az oktatóanyagban áttekintettük a TensorFlow számítási grafikonhoz kapcsolódó alapfogalmakat. Láttuk, hogyan kell használni a TensorFlow Java API-t egy ilyen grafikon létrehozásához és futtatásához. Ezután beszéltünk a Java API használatának eseteiről a TensorFlow vonatkozásában.
Ennek során megértettük a grafikon vizualizálását a TensorBoard segítségével, valamint a modell mentését és újratöltését a Protokoll puffer segítségével.
Mint mindig, a példák kódja elérhető a GitHub oldalon.