Uvod u Tensorflow za Javu

1. Pregled

TensorFlow je biblioteka otvorenog koda za programiranje protoka podataka. Ovo je izvorno razvio Google i dostupan je za širok spektar platformi. Iako TensorFlow može raditi na jednoj jezgri, može kao lako iskoristiti više dostupnih CPU-a, GPU-a ili TPU-a.

U ovom uputstvu proći ćemo kroz osnove TensorFlowa i kako ga koristiti u Javi. Napominjemo da je Java API TensorFlow eksperimentalni API i stoga nije pokriven nikakvim jamstvom stabilnosti. Kasnije ćemo u ovom priručniku opisati moguće slučajeve korištenja Java API-ja TensorFlow.

2. Osnove

Izračun TensorFlow-a u osnovi se vrti okolo dva temeljna pojma: grafikon i sesija. Prođimo kroz njih brzo kako bismo stekli pozadinu potrebnu za prolazak kroz ostatak vodiča.

2.1. Grafikon TensorFlow

Za početak, shvatimo temeljne gradivne dijelove programa TensorFlow. Izračuni su predstavljeni kao grafovi u TensorFlowu. Grafik je obično usmjereni aciklički graf operacija i podataka, na primjer:

Gornja slika predstavlja računski graf za sljedeću jednadžbu:

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

Računski graf TensorFlow sastoji se od dva elementa:

  1. Tensor: To su temeljna jedinica podataka u TensorFlowu. Prikazani su kao rubovi u računalnom grafu, koji prikazuju protok podataka kroz graf. Tenzor može imati oblik s bilo kojim brojem dimenzija. Broj dimenzija u tenzoru obično se naziva njegovim rangom. Dakle, skalar je tenzor ranga 0, vektor je tenzor ranga 1, matrica je tenzor ranga 2, i tako dalje i tako dalje.
  2. Operacija: To su čvorovi u računskom grafu. Oni se odnose na širok spektar izračunavanja koji se mogu dogoditi na tenzorima koji ulaze u operaciju. Često rezultiraju i tenzorima koji iz operacije proizlaze u računalnom grafikonu.

2.2. Sjednica TensorFlow

Sada je TensorFlow graf puka shema izračuna koja zapravo ne sadrži vrijednosti. Takva graf mora biti pokrenut unutar onoga što se naziva TensorFlow sesija da bi se tenzori u grafu procijenili. Sesija može potrajati hrpu tenzora za procjenu na grafikonu kao ulazne parametre. Zatim se pokreće unatrag u grafikonu i izvodi sve čvorove potrebne za procjenu tih tenzora.

S tim znanjem, sada smo spremni to poduzeti i primijeniti na Java API!

3. Postavljanje Mavena

Postavit ćemo brzi Maven projekt za stvaranje i pokretanje TensorFlow grafa u Javi. Samo nam treba tensorflow ovisnost:

 org.tensorflow tenzorflow 1.12.0 

4. Izrada grafikona

Pokušajmo sada izgraditi graf o kojem smo raspravljali u prethodnom odjeljku koristeći TensorFlow Java API. Točnije, za ovaj ćemo vodič koristiti TensorFlow Java API za rješavanje funkcije predstavljene sljedećom jednadžbom:

z = 3 * x + 2 * y

Prvi korak je deklariranje i inicijalizacija grafa:

Grafikon grafikona = novi grafikon ()

Sada moramo definirati sve potrebne operacije. Zapamti to operacije u TensorFlowu troše i proizvode nula ili više tenzora. Štoviše, svaki čvor na grafu je operacija koja uključuje konstante i rezervirana mjesta. Ovo se može činiti kontraintuitivno, ali podnesite ga na trenutak!

Razred Grafikon ima generičku funkciju tzv opBuilder () za izgradnju bilo kakve operacije na TensorFlowu.

4.1. Utvrđivanje konstanti

Za početak definirajmo konstantne operacije na našem grafikonu gore. Imajte na umu da a stalni rad trebat će tenzor za svoju vrijednost:

Operacija a = graph.opBuilder ("Const", "a") .setAttr ("dtype", DataType.fromClass (Double.class)) .setAttr ("value", Tensor.create (3.0, Double.class)). izgraditi(); Operacija b = graph.opBuilder ("Const", "b") .setAttr ("dtype", DataType.fromClass (Double.class)) .setAttr ("value", Tensor.create (2.0, Double.class)). izgraditi();

Ovdje smo definirali Operacija stalnog tipa, hranjenje u Tenzor s Dvostruko vrijednosti 2,0 i 3,0. Za početak se može činiti malo poraznim, ali to je upravo tako u Java API-u za sada. Te su konstrukcije mnogo jezgrovitije u jezicima poput Pythona.

4.2. Utvrđivanje rezerviranih mjesta

Iako trebamo pružiti vrijednosti našim konstantama, rezerviranim mjestima nije potrebna vrijednost u vrijeme definicije. Vrijednosti rezerviranog mjesta moraju se navesti kada se grafikon izvodi unutar sesije. Taj ćemo dio proći kasnije u vodiču.

Za sada, da vidimo kako možemo definirati svoja rezervirana mjesta:

Operacija x = graph.opBuilder ("Rezervirano mjesto", "x") .setAttr ("dtype", DataType.fromClass (Double.class)) .build (); Operacija y = graph.opBuilder ("Rezervirano mjesto", "y") .setAttr ("dtype", DataType.fromClass (Double.class)) .build ();

Imajte na umu da nismo trebali pružiti nikakvu vrijednost našim rezerviranim mjestima. Te vrijednosti će se hraniti kao Tenzori kad se trči.

4.3. Definiranje funkcija

Konačno, moramo definirati matematičke operacije naše jednadžbe, naime množenje i zbrajanje da bismo dobili rezultat.

To opet nisu ništa drugo nego Operacijas u TensorFlowu i Graph.opBuilder () je još jednom zgodan:

Operacija ax = graph.opBuilder ("Mul", "ax") .addInput (a.output (0)) .addInput (x.output (0)) .build (); Operacija = graph.opBuilder ("Mul", "by") .addInput (b.output (0)) .addInput (y.output (0)) .build (); Operacija z = graph.opBuilder ("Dodaj", "z") .addInput (ax.output (0)) .addInput (by.output (0)) .build ();

Evo, tamo smo definirali Operacija, dva za množenje naših inputa i konačni za zbrajanje srednjih rezultata. Imajte na umu da operacije ovdje primaju tenzore koji nisu ništa drugo do rezultat naših ranijih operacija.

Imajte na umu da dobivamo izlazne podatke Tenzor od Operacija pomoću indeksa '0'. Kao što smo ranije razgovarali, an Operacija može rezultirati jednim ili više Tenzor i stoga, dok dohvaćamo kvaku za to, moramo spomenuti indeks. Budući da znamo da naše operacije vraćaju samo jedno Tenzor, '0' djeluje sasvim dobro!

5. Vizualizacija grafikona

Teško je zadržati karticu na grafikonu jer ona raste u veličini. Ovo ga čini važno to vizualizirati na neki način. Uvijek možemo stvoriti ručni crtež poput malog grafa koji smo prethodno stvorili, ali to nije praktično za veće grafikone. TensorFlow nudi uslužni program pod nazivom TensorBoard koji to olakšava.

Nažalost, Java API nema mogućnost generiranja datoteke događaja koju konzumira TensorBoard. Ali pomoću API-ja u Pythonu možemo generirati datoteku događaja poput:

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

Molimo vas da se ne zamarate ako ovo nema smisla u kontekstu Jave, ovo je ovdje dodano samo radi cjelovitosti i nije potrebno za nastavak ostatka tutorijala.

Sada u TensorBoard možemo učitati i vizualizirati datoteku događaja poput:

tensorboard --logdir.

TensorBoard dolazi kao dio instalacije TensorFlow.

Primijetite sličnost između ovog i ručno nacrtanog grafa ranije!

6. Rad sa sesijom

Sada smo stvorili računski graf za našu jednostavnu jednadžbu u TensorFlow Java API-ju. Ali kako to vodimo? Prije nego što se pozabavimo time, pogledajmo u kakvom je stanju Grafikon upravo smo stvorili u ovom trenutku. Ako pokušamo ispisati rezultat našeg konačnog Operacija "Z":

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

To će rezultirati nečim poput:

Ovo nije ono što smo očekivali! Ali ako se prisjetimo onoga o čemu smo ranije razgovarali, ovo zapravo ima smisla. The Grafikon upravo smo definirali da još nije pokrenut, tako da tenzori u njemu zapravo nemaju nikakvu stvarnu vrijednost. Izlaz gore samo govori da će ovo biti Tenzor tipa Dvostruko.

Ajmo sada definirati a Sjednica pokrenuti naše Grafikon:

Sjednica sess = nova sjednica (grafikon)

Konačno, sada smo spremni pokrenuti naš Graf i dobiti izlaz koji smo očekivali:

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 ());

Pa što mi radimo ovdje? Trebalo bi biti prilično intuitivno:

  • Dobiti Trkač od Sjednica
  • Definirajte Operacija dohvatiti imenom "z"
  • Unesite tenzore za naša rezervirana mjesta "x" i "y"
  • Pokrenite Grafikon u Sjednica

I sada vidimo skalarni izlaz:

21.0

Ovo smo očekivali, zar ne!

7. Slučaj upotrebe za Java API

U ovom trenutku TensorFlow može zvučati pretjerano za obavljanje osnovnih operacija. Ali, naravno, TensorFlow je namijenjen izvođenju mnogo većih grafova od ovoga.

Dodatno, tenzori s kojima se bavi u stvarnim modelima mnogo su veći po veličini i rangu. To su stvarni modeli strojnog učenja u kojima TensorFlow pronalazi svoju stvarnu upotrebu.

Nije teško uočiti da rad s jezgrom API-ja u TensorFlowu može postati vrlo glomazan kako se veličina grafikona povećava. Do kraja, TensorFlow nudi API-je visoke razine poput Kerasa za rad sa složenim modelima. Nažalost, još uvijek nema nikakve službene podrške za Keras na Javi.

Međutim, možemo koristite Python za definiranje i obuku složenih modela bilo izravno u TensorFlowu ili pomoću API-ja visoke razine poput Kerasa. Poslije toga možemo izvezite obučeni model i upotrijebite ga u Javi pomoću Java API-ja TensorFlow.

Sad, zašto bismo željeli učiniti tako nešto? Ovo je posebno korisno u situacijama kada želimo koristiti značajke omogućene strojnim učenjem u postojećim klijentima koji rade na Javi. Na primjer, preporučivanje opisa za korisničke slike na Android uređaju. Ipak, postoji nekoliko slučajeva kada smo zainteresirani za rezultate modela strojnog učenja, ali ne želimo nužno stvoriti i obučiti taj model u Javi.

Tu TensorFlow Java API pronalazi glavninu njegove upotrebe. Kako će se to postići, proći ćemo u sljedećem odjeljku.

8. Korištenje spremljenih modela

Sada ćemo razumjeti kako možemo spremiti model u TensorFlowu u datotečni sustav i učitati ga natrag, možda na potpuno drugom jeziku i platformi. TensorFlow nudi API-je za generiranje datoteka modela u strukturi koja je neutralna za jezik i platformu nazvanu Protocol Buffer.

8.1. Spremanje modela u datotečni sustav

Započet ćemo definiranjem istog grafa koji smo stvorili ranije u Pythonu i spremanjem u datotečni sustav.

Da vidimo da li to možemo učiniti u Pythonu:

uvoz tensorflow kao 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. dodaj (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 ()

Kao fokus ovog vodiča na Javi, nemojmo obraćati previše pažnje na detalje ovog koda u Pythonu, osim na činjenicu da generira datoteku nazvanu "saved_model.pb". Primijetite kratkoću u definiranju sličnog grafikona u usporedbi s Javom!

8.2. Učitavanje modela iz datotečnog sustava

Sada ćemo u Java učitati "saved_model.pb". Java TensorFlow API ima SavedModelBundle za rad sa spremljenim modelima:

SavedModelBundle model = SavedModelBundle.load ("./ model", "serve"); 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 ());

Do sada bi trebalo biti prilično intuitivno razumjeti što gornji kod radi. Jednostavno učitava grafikon modela iz međuspremnika protokola i čini dostupnom sesiju u njemu. Od tada nadalje, s ovim grafom možemo učiniti gotovo sve što bismo mogli učiniti za lokalno definirani graf.

9. Zaključak

Da rezimiramo, u ovom smo tutorijalu prošli kroz osnovne koncepte povezane s računalnim grafom TensorFlow. Vidjeli smo kako koristiti Java API TensorFlow za stvaranje i pokretanje takvog grafa. Zatim smo razgovarali o slučajevima upotrebe Java API-ja s obzirom na TensorFlow.

U tom smo procesu također razumjeli kako vizualizirati graf pomoću TensorBoarda te spremiti i ponovo učitati model pomoću protokola međuspremnika.

Kao i uvijek, kod za primjere dostupan je na GitHub-u.


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