învățarea profundă aplicată-Partea 3: Autoencoders

Bine ați venit la Partea 3 din seria de învățare profundă aplicată. Partea 1 a fost o introducere practică în rețelele neuronale artificiale, acoperind atât teoria, cât și aplicația cu o mulțime de exemple de cod și vizualizare. În partea 2 am aplicat învățarea profundă seturilor de date din lumea reală, acoperind cele 3 probleme întâlnite cel mai frecvent ca studii de caz: clasificare binară, clasificare multiclasă și regresie.

acum vom începe să ne scufundăm în arhitecturi specifice de învățare profundă, începând cu cele mai simple: Autoencodere.

  1. Introducere
  2. Arhitectură
  3. implementare
  4. Denoising Autoencoders
  5. Autoencoders rare
  6. cazuri de Utilizare
  7. concluzie

codul pentru acest articol este disponibil aici ca notebook jupyter, nu ezitați să îl descărcați și să îl încercați singur.

Introducere

Autoencoderele sunt un tip specific de rețele neuronale feedforward în care intrarea este aceeași cu ieșirea. Acestea comprimă intrarea într-un cod de dimensiuni inferioare și apoi reconstruiesc ieșirea din această reprezentare. Codul este un „rezumat” compact sau „compresie” a intrării, numită și reprezentarea spațiului latent.

un autoencoder este format din 3 componente: codificator, cod și decodor. Codificatorul comprimă intrarea și produce codul, decodorul apoi reconstruiește intrarea numai folosind acest cod.

pentru a construi un autoencoder avem nevoie de 3 lucruri: o metodă de codificare, o metodă de decodare și o funcție de pierdere pentru a compara ieșirea cu ținta. Le vom explora în secțiunea următoare.

Autoencoderele sunt în principal un algoritm de reducere a dimensionalității (sau compresie) cu câteva proprietăți importante:

  • date specifice: Autoencoderele pot comprima în mod semnificativ date similare cu cele pe care au fost instruite. Deoarece învață caracteristici specifice pentru datele de antrenament date, acestea sunt diferite de un algoritm standard de compresie a datelor, cum ar fi gzip. Deci, nu ne putem aștepta la un autoencoder instruit pe cifre scrise de mână pentru a comprima fotografii peisaj.
  • pierderi: Ieșirea autoencoderului nu va fi exact aceeași cu intrarea, va fi o reprezentare apropiată, dar degradată. Dacă doriți compresie fără pierderi, acestea nu sunt calea de urmat.
  • nesupravegheat: pentru a instrui un autoencoder nu trebuie să facem nimic fantezist, ci doar să aruncăm datele de intrare brute. Autoencoderele sunt considerate o tehnică de învățare nesupravegheată, deoarece nu au nevoie de etichete explicite pentru a se antrena. Dar, pentru a fi mai precis, sunt auto-supravegheați, deoarece își generează propriile etichete din datele de antrenament.

Arhitectură

să explorăm detaliile codificatorului, codului și decodorului. Atât codificatorul, cât și decodorul sunt rețele neuronale feedforward complet conectate, în esență Ann-urile pe care le-am acoperit în partea 1. Codul este un singur strat al unui ANN cu dimensionalitatea la alegere. Numărul de noduri din stratul de cod (dimensiunea codului) este un hiperparametru pe care l-am setat înainte de a antrena autoencoderul.

aceasta este o vizualizare mai detaliată a unui autoencoder. Mai întâi, intrarea trece prin codificator, care este un ANN complet conectat, pentru a produce codul. Decodorul, care are structura ANN similară, produce apoi ieșirea numai folosind codul. Scopul este de a obține o ieșire identică cu intrarea. Rețineți că arhitectura decodorului este imaginea în oglindă a codificatorului. Aceasta nu este o cerință, dar este de obicei cazul. Singura cerință este dimensionalitatea de intrare și de ieșire trebuie să fie aceeași. Orice în mijloc poate fi jucat cu.

există 4 hiperparametre pe care trebuie să le setăm înainte de a antrena un autoencoder:

  • dimensiunea codului: numărul de noduri din stratul de mijloc. Dimensiunea mai mică are ca rezultat o compresie mai mare.
  • numărul de straturi: autoencoder poate fi la fel de adânc ca ne place. În figura de mai sus avem 2 straturi atât în codificator, cât și în decodificator, fără a lua în considerare intrarea și ieșirea.
  • numărul de noduri pe strat: arhitectura autoencoder la care lucrăm se numește autoencoder stivuit, deoarece straturile sunt stivuite unul după altul. De obicei, autoencoderele stivuite arată ca un „sandwitch”. Numărul de noduri pe strat scade cu fiecare strat ulterior al codificatorului și crește înapoi în decodor. De asemenea, decodorul este simetric cu codificatorul în ceea ce privește structura stratului. După cum sa menționat mai sus, acest lucru nu este necesar și avem un control total asupra acestor parametri.
  • funcția de pierdere: folosim fie eroarea pătrată medie (mse), fie crossentropia binară. Dacă valorile de intrare sunt în interval, atunci folosim de obicei crossentropy, altfel folosim eroarea medie pătrată. Pentru mai multe detalii, consultați acest videoclip.

Autoencoders sunt instruiți în același mod ca și Anss prin backpropagation. Consultați introducerea părții 1 Pentru mai multe detalii despre modul în care sunt instruite rețelele neuronale, se aplică direct autoencoderelor.

implementare

acum să implementăm un autoencoder pentru următoarea arhitectură, 1 strat ascuns în codificator și decodificator.

vom folosi setul de date extrem de popular MNIST ca intrare. Acesta conține imagini alb-negru de cifre scrise de mână.

sunt de dimensiunea 28×28 și le folosim ca un vector de 784 numere între . Verificați notebook-ul jupyter pentru detalii.

vom implementa acum autoencoderul cu Keras. Hiperparametrii sunt: 128 noduri în stratul ascuns, dimensiunea codului este 32, iar crossentropia binară este funcția de pierdere.

acest lucru este foarte similar cu Ann-urile la care am lucrat, dar acum folosim API-ul funcțional Keras. Consultați acest ghid pentru detalii, dar iată o comparație rapidă. Înainte am folosit pentru a adăuga straturi folosind API secvențială, după cum urmează:

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

cu API-ul funcțional facem acest lucru:

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

este mai detaliat, dar un mod mai flexibil de a defini modele complexe. Putem apuca cu ușurință părți ale modelului nostru, de exemplu doar decodorul, și putem lucra cu acesta. Ieșirea metodei Dense este un strat apelabil, folosind API-ul funcțional îi furnizăm intrarea și stocăm ieșirea. Ieșirea unui strat devine intrarea stratului următor. Cu API secvențială metoda add manipulate implicit acest lucru pentru noi.

rețineți că toate straturile utilizează funcția de activare relu, deoarece este standardul cu rețele neuronale profunde. Ultimul strat folosește activarea sigmoid deoarece avem nevoie de ieșiri pentru a fi între . Intrarea este, de asemenea, în același interval.

de asemenea, rețineți apelul pentru a se potrivi funcția, înainte cu Anss am folosit pentru a face:

model.fit(x_train, y_train)

dar acum facem:

model.fit(x_train, x_train)

amintiți-vă că țintele autoencoderului sunt aceleași cu intrarea. De aceea furnizăm datele de antrenament ca țintă.

vizualizare

acum să vizualizăm cât de bine își reconstruiește autoencoderul intrarea.

rulăm autoencoderul pe setul de testare pur și simplu folosind funcția de predicție a Keras. Pentru fiecare imagine din setul de testare, obținem ieșirea autoencoderului. Ne așteptăm ca ieșirea să fie foarte asemănătoare cu intrarea.

ele sunt într-adevăr destul de similare, dar nu Exact la fel. O putem observa mai clar în ultima cifră „4”. Deoarece aceasta a fost o sarcină simplă autoencoder nostru efectuat destul de bine.

sfat

avem control total asupra arhitecturii autoencoderului. Putem face foarte puternic prin creșterea numărului de straturi, noduri pe strat și cel mai important dimensiunea codului. Creșterea acestor hiperparametrii va permite autoencoder pentru a afla codificări mai complexe. Dar ar trebui să fim atenți să nu o facem prea puternică. În caz contrar, autoencoderul va învăța pur și simplu să-și copieze intrările la ieșire, fără a învăța nicio reprezentare semnificativă. Acesta va imita doar funcția de identitate. Autoencoderul va reconstrui perfect datele de antrenament, dar va fi suprasolicitat fără a putea generaliza la noi instanțe, ceea ce nu este ceea ce ne dorim.

acesta este motivul pentru care preferăm o arhitectură „sandwitch” și păstrăm în mod deliberat dimensiunea codului mică. Deoarece stratul de codare are o dimensionalitate mai mică decât datele de intrare, se spune că autoencoderul este incomplet. Nu va putea copia direct intrările sale la ieșire și va fi forțat să învețe caracteristici inteligente. Dacă datele de intrare au un model, de exemplu cifra „1” conține de obicei o linie oarecum dreaptă, iar cifra „0” este circulară, va învăța acest fapt și îl va codifica într-o formă mai compactă. În cazul în care datele de intrare a fost complet aleatoare, fără nici o corelație internă sau dependență, atunci un autoencoder undercomplete nu va fi capabil să-l recupereze perfect. Dar, din fericire, în lumea reală există o mulțime de dependență.

Denoising Autoencoders

păstrarea stratului de cod mic a forțat autoencoderul nostru să învețe o reprezentare inteligentă a datelor. Există un alt mod de a forța autoencoderul să învețe funcții utile, care adaugă zgomot aleatoriu la intrările sale și îl face să recupereze datele originale fără zgomot. În acest fel, autoencoderul nu poate copia pur și simplu intrarea la ieșirea sa, deoarece intrarea conține și zgomot aleatoriu. Îi cerem să scadă zgomotul și să producă datele semnificative subiacente. Aceasta se numește autoencoder denoising.

rândul de sus conține imaginile originale. Le adăugăm zgomot Gaussian aleatoriu, iar datele zgomotoase devin intrarea în autoencoder. Autoencoderul nu vede deloc imaginea originală. Dar atunci ne așteptăm ca autoencoderul să regenereze imaginea originală fără zgomot.

există o singură mică diferență între implementarea denoising autoencoder și cea obișnuită. Arhitectura nu se schimbă deloc, ci doar funcția fit. Am instruit autoencoderul obișnuit după cum urmează:

autoencoder.fit(x_train, x_train)

Denoising autoencoder este instruit ca:

autoencoder.fit(x_train_noisy, x_train)

simplu ca asta, orice altceva este exact la fel. Intrarea la autoencoder este imaginea zgomotoasă, iar ținta așteptată este cea originală fără zgomot.

vizualizare

acum să vizualizăm dacă suntem capabili să recuperăm imaginile fără zgomot.

arată destul de bine. Rândul de jos este ieșirea autoencoder. Putem face mai bine prin utilizarea arhitecturii autoencoder mai complexe, cum ar fi autoencodere convoluționale. Vom acoperi convoluțiile în următorul articol.

Autoencoders rare

am introdus două moduri de a forța autoencoder pentru a afla caracteristici utile: păstrarea dimensiunea codului mici și denoising autoencoders. A treia metodă este utilizarea regularizării. Putem regulariza autoencoderul folosind o constrângere de sparsitate astfel încât doar o fracțiune din noduri să aibă valori diferite de zero, numite noduri active.

în special, adăugăm un termen de penalizare funcției de pierdere astfel încât doar o fracțiune din noduri să devină active. Acest lucru forțează autoencoderul să reprezinte fiecare intrare ca o combinație de număr mic de noduri și îi cere să descopere o structură interesantă în date. Această metodă funcționează chiar dacă dimensiunea codului este mare, deoarece doar un mic subset al nodurilor va fi activ în orice moment.

este destul de ușor să faceți acest lucru în Keras cu un singur parametru. Ca o reamintire, anterior am creat stratul de cod după cum urmează:

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

acum adăugăm un alt parametru numit activity_regularizer specificând puterea de regularizare. Aceasta este de obicei o valoare în intervalul . Aici am ales 10e-6.

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

pierderea finală a modelului rar este cu 0,01 mai mare decât cea standard, datorită termenului de regularizare adăugat.

să demonstrăm codificările generate de modelul regularizat sunt într-adevăr rare. Dacă ne uităm la histograma valorilor codului pentru imaginile din setul de testare, distribuția este după cum urmează:

media pentru modelul standard este 6.6, dar pentru modelul regularizat este 0.8, o reducere destul de mare. Putem vedea că o bucată mare de valori de cod în modelul regularizat sunt într-adevăr 0, ceea ce ne-am dorit. Varianța modelului regularizat este, de asemenea, destul de scăzută.

cazuri de Utilizare

acum am putea pune următoarele întrebări. Cât de bune sunt autoencoderele la comprimarea intrării? Și sunt o tehnică de învățare profundă folosită în mod obișnuit?

din păcate, autoencodere nu sunt utilizate pe scară largă în aplicații din lumea reală. Ca metodă de compresie, acestea nu funcționează mai bine decât alternativele sale, de exemplu jpeg face compresia foto mai bună decât un autoencoder. Iar faptul că autoencoderele sunt specifice datelor le face impracticabile ca tehnică generală. Ei au 3 cazuri comune de utilizare, deși:

  • date denoising: am văzut un exemplu în acest sens pe imagini.
  • reducerea dimensionalității: vizualizarea datelor de înaltă dimensiune este o provocare. t-end este metoda cea mai frecvent utilizată, dar se luptă cu un număr mare de dimensiuni (de obicei peste 32). Deci, autoencoderele sunt utilizate ca pas de preprocesare pentru a reduce dimensionalitatea, iar această reprezentare comprimată este utilizată de t-end pentru a vizualiza datele în spațiul 2D. Pentru articole de mare pe t-end se referă aici și aici.
  • Autoencodere variaționale (VAE): acesta este un caz de utilizare mai modern și mai complex al autoencoderelor și le vom acoperi într-un alt articol. Dar, ca un rezumat rapid, VAE învață parametrii distribuției probabilității care modelează datele de intrare, în loc să învețe o funcție arbitrară în cazul autoencoderelor vanilla. Prin punctele de eșantionare din această distribuție putem folosi și VAE ca model generativ. Iată o referință bună.

concluzie

Autoencoderele sunt o tehnică foarte utilă de reducere a dimensionalității. Sunt foarte populare ca material didactic în cursurile introductive de învățare profundă, cel mai probabil datorită simplității lor. În acest articol le-am acoperit în detaliu și sper că v-a plăcut.

întregul cod pentru acest articol este disponibil aici dacă doriți să vă hackați singur. Dacă aveți orice feedback-ul nu ezitați să ajungă la mine pe twitter.

Lasă un răspuns

Adresa ta de email nu va fi publicată.

Previous post New England Diary
Next post Un ghid global pentru sfaturi atunci când luați masa