O rețetă pentru formarea rețelelor neuronale
Cu câteva săptămâni în urmă, am postat un tweet despre „cele mai frecvente greșeli ale rețelei neuronale”, enumerând câteva probleme obișnuite legate de antrenarea plaselor neuronale. Tweet-ul a obținut destul de mult mai mult angajament decât am anticipat (inclusiv un webinar:)). În mod clar, o mulțime de oameni au întâmpinat personal diferența mare dintre „iată cum funcționează un strat convoluțional” și „convnetul nostru obține rezultate de ultimă generație”.

Așa că m-am gândit că ar putea fi amuzant să-mi scot blogul prăfuit pentru a-mi extinde tweet-ul la forma lungă pe care acest subiect o merită. Cu toate acestea, în loc să intru într-o enumerare a erorilor mai frecvente sau să le scot în evidență, am vrut să sap un pic mai adânc și să vorbesc despre cum se poate evita să comită aceste erori cu totul (sau să le remedieze foarte rapid). Trucul pentru a face acest lucru este să urmezi un anumit proces, care din câte îmi dau seama nu este foarte des documentat. Să începem cu două observații importante care îl motivează.
1) Antrenamentul cu rețele neuronale este o abstracție cu scurgeri
Se presupune că este ușor să începeți cu antrenarea plaselor neuronale. Numeroase biblioteci și cadre se mândresc cu afișarea de fragmente minune de 30 de linii care vă rezolvă problemele de date, dând impresia (falsă) că aceste lucruri sunt plug and play. Este obișnuit să vezi lucruri precum:
Aceste biblioteci și exemple activează partea creierului nostru care este familiarizată cu software-ul standard - un loc în care API-urile și abstractizările curate sunt adesea realizabile. Solicită biblioteca pentru a demonstra:
Asta e tare! Un dezvoltator curajos a preluat sarcina de a înțelege șirurile de întrebări, adresele URL, solicitările GET/POST, conexiunile HTTP și așa mai departe și a ascuns în mare măsură complexitatea din spatele câtorva linii de cod. La asta ne familiarizăm și ne așteptăm. Din păcate, rețelele neuronale nu sunt așa ceva. Acestea nu sunt tehnologie „off-the-raft” în secunda în care vă abateți ușor de la instruirea unui clasificator ImageNet. Am încercat să subliniez acest lucru în postarea mea „Da, ar trebui să înțelegeți backprop”, alegând backpropagation și numind-o „abstractizare scurgeri”, dar situația este, din păcate, mult mai gravă. Backprop + SGD nu face ca rețeaua să funcționeze în mod magic. Norma de lot nu o face să transforme magic mai rapid. RNN-urile nu vă permit magic să „conectați” text. Și doar pentru că îți poți formula problema ca RL nu înseamnă că ar trebui. Dacă insistați să utilizați tehnologia fără a înțelege cum funcționează, este posibil să eșuați. Ceea ce mă aduce la ...
2) Antrenamentul cu rețele neuronale eșuează în tăcere
Când spargeți sau configurați greșit codul, veți obține adesea un fel de excepție. Ați conectat un număr întreg în care ceva se aștepta la un șir. Funcția aștepta doar 3 argumente. Acest import a eșuat. Cheia respectivă nu există. Numărul de elemente din cele două liste nu este egal. În plus, este adesea posibil să creați teste unitare pentru o anumită funcționalitate.
Acesta este doar un început când vine vorba de antrenarea plaselor neuronale. Totul ar putea fi corect din punct de vedere sintactic, dar totul nu este aranjat corect și este foarte greu de spus. „Suprafața posibilă de eroare” este mare, logică (spre deosebire de sintactică) și foarte dificilă pentru testarea unității. De exemplu, poate ați uitat să vă răsturnați etichetele când ați răsturnat imaginea în stânga-dreapta în timpul măririi datelor. Rețeaua dvs. poate funcționa încă (șocant) destul de bine, deoarece rețeaua dvs. poate învăța intern să detecteze imaginile răsturnate și apoi își stabilește predicțiile. Sau poate că modelul dvs. autoregresiv ia din greșeală ceea ce încearcă să prezică ca intrare din cauza unei erori off-by-one. Sau ați încercat să tăiați gradienții, dar în schimb ați tăiat pierderea, făcând ca exemplele anterioare să fie ignorate în timpul antrenamentului. Sau v-ați inițializat greutățile dintr-un punct de control predeterminat, dar nu ați folosit media inițială. Sau pur și simplu ați înșelat setările pentru punctele forte de regularizare, rata de învățare, rata de descompunere a acesteia, dimensiunea modelului etc. Prin urmare, rețeaua dvs. neuronală mal configurată va arunca excepții numai dacă aveți noroc; De cele mai multe ori se va antrena, dar va funcționa în tăcere puțin mai rău.
Ca urmare, (și acest lucru este dificil de subliniat) o abordare „rapidă și furioasă” a instruirii rețelelor neuronale nu funcționează și duce doar la suferință. Acum, suferința este o parte perfect naturală a obținerii unei rețele neuronale să funcționeze bine, dar poate fi atenuată prin a fi minuțioasă, defensivă, paranoică și obsedată de vizualizarea practic a oricărui lucru posibil. Calitățile care din experiența mea se corelează cel mai puternic cu succesul în învățarea profundă sunt răbdarea și atenția la detalii.
Reteta
În lumina celor două fapte de mai sus, am dezvoltat un proces specific pentru mine, pe care îl urmez atunci când aplic o rețea neuronală la o nouă problemă, pe care voi încerca să o descriu. Veți vedea că ia cele două principii de mai sus foarte în serios. În special, se dezvoltă de la simplu la complex și la fiecare pas al modului facem ipoteze concrete despre ceea ce se va întâmpla și apoi fie le validăm cu un experiment, fie investigăm până când găsim o problemă. Ceea ce încercăm să prevenim foarte greu este introducerea multor complexități „neconfirmate” simultan, care este obligată să introducă erori/configurații greșite care vor dura pentru totdeauna să fie găsite (dacă vreodată). Dacă scrierea codului de rețea neuronală a fost ca un antrenament, ar fi bine să folosiți o rată de învățare foarte mică și să ghiciți și apoi să evaluați setul complet de testare după fiecare iterație.