Applied Deep Learning-Del 3: Autoencoders

Velkommen Til Del 3 Av Applied Deep Learning-serien. Del 1 var en praktisk introduksjon til Kunstige Nevrale Nettverk, som dekker både teorien og applikasjonen med mange kodeeksempler og visualisering. I Del 2 brukte vi dyp læring til virkelige datasett, som dekker de 3 vanligste problemene som casestudier: binær klassifisering, multiclass klassifisering og regresjon.

nå skal Vi begynne å dykke inn i spesifikke dype læringsarkitekturer, som starter med det enkleste: Autoencoders.

  1. Introduksjon
  2. Arkitektur
  3. Implementering
  4. Denoising Autoenkodere
  5. Sparsomme Autoenkodere
  6. Brukstilfeller
  7. Konklusjon

koden for denne artikkelen er tilgjengelig her som en jupyter notebook, gjerne Laste Ned Og Prøve Det Ut Selv.

Innledning

Autoencoders er en bestemt type feedforward nevrale nettverk der inngangen er den samme som utgangen. De komprimerer inngangen til en lavere dimensjonal kode og rekonstruerer deretter utgangen fra denne representasjonen. Koden er en kompakt » sammendrag «eller» komprimering » av inngangen, også kalt latent-plass representasjon.

en autoencoder består av 3 komponenter: encoder, kode og dekoder. Koderen komprimerer inngangen og produserer koden, dekoderen rekonstruerer deretter inngangen bare ved hjelp av denne koden.

for å bygge en autoencoder trenger vi 3 ting: en kodingsmetode, dekodingsmetode og en tapsfunksjon for å sammenligne utgangen med målet. Vi vil utforske disse i neste avsnitt.

Autoencoders er hovedsakelig en dimensjonal reduksjon (eller komprimering) algoritme med et par viktige egenskaper:

  • data-spesifikk: Autoencoders er bare i stand til å menings komprimere data som ligner på hva de har blitt trent på. Siden de lærer funksjoner som er spesifikke for de oppgitte treningsdataene, er de forskjellige enn en standard datakomprimeringsalgoritme som gzip. Så vi kan ikke forvente en autoencoder trent på håndskrevne sifre for å komprimere landskapsbilder.
  • Lossy: Utgangen av autoencoderen vil ikke være nøyaktig den samme som inngangen, det vil være en nær, men forringet representasjon. Hvis du vil ha lossless komprimering, er de ikke veien å gå.
  • Unsupervised: for å trene en autoencoder trenger vi ikke å gjøre noe fancy, bare kaste de rå inngangsdataene på den. Autoencoders anses som en uovervåket læringsteknikk siden de ikke trenger eksplisitte etiketter for å trene på. Men for å være mer presis er de selvstyrte fordi de genererer egne etiketter fra treningsdataene.

Arkitektur

la oss utforske detaljene til koderen, koden og dekoderen. Både encoder og dekoder er fullt tilkoblet feedforward nevrale nettverk, i hovedsak De ANNs vi dekket I Del 1. Kode er et enkelt lag AV EN ANN med dimensjonaliteten av vårt valg. Antall noder i kodelaget (kodestørrelse) er en hyperparameter som vi angir før du trener autoencoderen.

Dette er en mer detaljert visualisering av en autoencoder. Først går inngangen gjennom koderen, som er en fullt tilkoblet ANN, for å produsere koden. Dekoderen, som har den samme ANN-strukturen, produserer deretter utgangen bare ved hjelp av koden. Målet er å få en utgang identisk med inngangen. Legg merke til at dekoderarkitekturen er speilbildet av koderen. Dette er ikke et krav, men det er vanligvis tilfelle. Det eneste kravet er dimensjonaliteten til inngang og utgang må være den samme. Alt i midten kan spilles med.

Det er 4 hyperparametere som vi må sette før du trener en autoencoder:

  • Kodestørrelse: antall noder i mellomlaget. Mindre størrelse resulterer i mer kompresjon.
  • Antall lag: autoencoderen kan være så dyp som vi liker. I figuren ovenfor har vi 2 lag i både koder og dekoder, uten å vurdere inngang og utgang.
  • Antall noder per lag: autoencoder-arkitekturen vi jobber med kalles en stablet autoencoder siden lagene er stablet etter hverandre. Vanligvis stablet autoencoders ser ut som en»sandwitch». Antall noder per lag reduseres med hvert etterfølgende lag av koderen, og øker tilbake i dekoderen. Også dekoderen er symmetrisk til koderen når det gjelder lagstruktur. Som nevnt ovenfor er dette ikke nødvendig, og vi har full kontroll over disse parametrene.
  • Tap funksjon: vi bruker enten mean squared error (mse) eller binær crossentropi. Hvis inngangsverdiene er i området, bruker vi vanligvis crossentropy, ellers bruker vi den gjennomsnittlige kvadrerte feilen. For mer informasjon sjekk ut denne videoen.

Autoencoders er trent på samme måte som ANNs via backpropagation. Sjekk ut introduksjonen Av Del 1 for mer informasjon om hvordan nevrale nettverk er opplært, det gjelder direkte for autoencoders.

Implementering

la Oss nå implementere en autoencoder for følgende arkitektur, 1 skjult lag i koderen og dekoderen.

Vi vil bruke det ekstremt populære MNIST datasettet som input. Den inneholder svart-hvitt bilder av håndskrevne sifre.

De er av størrelse 28×28 og vi bruker dem som en vektor av 784 tall mellom . Sjekk jupyter bærbare for detaljer.

vi vil nå implementere autoencoderen med Keras. Hyperparametrene er: 128 noder i det skjulte laget, kodestørrelsen er 32, og binær crossentropi er tapsfunksjonen.

Dette ligner Veldig På ANNs vi jobbet med, men nå bruker Vi Keras functional API. Se denne veiledningen for detaljer, men her er en rask sammenligning. Før vi pleide å legge til lag ved hjelp av sekvensiell API som følger:

model.add(Dense(16, activation='relu'))
model.add(Dense(8, activation='relu'))

med funksjonell API gjør vi dette:

layer_1 = Dense(16, activation='relu')(input)
layer_2 = Dense(8, activation='relu')(layer_1)

det er mer verbose, men en mer fleksibel måte å definere komplekse modeller på. Vi kan enkelt ta deler av vår modell, for eksempel bare dekoderen, og jobbe med det. Utgangen Av Tett metode er et callable lag, ved hjelp av funksjonell API gir vi det med inngangen og lagrer utgangen. Utgangen av et lag blir inngangen til neste lag. Med sekvensiell API håndterte add-metoden implisitt dette for oss.

Merk at alle lagene bruker relu-aktiveringsfunksjonen, da det er standarden med dype nevrale nettverk. Det siste laget bruker sigmoid-aktiveringen fordi vi trenger utgangene å være mellom . Inngangen er også i samme område.

legg også merke til kallet for å passe funksjon, før Med ANNs vi pleide å gjøre:

model.fit(x_train, y_train)

Men nå gjør vi:

model.fit(x_train, x_train)

Husk at målene til autoencoderen er de samme som inngangen. Derfor leverer vi treningsdataene som mål.

Visualisering

la Oss nå visualisere hvor godt vår autoencoder rekonstruerer sin inngang.

vi kjører autoencoderen på testsettet ved å bruke predict-funksjonen Til Keras. For hvert bilde i testsettet får vi utgangen av autoencoderen. Vi forventer at utgangen vil være svært lik inngangen.

De er faktisk ganske like, men ikke akkurat det samme. Vi kan legge merke til det tydeligere i det siste sifferet «4». Siden dette var en enkel oppgave vår autoencoder utført ganske bra.

Råd

vi har total kontroll over arkitekturen til autoencoderen. Vi kan gjøre det veldig kraftig ved å øke antall lag, noder per lag og viktigst kodestørrelsen. Å øke disse hyperparametrene vil la autoencoderen lære mer komplekse kodinger. Men vi bør være forsiktig med å ikke gjøre det for kraftig. Ellers autoencoder vil bare lære å kopiere sine innganger til utgangen, uten å lære noen meningsfull representasjon. Det vil bare etterligne identitetsfunksjonen. Autoencoderen vil rekonstruere treningsdataene perfekt, men det vil være overfitting uten å kunne generalisere til nye forekomster, noe som ikke er det vi ønsker.

Derfor foretrekker vi en» sandwitch » – arkitektur, og bevisst holder kodestørrelsen liten. Siden kodingslaget har en lavere dimensjonalitet enn inngangsdataene, sies autoencoderen å være underkomplett. Det vil ikke kunne kopiere inngangene direkte til utgangen, og vil bli tvunget til å lære intelligente funksjoner. Hvis inngangsdataene har et mønster, for eksempel inneholder sifferet «1» vanligvis en noe rett linje og sifferet » 0 » er sirkulært, vil det lære dette faktum og kode det i en mer kompakt form. Hvis inngangsdataene var helt tilfeldige uten intern korrelasjon eller avhengighet, vil en undercomplete autoencoder ikke kunne gjenopprette den perfekt. Men heldigvis i den virkelige verden er det mye avhengighet.

Denoising Autoencoders

Å Holde kodelaget lite tvang vår autoencoder til å lære en intelligent representasjon av dataene. Det er en annen måte å tvinge autoencoderen til å lære nyttige funksjoner, som legger til tilfeldig støy til inngangene og gjør det til å gjenopprette de opprinnelige støyfrie dataene. På denne måten kan autoencoderen ikke bare kopiere inngangen til utgangen fordi inngangen også inneholder tilfeldig støy. Vi ber den om å trekke fra støyen og produsere de underliggende meningsfulle dataene. Dette kalles en denoising autoencoder.

den øverste raden inneholder de opprinnelige bildene. Vi legger til tilfeldig Gaussisk støy til dem, og de støyende dataene blir inngangen til autoencoderen. Autoencoderen ser ikke det opprinnelige bildet i det hele tatt. Men så forventer vi at autoencoderen skal regenerere det støyfrie originalbildet.

Det er bare en liten forskjell mellom implementeringen av denoising autoencoder og den vanlige. Arkitekturen endres ikke i det hele tatt, bare fit-funksjonen. Vi trente den vanlige autoencoderen som følger:

autoencoder.fit(x_train, x_train)

Denoising autoencoder er opplært som:

autoencoder.fit(x_train_noisy, x_train)

Enkelt som det, alt annet er akkurat det samme. Inngangen til autoencoderen er det støyende bildet, og det forventede målet er den opprinnelige støyfrie.

Visualisering

la Oss nå visualisere om vi er i stand til å gjenopprette støyfrie bilder.

Ser ganske bra ut. Den nederste raden er autoencoder-utgangen. Vi kan gjøre det bedre ved å bruke mer kompleks autoencoder arkitektur, for eksempel convolutional autoencoders. Vi vil dekke konvolutter i den kommende artikkelen.

Sparsomme Autoencoders

vi introduserte To måter å tvinge autoencoderen til å lære nyttige funksjoner: holde kodestørrelsen liten og denoising autoencoders. Den tredje metoden bruker regularisering. Vi kan regulere autoencoderen ved å bruke en sparsity-begrensning slik at bare en brøkdel av nodene vil ha ikke-nullverdier, kalt aktive noder.

spesielt legger vi til en straffeperiode til tapsfunksjonen slik at bare en brøkdel av nodene blir aktive. Dette tvinger autoencoder å representere hver inngang som en kombinasjon av lite antall noder, og krever det å oppdage interessant struktur i dataene. Denne metoden fungerer selv om kodestørrelsen er stor, siden bare en liten delmengde av nodene vil være aktiv når som helst.

det er ganske enkelt å gjøre Dette I Keras med bare en parameter. Som en påminnelse opprettet vi tidligere kodelaget som følger:

code = Dense(code_size, activation='relu')(input_img)

vi legger nå til en annen parameter kalt activity_regularizer ved å angi regulariseringsstyrken. Dette er vanligvis en verdi i området . Her valgte vi 10e-6.

code = Dense(code_size, activation='relu', activity_regularizer=l1(10e-6))(input_img)

det endelige tapet av den sparsomme modellen er 0,01 høyere enn standardmodellen, på grunn av den ekstra reguleringsperioden.

la oss demonstrere kodingene generert av den regulariserte modellen er faktisk sparsomme. Hvis vi ser på histogrammet av kodeverdier for bildene i testsettet, er fordelingen som følger:

gjennomsnittet for standardmodellen er 6,6, men for den regulariserte modellen er det 0,8, en ganske stor reduksjon. Vi kan se at en stor del av kodeverdier i den regulariserte modellen faktisk er 0, noe som vi ønsket. Variansen til den regulariserte modellen er også ganske lav.

Use Cases

nå kan vi stille følgende spørsmål. Hvor gode er autoencoders ved å komprimere inngangen? Og er de en vanlig dyp læringsteknikk?

Dessverre er autoencoders Ikke mye brukt i virkelige applikasjoner. Som komprimeringsmetode utfører de ikke bedre enn sine alternativer, for eksempel jpeg gjør fotokomprimering bedre enn en autoencoder. Og det faktum at autoencoders er dataspesifikke gjør dem upraktiske som en generell teknikk. De har 3 vanlige brukstilfeller skjønt:

  • Data denoising: vi har sett et eksempel på dette på bilder.
  • Dimensjonsreduksjon: det er utfordrende å visualisere høydimensjonale data. t-SNE er den mest brukte metoden, men sliter med stort antall dimensjoner (vanligvis over 32). Så autoencoders brukes som et preprosesseringstrinn for å redusere dimensjonaliteten, og denne komprimerte representasjonen brukes av t-SNE for å visualisere dataene I 2D-rom. For gode artikler om t-SNE se her og her.
  • Variational Autoencoders (VAE): Dette er et mer moderne og komplekst brukstilfelle av autoencoders, og vi vil dekke dem i en annen artikkel. MEN SOM en rask oppsummering lærer VAE parametrene for sannsynlighetsfordelingen som modellerer inngangsdataene, i stedet for å lære en vilkårlig funksjon når det gjelder vanilla autoencoders. Ved sampling poeng fra denne fordelingen kan VI også bruke VAE som en generativ modell. Her er en god referanse.

Konklusjon

Autoencoders er en veldig nyttig dimensjonsreduksjonsteknikk. De er svært populære som undervisningsmateriale i innledende dype læringskurs, mest sannsynlig på grunn av deres enkelhet. I denne artikkelen dekket vi dem i detalj, og jeg håper du likte det.

hele koden for denne artikkelen er tilgjengelig her hvis du ønsker å hacke på det selv. Hvis du har noen tilbakemeldinger gjerne nå ut til meg på twitter.

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert.

Previous post New England Diary
Next post En global guide til tipping når du spiser ute