Effektiv TensorFlow 2.0: Beste fremgangsmåter og hva som er endret

Skrevet av TensorFlow Team

I en nylig artikkel nevnte vi at TensorFlow 2.0 har blitt redesignet med fokus på utviklerens produktivitet, enkelhet og brukervennlighet.

For å se nærmere på hva som er endret og lære om beste fremgangsmåter, sjekk ut den nye Effektiv TensorFlow 2.0-guiden (publisert på GitHub). Denne artikkelen gir en rask oversikt over innholdet du finner der. Hvis noen av disse emnene interesserer deg, kan du gå til guiden for å lære mer!

En kort oppsummering av større endringer

Det er mange endringer i TensorFlow 2.0 for å gjøre brukerne mer produktive, inkludert å fjerne overflødige API-er, gjøre API-er mer konsistente (Unified RNNs, Unified Optimizers), og bedre integrere med Python-runtime med Eager-utførelse.

Mange RFC-er (sjekk dem ut, hvis du er ny på det!) Har forklart endringene og tankene som har gått til å lage TensorFlow 2.0. Denne guiden presenterer en visjon for hvordan utvikling i TensorFlow 2.0 skal se ut. Det antas at du er kjent med TensorFlow 1.x.

API-opprydding

Mange APIer er enten borte eller flyttet i TF 2.0, og noen har blitt erstattet med 2,0 ekvivalenter - tf.summary, tf.keras.metrics og tf.keras.optimizers. Den enkleste måten å automatisk bruke disse navnene på er å bruke v2-oppgraderingsskriptet.

Ivrig henrettelse

TensorFlow 1.X krever at brukerne manuelt sy sammen et abstrakt syntaks-tre (grafen) ved å foreta tf. * API-anrop. Det krever at brukerne manuelt skal kompilere det abstrakte syntaks-treet ved å sende et sett med utspenningstensorer og legge inn tensorer til en session.run () -samtale. Derimot kjører TensorFlow 2.0 ivrig (slik Python vanligvis gjør), og i 2.0 skal grafer og økter føles som implementeringsdetaljer.

Ingen flere globals

TensorFlow 1.X stolte veldig på implisitt globale navnefelt. Når du kalte tf.Variable (), ville den bli satt inn i standardgrafen, og den vil forbli der, selv om du mistet oversikten over Python-variabelen som peker på den. Du kan deretter gjenopprette det tf. Variabelt, men bare hvis du visste navnet det var opprettet med. Dette var vanskelig å gjøre hvis du ikke hadde kontroll over variabelen. Som et resultat spredte det seg alle slags mekanismer for å forsøke å hjelpe brukere med å finne variablene sine igjen.

TensorFlow 2.0 eliminerer alle disse mekanismene (Variables 2.0 RFC) til fordel for standardmekanismen: Hold oversikt over variablene dine! Hvis du mister oversikten over en tf.Variable, blir det søppel samlet inn. Se veiledningen for mer informasjon.

Funksjoner, ikke økter

En session.run () -samtale er nesten som et funksjonsanrop: Du spesifiserer inngangene og funksjonen som skal ringes, og du får tilbake et sett utganger. I TensorFlow 2.0 kan du dekorere en Python-funksjon ved å bruke tf.function () for å markere den for JIT-kompilering, slik at TensorFlow kjører den som en enkelt graf (Functions 2.0 RFC).

Denne mekanismen lar TensorFlow 2.0 få alle fordelene med grafmodus:

  • Ytelse: Funksjonen kan optimaliseres (node-beskjæring, kjernefusjon, etc.)
  • Portabilitet: Funksjonen kan eksporteres / importeres på nytt (SavedModel 2.0 RFC), slik at brukerne kan gjenbruk og dele modulære TensorFlow-funksjoner.

Med kraften til å spre Python og TensorFlow-koden fritt, kan du dra full nytte av Pythons ekspressivitet. Men bærbar TensorFlow kjører i sammenhenger uten en Python-tolk - mobil, C ++ og JS. For å hjelpe brukere med å unngå å skrive om koden når de legger til @ tf.function, vil AutoGraph konvertere et underett av Python-konstruksjoner til TensorFlow-ekvivalenter.

Se veiledningen for mer informasjon.

Anbefalinger for idiomatisk TensorFlow 2.0

Refaktor koden din til mindre funksjoner

Et vanlig bruksmønster i TensorFlow 1.X var "kjøkkenvasken" -strategien, der foreningen av alle mulige beregninger ble preemptivt lagt ut, og deretter valgte tensorer ble evaluert via session.run (). I TensorFlow 2.0 skal brukerne refaktorere koden sin til mindre funksjoner som kalles etter behov. Generelt er det ikke nødvendig å dekorere hver av disse mindre funksjonene med funksjonen; bare bruk tf.function for å dekorere beregninger på høyt nivå - for eksempel ett treningstrinn eller modellens forkjøring.

Bruk Keras-lag og modeller for å administrere variabler

Keras-modeller og lag tilbyr de praktiske variablene og trenbare egenskapene, som rekursivt samler alle avhengige variabler. Dette gjør det enkelt å administrere variabler lokalt der de blir brukt.

Keras lag / modeller arver fra tf.train.Checkpointable og er integrert med @ tf.function, noe som gjør det mulig å direkte sjekke eller eksportere SavedModels fra Keras-objekter. Du trenger ikke nødvendigvis å bruke Keras’s.fit () API for å dra nytte av disse integrasjonene.

Se veiledningen for mer informasjon.

Kombiner tf.data.Datasets og @ tf.function

Når du itererer over treningsdata som passer i minnet, kan du gjerne bruke vanlig Python-iterasjon. Ellers er tf.data.Dataset den beste måten å streame treningsdata fra disk. Datasett er iterables (ikke iteratorer), og fungerer akkurat som andre Python-iterables i ivrig-modus. Du kan fullt ut benytte datasett async prefetching / streaming funksjoner ved å pakke inn koden din i tf.function (), som erstatter Python-iterasjon med tilsvarende grafoperasjoner ved hjelp av AutoGraph.

@ tf.function
def train (modell, datasett, optimizer):
 for x, y i datasett:
  med tf.GradientTape () som tape:
   prediksjon = modell (x)
   tap = loss_fn (prediksjon, y)
  gradients = tape.gradients (loss, model.trainable_variables)
  optimizer.apply_gradients (gradients, model.trainable_variables)

Hvis du bruker Keras .fit () API, trenger du ikke å bekymre deg for datasett-iterasjon.

model.compile (optimizer = optimizer, loss = loss_fn)
model.fit (datasettet)

Dra nytte av AutoGraph med Python kontrollstrøm

AutoGraph gir en måte å konvertere datavhengig kontrollstrøm til grafmodusekvivalenter som tf.cond og tf.while_loop.

Et vanlig sted der datavhengig kontrollstrøm vises er i sekvensmodeller. tf.keras.layers.RNN pakker inn en RNN-celle, slik at du enten kan statisk eller dynamisk rulle ut gjentakelsen. For demonstrasjonens skyld kan du implementere dynamisk avrulling på nytt på følgende måte:

klasse DynamicRNN (tf.keras.Model):
def __init __ (self, rnn_cell):
 super (DynamicRNN, self) .__ init __ (self)
 self.cell = rnn_cell
def call (selv, input_data):
 # [batch, tid, funksjoner] -> [tid, batch, funksjoner]
 input_data = tf.transpose (input_data, [1, 0, 2])
 utganger = tf.TensorArray (tf.float32, input_data.shape [0])
 state = self.cell.zero_state (input_data.shape [1], dtype = tf.float32)
 for i i tf.range (input_data.shape [0]):
  output, state = self.cell (input_data [i], state)
  output = outputs.write (i, output)
 return tf.transpose (output.stack (), [1, 0, 2]), state

Se veiledningen for mer informasjon.

Bruk tf.metrics for å samle data og tf.summary for å logge dem

Endelig kommer et komplett sett med tf.summary symboler snart. Du får tilgang til 2.0-versjonen av tf.summary med:

fra tensorflow.python.ops importer oppsummering_ops_v2

Se veiledningen for mer informasjon.

Neste skritt

Denne artikkelen ga et raskt sammendrag av den effektive TF 2.0-guiden (hvis du er interessert i disse emnene, gå dit for å lære mer!) For å lære mer om TensorFlow 2.0, anbefaler vi også disse nylige artiklene:

  • Bidra til TensorFlow: SIGs, RFCs, Testing and Docs.
  • Hva er symbolsk og imperativ API i TensorFlow 2.0?
  • Standardisering av Keras: Veiledning på høye nivå APIer i TensorFlow 2.0

Og vennligst still deg inn for TensorFlow-utviklermøtet 6. og 7. mars. Som alltid blir alle samtalene lastet opp til YouTube for folk som ikke kan gjøre det personlig.