Úvod do Tensorflow pre Javu

1. Prehľad

TensorFlow je open source knižnica pre programovanie toku dát. Tento produkt pôvodne vyvinula spoločnosť Google a je k dispozícii pre širokú škálu platforiem. Aj keď TensorFlow môže pracovať na jednom jadre, môže ako ľahko profitujte z viacerých dostupných CPU, GPU alebo TPU.

V tomto výučbe si prečítame základné informácie o TensorFlow a o tom, ako ho používať v prostredí Java. Upozorňujeme, že rozhranie TensorFlow Java API je experimentálne rozhranie API, a preto na neho nevzťahuje žiadna záruka stability. Ďalej sa v tutoriálu zaoberáme možnými prípadmi použitia TensorFlow Java API.

2. Základy

Výpočet TensorFlow sa v podstate točí okolo dva základné pojmy: Graf a Relácia. Prejdime ich rýchlo, aby sme získali pozadie potrebné na absolvovanie zvyšnej časti tutoriálu.

2.1. Graf TensorFlow

Na začiatok si uvedomíme základné stavebné prvky programov TensorFlow. Výpočty sú v TensorFlow reprezentované ako grafy. Graf je zvyčajne usmernený acyklický graf operácií a údajov, napríklad:

Vyššie uvedený obrázok predstavuje výpočtový graf pre nasledujúcu rovnicu:

f (x, y) = z = a * x + b * y

Výpočtový graf TensorFlow sa skladá z dvoch prvkov:

  1. Tensor: Toto sú základné jednotky údajov v TensorFlow. Sú reprezentované ako hrany vo výpočtovom grafe, ktorý zobrazuje tok údajov grafom. Tenzor môže mať tvar s ľubovoľným počtom rozmerov. Počet rozmerov v tenzore sa zvyčajne označuje ako jeho poradie. Takže skalár je tenzor stupňa 0, vektor je tenzor stupňa 1, matica je tenzor stupňa 2 a tak ďalej a tak ďalej.
  2. Prevádzka: Toto sú uzly vo výpočtovom grafe. Odvolávajú sa na širokú škálu výpočtov, ktoré sa môžu vyskytnúť na tenzoroch napájaných do operácie. Výsledkom majú často aj tenzory, ktoré vychádzajú z operácie vo výpočtovom grafe.

2.2. Relácia TensorFlow

Teraz je graf TensorFlow iba schémou výpočtu, ktorý v skutočnosti neobsahuje žiadne hodnoty. Taký pre vyhodnotenie tenzorov v grafe musí byť v grafe spustený graf, ktorý sa nazýva relácia TensorFlow. Relácia môže trvať veľa tenzorov, aby sa vyhodnotila z grafu ako vstupné parametre. Potom sa v grafe spustí dozadu a spustí všetky uzly potrebné na vyhodnotenie týchto tenzorov.

S týmito vedomosťami sme teraz pripravení vziať to a aplikovať ich na Java API!

3. Nastavenie Maven

Pripravíme rýchly projekt Maven na vytvorenie a spustenie grafu TensorFlow v Jave. Len potrebujeme tensorflow závislosť:

 org.tensorflow tensorflow 1.12.0 

4. Vytvorenie grafu

Pokúsme sa teraz zostaviť graf, o ktorom sme hovorili v predchádzajúcej časti, pomocou Java API TensorFlow. Presnejšie povedané, pre tento tutoriál použijeme Java API TensorFlow na riešenie funkcie predstavovanej nasledujúcou rovnicou:

z = 3 * x + 2 * y

Prvým krokom je deklarácia a inicializácia grafu:

Graf graf = nový Graf ()

Teraz musíme definovať všetky požadované operácie. Zapamätaj si to operácie v TensorFlow spotrebúvajú a produkujú nulové alebo viac tenzorov. Navyše každý uzol v grafe je operácia vrátane konštánt a zástupných znakov. Môže sa to javiť ako neintuitívne, ale chvíľu to vydržte!

Trieda Graf má všeobecnú funkciu s názvom opBuilder () vybudovať akýkoľvek druh operácie na TensorFlow.

4.1. Definovanie konštánt

Na začiatok si definujeme konštantné operácie v našom grafe vyššie. Všimnite si, že a konštantná prevádzka bude pre svoju hodnotu potrebovať tenzor:

Prevádzka a = graph.opBuilder ("Const", "a") .setAttr ("dtype", DataType.fromClass (Double.class)) .setAttr ("value", Tensor.create (3.0, Double.class)). build (); Operácia b = graph.opBuilder ("Const", "b") .setAttr ("dtype", DataType.fromClass (Double.class)) .setAttr ("value", Tensor.create (2.0, Double.class)). build ();

Tu sme definovali Prevádzka konštantného typu, kŕmenie v Tenzor s Dvojitý hodnoty 2,0 a 3,0. Na začiatok sa to môže zdať trochu ohromujúce, ale tak to zatiaľ v Java API je. Tieto konštrukcie sú v jazykoch ako Python oveľa stručnejšie.

4.2. Definovanie zástupných znakov

Aj keď musíme svojim konštantám poskytnúť hodnoty, zástupné symboly nepotrebujú hodnotu v čase definície. Hodnoty zástupných symbolov je potrebné zadať, keď je graf spustený v relácii. Tú časť si prejdeme neskôr v návode.

Zatiaľ sa pozrime, ako môžeme definovať naše zástupné symboly:

Operácia x = graph.opBuilder ("Placeholder", "x") .setAttr ("dtype", DataType.fromClass (Double.class)) .build (); Operácia y = graph.opBuilder ("Placeholder", "y") .setAttr ("dtype", DataType.fromClass (Double.class)) .build ();

Upozorňujeme, že sme pre svojich zástupcov nemuseli poskytovať žiadnu hodnotu. Tieto hodnoty sa budú vkladať ako Tenzory keď beží.

4.3. Definovanie funkcií

Nakoniec musíme definovať matematické operácie našej rovnice, a to násobenie a sčítanie, aby sme dosiahli výsledok.

To opäť nie sú nič iné ako Prevádzkas v TensorFlow a Graph.opBuilder () je šikovný ešte raz:

Prevádzka ax = graph.opBuilder ("Mul", "ax") .addInput (a.output (0)) .addInput (x.output (0)) .build (); Operácia = graph.opBuilder ("Mul", "by") .addInput (b.output (0)) .addInput (y.output (0)) .build (); Operácia z = graph.opBuilder ("Add", "z") .addInput (ax.output (0)) .addInput (by.output (0)) .build ();

Tu sme to definovali Prevádzka, dva na znásobenie našich vstupov a posledný na sčítanie medzivýsledkov. Upozorňujeme, že operácie tu prijímajú tenzory, ktoré nie sú ničím iným ako výstupom z našich predchádzajúcich operácií.

Upozorňujeme, že dostávame výstup Tenzor z Prevádzka pomocou indexu „0“. Ako sme už diskutovali, an Prevádzka môže mať za následok jeden alebo viac Tenzor a teda pri načítaní popisovača k tomu musíme spomenúť index. Pretože vieme, že naše operácie vracajú iba jednu Tenzor„„ 0 “funguje dobre!

5. Vizualizácia grafu

Je ťažké udržať kartu v grafe, pretože sa zväčšuje. Toto ho robí je dôležité si to nejakým spôsobom predstaviť. Vždy môžeme vytvoriť ručnú kresbu ako malý graf, ktorý sme vytvorili predtým, ale pre väčšie grafy to nie je praktické. TensorFlow poskytuje na tento účel nástroj s názvom TensorBoard.

Bohužiaľ, Java API nemá schopnosť generovať súbor udalostí, ktorý spotrebúva TensorBoard. Ale pomocou API v Pythone môžeme vygenerovať súbor udalosti ako:

writer = tf.summary.FileWriter ('.') ...... writer.add_graph (tf.get_default_graph ()) writer.flush ()

Neobťažujte sa, ak to v kontexte Javy nedáva zmysel, toto tu bolo pridané len pre úplnosť a nie je potrebné pokračovať vo zvyšku tutoriálu.

Teraz môžeme načítať a vizualizovať súbor udalostí v TensorBoard ako:

tensorboard --logdir.

TensorBoard je súčasťou inštalácie TensorFlow.

Všimnite si podobnosť medzi týmto a ručne nakresleným grafom skôr!

6. Práca s reláciou

Teraz sme vytvorili výpočtový graf pre našu jednoduchú rovnicu v rozhraní TensorFlow Java API. Ako to však spustíme? Predtým, ako sa tým budeme venovať, pozrime sa, aký je stav Graf práve sme vytvorili v tomto bode. Ak sa pokúsime vytlačiť výstup z nášho finále Prevádzka „Z“:

System.out.println (z.output (0));

Výsledkom bude niečo ako:

To nie je to, čo sme očakávali! Ale ak si spomenieme na to, o čom sme hovorili už skôr, má to vlastne zmysel. The Graf sme práve definovali, ešte nebol spustený, takže jeho tenzory v skutočnosti nedržia žiadnu skutočnú hodnotu. Vyššie uvedený výstup iba hovorí, že to bude a Tenzor typu Dvojitý.

Definujme teraz a Session spustiť našu Graf:

Relácia sess = nová relácia (graf)

Nakoniec sme teraz pripravení spustiť náš Graph a získať výstup, aký sme očakávali:

Tenzor tenzora = 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 ());

Čo tu teda robíme? Malo by to byť celkom intuitívne:

  • Dostať Bežec z Session
  • Definujte Prevádzka načítať podľa názvu „z“
  • Vložte tenzory pre naše zástupné symboly „x“ a „y“
  • Spustiť Graf v Session

A teraz vidíme skalárny výstup:

21.0

Toto sme očakávali, však!

7. Prípad použitia pre Java API

V tomto okamihu môže TensorFlow znieť ako prehnaný pri vykonávaní základných operácií. Ale samozrejme, TensorFlow má prevádzkovať grafy oveľa väčšie ako toto.

Navyše, tenzory, s ktorými sa zaoberá v reálnych modeloch, sú oveľa väčšie čo do veľkosti i postavenia. Toto sú skutočné modely strojového učenia, kde TensorFlow nachádza svoje skutočné využitie.

Nie je ťažké vidieť, že práca s jadrom API v TensorFlow môže byť veľmi ťažkopádna, keď sa veľkosť grafu zväčšuje. Do tohto konca, TensorFlow poskytuje na vysokej úrovni API, ako je Keras, na prácu so zložitými modelmi. Bohužiaľ zatiaľ neexistuje nijaká oficiálna podpora pre Keras na Jave.

Môžeme však použite Python na definovanie a trénovanie zložitých modelov buď priamo v TensorFlow, alebo pomocou rozhraní API na vysokej úrovni, ako je Keras. Následne môžeme exportujte trénovaný model a použite ho v prostredí Java pomocou Java API TensorFlow.

Prečo by sme teraz chceli niečo také robiť? To je obzvlášť užitočné v situáciách, keď chceme používať funkcie s povoleným strojovým učením v existujúcich klientoch bežiacich na Jave. Napríklad odporúčanie titulkov k obrázkom používateľov v zariadení Android. Existuje niekoľko prípadov, keď nás zaujíma výstup z modelu strojového učenia, ale nemusíme nevyhnutne chcieť tento model vytvoriť a trénovať v Jave.

To je miesto, kde TensorFlow Java API nachádza väčšinu svojho použitia. V nasledujúcej časti si ukážeme, ako sa to dá dosiahnuť.

8. Používanie uložených modelov

Teraz pochopíme, ako môžeme uložiť model v TensorFlow do súborového systému a nahrať ho späť prípadne v úplne inom jazyku a platforme. TensorFlow poskytuje API na generovanie modelových súborov v jazykovo a platformovo neutrálnej štruktúre nazývanej Protocol Buffer.

8.1. Ukladanie modelov do súborového systému

Začneme definovaním rovnakého grafu, ktorý sme vytvorili predtým v Pythone, a jeho uložením do súborového systému.

Pozrime sa, že to môžeme urobiť v Pythone:

importujte tensorflow ako tf graph = tf.Graph () builder = tf.saved_model.builder.SavedModelBuilder ('./ model') s graph.as_default (): a = tf.constant (2, name = "a") b = tf.constant (3, name = "b") x = tf.placeholder (tf.int32, name = "x") y = tf.placeholder (tf.int32, name = "y") z = tf.math. add (a * x, b * y, name = "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 ()

V rámci tohto výukového programu v Jave sa nebudeme venovať veľkým detailom tohto kódu v Pythone, okrem skutočnosti, že generuje súbor s názvom „saved_model.pb“. Upozorňujeme na krátkosť definície podobného grafu v porovnaní s Javou!

8.2. Načítavajú sa modely zo súborového systému

Teraz načítame súbor „saved_model.pb“ do Javy. Rozhranie Java TensorFlow API má SavedModelBundle pracovať s uloženými modelmi:

SavedModelBundle model = SavedModelBundle.load ("./ model", "slúžiť"); Tenzor tenzora = 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 ());

Teraz by už malo byť celkom intuitívne pochopiť, čo vyššie uvedený kód robí. Jednoducho načíta modelový graf z vyrovnávacej pamäte protokolu a sprístupní v ňom reláciu. Od tejto chvíle môžeme s týmto grafom robiť čokoľvek, čo by sme robili pre lokálne definovaný graf.

9. Záver

Ak to zhrnieme, v tomto tutoriáli sme si prešli základné pojmy týkajúce sa výpočtového grafu TensorFlow. Videli sme, ako použiť TensorFlow Java API na vytvorenie a spustenie takéhoto grafu. Potom sme hovorili o prípadoch použitia rozhrania Java API s ohľadom na TensorFlow.

V tomto procese sme tiež pochopili, ako vizualizovať graf pomocou TensorBoard a ako uložiť a znovu načítať model pomocou Protocol Buffer.

Ako vždy, kód príkladov je k dispozícii na GitHub.


$config[zx-auto] not found$config[zx-overlay] not found