Sådan bruges datasæt og Iteratorer i Tensorflow med kodeprøver

Fra det tidspunkt, jeg begyndte at bruge Tensorflow, har jeg altid fodret dataene til min graf under træning, test eller inferencing ved hjælp af feed_dict-mekanismen i Session. Denne særlige praksis er blevet anbefalet af Tensorflow-udviklere om at blive stærkt afbrudt enten under træningen eller gentagne gange teste den samme datasæt. Det eneste særlige scenario, hvor feed_dict-mekanisme skal bruges, er under inferencing af data under installationen. Udskiftningen af ​​feed_dict har fundet sted med Dataset og Iterator. Datasættet kan oprettes enten med Numpy array eller TFRecords eller med tekst.

I dette indlæg udforsker vi datasæt og Iteratorer. Vi starter med, hvordan man opretter datasæt ved hjælp af nogle kildedata og derefter anvender forskellige former for transformationer til det. Vi vil demonstrere, hvordan man træner ved hjælp af forskellige typer iteratorer med MNIST-håndskrevne cifordata på LeNet-5-modellen.

Bemærk: Tensorflow Dataset-klassen kan blive meget forvirrende med ord, der er beregnet til datasæt som X_train, y_train osv. Derfor henviser jeg til 'Dataset' (hovedstad D) som Tensorflow Dataset-klasse og 'datasæt' som datasæt for i denne artikel X_train, y_train osv.

Oprettelse af datasæt

Datasæt kan genereres ved hjælp af flere typer datakilder som Numpy, TFRecords, tekstfiler, CSV-filer osv. Den mest almindelige praksis for generering af datasæt er fra Numpy (eller Tensors). Lad os gennemgå alle de funktioner, der leveres af Tensorflow for at generere dem.

a) fra_tensor_slices: Denne metode accepterer individuelle (eller flere) numpede (eller Tensorer) -objekter. I tilfælde af at du fodrer flere objekter, skal du give dem som tuple og sørge for, at alle objekter har samme størrelse i nul dimension.

b) from_tensors: Ligesom from_tensor_slices accepterer denne metode også individuelle (eller flere) numpy (eller Tensors) -objekter. Men denne metode understøtter ikke batching af data, dvs. alle data udleveres med det samme. Som et resultat kan du videregive input i forskellige størrelser i nul dimension, hvis du passerer flere objekter. Denne metode er nyttig i tilfælde, hvor datasæt er meget lille, eller din læringsmodel har brug for alle data på én gang.

c) fra_generator: I denne metode overføres en generatorfunktion som input. Denne metode er nyttig i tilfælde, hvor du ønsker at generere dataene under kørsel, og som sådan findes der ingen rå data hos dig eller i scenarier, hvor dine træningsdata er ekstremt enorme, og det ikke er muligt at gemme dem på din disk. Jeg vil kraftigt opfordre folk til ikke at bruge denne metode til at generere dataforstørrelser.

Datasæt Transformationer

Når du har oprettet datasættet, der dækker alle data (eller scenarier, i nogle tilfælde som generering af runtime-data), er det tid til at anvende forskellige former for transformation. Lad os gennemgå nogle af ofte anvendte transformationer.

a) Batch: Batch svarer til at dele dit datasæt sekventielt med den specificerede batchstørrelse.

Illustration af batchtransformation

b) Gentag: Uanset hvilket datasæt du har genereret, skal du bruge denne transformation til at oprette duplikater af de eksisterende data i dit datasæt.

Illustration af gentagen transformation

c) Bland: Blanding af transformation blander tilfældigt dataene i dit datasæt.

Illustration af blandingstransformation

d) Kort: I korttransformation kan du anvende nogle operationer på alle de individuelle dataelementer i dit datasæt. Brug denne særlige transformation til at anvende forskellige typer dataforøgelse. (Du kan tjekke mit andet Medium-indlæg på billedforøgelse)

Illustration, der viser korttransformation

e) Filter: Brug filterfunktion, hvis du vil filtrere nogle elementer fra Dataset.

Illustration, der viser filtertransformation

Kodeneksempel på forskellige transformationer, der anvendes på et datasæt, vises næste.

Bestilling af transformation

Bestillingen af ​​anvendelsen af ​​transformationen er meget vigtig. Din model lærer måske forskelligt for det samme datasæt, men forskelligt bestilte transformationer. Se på den kodeeksempel, hvor det er vist, at der produceres forskellige datasæt.

Bygning af LeNet-5 Model

Inden vi starter iterator-delen, lad os hurtigt bygge vores LeNet-5-model og udtrække MNIST-data. Jeg har brugt Tensorflows Slim-bibliotek til at opbygge modellen på få linjer. Dette vil være den fælles kode for alle typer iteratorer, vi skal arbejde videre med næste.

iteratorer

Lad os begynde at opbygge iteratorerne. Tensorflow har leveret fire typer iteratorer, og hver af dem har et specifikt formål og brugssag bag det.

Uanset typen af ​​iterator bruges get_next-funktionen til iterator til at oprette en operation i din Tensorflow-graf, der, når der køres over en session, returnerer værdierne fra den indførte datasæt af iterator. Iterator holder ikke styr på, hvor mange elementer der findes i datasættet. Derfor er det normalt at køre iteratorens get_next-operation, indtil Tensorflows tf.errors.OutOfRangeError-undtagelse er forekommet. Dette er normalt skeletkoden for, hvordan et datasæt og iterator ser ud.

Lad os derefter undersøge hver type iterator.

a) Iterator med et skud

Dette er den mest basale type iterator. Alle data med alle typer transformationer, der er nødvendige i datasættet, skal afgøres, før datasættet indføres i denne iterator. En-shot iterator itererer gennem alle elementerne, der findes i datasættet, og når de først er opbrugt, kan de ikke bruges mere. Som et resultat kan datasættet, der genereres til denne iterator, have en tendens til at besætte en masse hukommelse.

I eksemplet ovenfor har vi genereret datasættet for i alt 10 epoker. Brug kun denne særlige iterator, hvis dit datasæt er lille i størrelse eller i tilfælde, hvor du kun ønsker at udføre test på din model kun én gang.

b) Initialiserbar

I en-shot iterator havde vi manglen på gentagelse af det samme træningsdatasæt i hukommelsen, og der var mangel på periodisk at validere vores model ved hjælp af valideringsdatasæt i vores kode. I initialiserbar iterator overvinder vi disse problemer. Initierbar iterator skal initialiseres med datasæt, før den begynder at køre. Se koden.

Som det kan ses, ved hjælp af initialiseringsfunktion, har vi ændret datasættet mellem træning og validering ved hjælp af det samme Dataset-objekt.

Denne iterator er meget ideel, når du skal træne din model med datasæt, der er opdelt på flere steder, og du ikke er i stand til at akkumulere dem ét sted.

c) Geninitialiserbar

I initialiserbar iterator var der en mangel på forskellige datasæt, der gennemgik den samme rørledning, før datasættet føres ind i iteratoren. Dette problem overvindes af geninitialiserbar iterator, da vi har evnen til at fodre forskellige typer datasæt og derved gennemgå forskellige rørledninger. Der skal kun udvises én forsigtighed, at forskellige datasæt er af samme datatype. Se koden.

Bemærk, at træningsdatasætobjekt gennemgår yderligere forøgelse, hvilket valideringsdatasæt ikke er. Du kunne have direkte fodret trænings- og valideringsdatasæt i Dataset-objekter, men jeg har brugt pladsholdere bare for at vise fleksibiliteten.

d) Fødelig

Den geninitialiserbare iterator gav fleksibiliteten ved at tildele forskellige pipelinerede datasæt til iterator, men iteratoren var utilstrækkelig til at opretholde tilstanden (dvs. indtil hvor dataene er blevet udsendt af individuel iterator). I kodeprøven viser jeg, hvordan man bruger Feedable iterator.

Selvom det ikke er illustreret i ovenstående kodeprøve, kan vi ved hjælp af strenghåndtaget genstarte det bestemte punkt, hvorfra dataekstraktionen blev udført, mens vi skifter mellem forskellige datasæt.

Denne iterator er ideel i scenarier, hvor du samtidig træner en model med forskellige datasæt, og du har brug for bedre kontrol for at bestemme, hvilken bestemt batch af datasæt der skal fodres ved siden af ​​modellen.

Datasæt kan også genereres med TFRecords. Jeg har skrevet en anden artikel om, hvordan man opretter TFRecords, og hvordan man foder det ind i datasæt i en anden artikel. Kontroller det, da det er som del 2 af denne artikel.

Du kan kontrollere koden, der er brugt i denne artikel fra mit Github-arkiv.

Eller hvis du vil se koden, der kører i den bærbare computer, kan du kontrollere den i min delte Colab-notebook.

Efterlad dine værdifulde kommentarer til, hvad du synes om denne artikel.