Sunteți pe pagina 1din 11

Tema: Învățarea automată, o perspectivă

mai tehnică.

Obiectivele lecției:
1. Vei afla cum poți să evaluezi cu un nivel înalt de fidelitate algoritmii de
învățare automată
2. O să afli cum poți determina când un algoritm de învățare automată, și în
special aprofundată încetează să învețe și începe să memoreze datele
3. O să obții o înțelegere generală a tehnicii de propagare inversă ce permite
învățarea rețelelor neuronale

Deja am ajuns la a 5-a lecție. Până acum am discutat despre concepte


precum rețele neuronale artificiale, convoluții, rețele neuronale recurente, procesare
de text și imagini, reprezentări de date și probleme curente. Dar toate aceste teme
sunt doar vârful aisbergului, iar subdomeniul învățării aprofundate, și domeniul
inteligenței artificiale în general este unul foarte vast, profund și pe alocuri
complicat.
Chiar și din punct de vedere aplicativ, deși este trivial de a face un mic demo
al unei aplicații ce utilizează algoritmi de inteligență artificială, este cu mult mai
complicat de a transpune rezultatele obținute în prototip în lumea reală. Aceasta
poate fi din numeroase motive. Începând cu discrepanțe între datele cu ajutorul
cărora a fost creata un algoritm până la un proces de evaluare rău formulat.

Evaluarea algoritmilor

Așa dar, hai să discutăm mai întâi despre evaluarea algoritmilor. E de la sine
înțeles că pentru a evalua corect un algoritm trebuie ca datele utilizate în acest
proces să nu fie aceleași date care au fost utilizate la învățare. O practică des
utilizată este de a împărți datele existente într-un set de învățare/antrenare și unul
de testare. În linii mari, același principiu este utilizat și la evaluarea oamenilor. Ai de
făcut teme pe acasă și vezi exemple de exerciții la școală, dar în cadrul testărilor ai
de rezolvat exerciții similare cu cele pe care le-ai mai văzut, dar nu exact aceleași.
Majoritatea cercetătorilor dar și dezvoltatorilor în domeniul învățării automate fac o
împărțire 70% pentru setul de date de antrenament și 30% pentru cel de testare. În
dependență de volumul de date pus la dispoziție, aceste cifre pot fi diferite. Dacă ai
la dispoziție milioane de valori de intrare, poți utiliza până la 90% pentru setul de
antrenament. O problemă des întâlnită este lipsa, sau reprezentarea slabă a unor
clase mai rare în setul de antrenare. Din acest motiv rezultatele evaluării pot să fie
derutante. Această problemă poate fi rezolvată cu un volum mai mare de date. Dar
ce să faci dacă ai puține date, spre exemplu până la câteva mii de exemple?
Răspunsul ar fi același, de a testa pe un volum mai mare de date. Nu, nu te
iau peste picior, vorbesc serios. Pentru a testa pe un volum mai mare de date,
având puține date, avem nevoie de un truc numit “validarea încrucișată” sau
cross-validation. Ce înseamnă asta? Să ne imaginăm că ai ales o partiție de 80%
pentru setul de antrenament și 20% pentru testare/validare. Rulezi o operație de
învățare și una de evaluare, pui de o parte rezultatele obținute. Iar acum trucul.
Selectezi o altă partiție, la fel de 20%, care nu conține nici un element din partiția de
testare precedentă și cu restul 80% din date (re)înveți același algoritm de la 0.
Mai repeți de 3 ori. E voila, ca prin magie, ai reușit să testezi algoritmul tău, într-un
mod fidel, pe întreg volumul de date disponibil. Drăguț, nu?

Validarea încrucișată presupune rularea ciclului de învățare/evaluare de mai multe


ori pe diferite combinații de seturi de date. Validarea încrucișată este în special
utilizată în scenarii de selecție a unui algoritm dintr-o mulțime, din motiv că permite
o evaluare justă a acestora . Sursa: https://scikit-
learn.org/stable/modules/cross_validation.html

Există și alte trucuri, pentru asemenea cazuri speciale precum clase cu o


proporție variabilă, sau pentru date care au o dependență cauzală, precum texte
sau măsurări periodice. Dar acestea deja o să le descoperi singur, dacă îți va fi
suficient de interesant.
Pe cât de magică validarea încrucișată nu ar părea, acesta are și neajunsuri.
Spre exemplu, este necesar de a antrena un algoritm de numeroase ori de la 0
pentru a-l putea evalua. În cazul în care acest algoritm este o rețea neuronală ce
necesită ore sau poate chiar zile pentru a fi învățată, nu pare atât de tentantă
această operație. Din acest motiv pentru rețelele neuronale mari a fost propus o altă
strategie de evaluare.
În primul rând trebuie de menționat că rețelele neuronale iterează de mai
multe ori prin setul de date disponibil. O singură trecere nu este suficientă pentru a
învăța. Vei afla mai târziu în cadrul lecției de ce. În orice caz, fiecare parcurgere este
numită o epocă. Așa dar, rețelele neuronale pot fi evaluate în modul următor. La
finele fiecărei epoci, rețeaua neuronală este testată utilizând setul de date de
evaluare/testare. În modul dat este posibil nu doar de a evalua algoritmul, dar și
spre exemplu de a detecta timpuriu dacă acesta are probleme în cadrul procesului
de învățare.
Acum hai să presupunem că ai un algoritm de detectare a fețelor în poze, și
ca să te asiguri că totul este în regulă cu acesta utilizezi schema de validare
propusă mai sus. La un moment dat observi ceva straniu. După o perioadă de
scădere rapidă a erorilor, și ulterior atingerea unui platou, erorile de validare încep
să crească. Ce se întâmplă?

Algoritmii de învățare automată deseori pot fi observați când aceștia trec din
regimul de învățare/generalizare în regimul de memorare. Analizând graficile erorilor
pe setul de date de evaluare și de antrenare putem detecta acest moment și spre
exemplu opri procesul de învățare. Sursa:
https://rmartinshort.jimdofree.com/2019/02/17/overfitting-bias-variance-and-
leaning-curves/

Ei bine, ești martor cum un algoritm încetează să învețe/generalizeze și


începe să memoreze datele. Memorând datele de test, acesta nu are suficiente
conexiuni adaptate pentru a generaliza, efectiv pentru a da niște predicții utile.
Acest proces se numește supra încadrare (eng. overfitting). Supra-încadrearea
este o problemă foarte răspândită în special la rețelele neuronale, din motiv că
acestea au o capacitate foarte mare de învățare, și în dependență de modul cum
acestea sunt antrenate, pot “decide” că pentru a excela este suficient să memoreze
datele.
Și desigur, acolo unde există supra încadrare, există și termenul de sub
încadrare (eng. underfitting). Sub încadrarea este mai simplă, aceasta are loc
atunci când algoritmul nu este în general capabil să învețe relația dintre valorile de
intrare și rezultatele corespunzătoare. Deseori aceasta se întâmplă pentru că
algoritmul nu este capabil să reprezinte funcții complexe. Spre exemplu încearcă să
înveți un algoritm ce poate separa liniar datele să detecteze fețe direct din pixeli.
Acesta o va da în bară rău de tot, manifestând efectul de sub încadrare.

Imaginea de mai sus reprezintă regimele de sub încadrare, generalizare și supra


încadrare a unui algoritm de învățare automată. Sursa: https://scikit-
learn.org/stable/auto_examples/model_selection/plot_underfitting_overfitting.html

Un truc eficient de a combate supra încadrarea în timpul învățării unui


algoritm de învățare aprofundată este de a opri procesul în momentul în care acesta
începe să mărească eroarea de validare în timp ce eroarea de învățare în continuare
scade. Pentru aceasta este nevoie să monitorizăm în continuu atât rezultatele
validării, cât și erorile pe setul de date de antrenare propriu-zis. De asemenea
pentru a ne asigura că totul este în regulă este nevoie să salvăm parametrii
algoritmului nostru periodic, ca să avem acces la algoritmul ce generalizează cel
mai bine.

Învățarea rețelelor neuronale

Deci cum învăță totuși o rețea neuronală? Din greșeli. Mai exact, avem
nevoie de o funcție ce ar cuantifica cât de mult a greșit algoritmul în predicția lui.
Cea mai simplă variantă pentru o astfel de funcție ar fi spre exemplu scăderea.
Imaginează-ți, avem o rețea neuronală care încearcă să prezică dacă într-o
imagine avem o pisică sau un câine. O să codăm clasa “câine” drept cifra 1 și clasa
“pisică” drept cifra 0. De ce? Pentru că mulți algoritmi de învățare automată, rețelele
neuronale inclusiv, pot lucra doar cu valori numerice. Așa dar, trecând prin tot setul
nostru de date obținem o secvență de predicții gen 0.9, 0.1, 0.15, 0.2, 0.87, 0.99,
0.98, 0.19, 0.84, … Observi că niciuna din valori nu este fix 0 sau 1, aceasta se
întâmplă din 2 motive, rețelele neuronale de obicei nu sunt niciodată 100 la 100
sigure în predicțiile care le fac, iar în al doilea rând, predicțiile neprocesate sunt de
fapt niște probabilități. Deci clasa prezisă ar fi aceste probabilități rotunjite. Pe de
altă parte, avem clasele adevărate: 1, 0, 0, 1, 1, 1, 1, 0, 0, … Cum vezi, avem câteva
predicții greșite, dar avem și ceva erori. Dacă am fi să utilizăm scăderea direct, am
obține următoarea secvență de erori:
(1-0.9) = 0.1,
(0-0.1) = -0.1,
-0.15, 0.8, 0.13, 0.01, 0.02, -0.19, -0.84, … Avem nevoie să sumarizăm
aceste măsurări, spre exemplu calculând eroarea medie.
[0.1 + (-0.1) + (-0.15) + 0.8 + 0.13 + 0.01 + 0.02 + (-0.19) + (-0.84) + …] / N
unde N este numărul total de valori în setul de date de învățare. O problemă cu
sumarea directă a erorilor este faptul că avem erori pozitive și negative, care se
atenuează unele pe celelalte. Nu dorim asta. La fel ar fi drăguț dacă am penaliza
prezicerile greșite mai mult decât nesiguranța în răspunsul care ni-l dă algoritmul.
Pentru aceasta am putea să calculăm media erorilor la pătrat. Apropo, media
erorilor la pătrat este foarte des utilizată în asemenea scenarii.
Acum că avem posibilitatea să exprimăm printr-un număr cât de bună sau
rea este o rețea neuronală, dorim să optimizăm această rețea, adică să o facem
mai bună. Pentru aceasta o să avem nevoie de un domeniu foarte interesant și
practic al matematicii care se numește optimizare. Domeniul optimizării este
preocupat cu identificarea punctelor extreme ale funcțiilor. De ce ar fi important
aceasta? Ei bine, spre exemplu putem exprima printr-o funcție cantitatea de energie
electrică pe care o poate genera o stație electrică în dependență de parametrii
generatorului electric. Sau configurația motorului unei rachete cosmice pentru a
atinge viteza maximă cu cât mai puțin combustibil. Sau valoarea tuturor parametrilor
unei rețele neuronale pentru ca aceasta să aibă o performanță cât mai înaltă.
Rețelele neuronale pot fi percepute drept niște funcții foarte complexe, cu
sute de mii, sau chiar sute de milioane de parametri. Cu alte cuvinte, o rețea
neuronală în final este fratele mai mare care are doctorat, este campion mondial la
nu știu ce sport și câștigă milioane a unei funcții de genul mx+n unde m și n sunt
niște parametri pe care tu trebuie să-i identifici astfel încât funcția dată să modeleze
datele tale cât mai bine.
Pentru a optimiza rețelele neuronale este utilizat pe larg un algoritm numit
Gradient Descent, sau algoritmul coborârii gradientului stohastic, și variații ale
acestuia. Sună strașnic, dar nu-ți fă griji, conceptul e simplu. Așa dar, în primul rând
ce este un gradient. Gradientul este un vector ce conține derivata unei funcții cu mai
multe variabile cu respect față de toate variabilele. Spre exemplu, având funcția
f(x, y) = 2x + y, gradientul acestei funcții o să fie (2 + y, 2x+1). Pentru a
înțelege de ce gradientul este important, este important să înțelegi o proprietate
extrem de importantă a derivatei unei funcții în general. Derivata reprezintă cât de
mult se schimbă o funcție. Așa dar, gradientul, fiind format din mai multe derivate,
una per direcție de schimbare, o să ne indice direcția unde schimbarea este cea mai
drastică într-o funcție.

Astfel, idea coborârii gradientului stohastic este de a urma această direcție


cu speranța că astfel va fi posibil de identificat minimul funcției, sau în cazul nostru
eroarea minimă a rețelei noastre neuronale. Eroare este estimată cu ajutorul unei
funcții, de exemplu funcția erorii pătrate medii.
Acestă imagine arată traiectoria algoritmului coborârii gradientului stohastic pe
suprafața unei funcții de 2 variabile. Graficul acestei funcții poate fi interpretat ca o
hartă geografică, unde cu cât mai închisă este culoarea, cu atât mai jos se află
punctul. Sursa: https://distill.pub/2017/momentum/

Cuvântul stohastic înseamnă că estimările noastre nu sunt făcute asupra


întregului set de date, ci doar a unui eșantion mic, de exemplu format din 32 sau 64
de elemente/valori de intrare. Aceasta minimizează costul computațional al
operației. Algoritmul coborârii gradientului stohastic este reprezentat prin formula:

Unde a este parametrul pe care încercăm să-l modificăm în urma procesului de


optimizare, F este funcția obiectiv, adica cea care ne spune ce erori avem pentru
valoarea curentă a parametrului nostru, litera delta inversată, numită în literatura de
profil nabla este operația de calcul a gradientului funcției de obiectiv și în final avem
litera gamma mică, aceasta este rata de învățare, probabil cel mai important
hiper-parametru al unei rețele neuronale. Rata de învățare este extrem de
importantă, dacă o setăm greșit, rețeaua noastră poate fie să învețe extrem de greu,
fie să nu învețe în general. Acest parametru, sau mai exact hiper-parametru, pentru
că este setat manual și nu este parte a funcției rețelei neuronale, controlează ce
efect are fiecare estimare a direcției ce variază cel mai mult la modificarea
parametrului. Există metode ce pot estima acest pas automat pe parcursul învățării
unei rețele neuronale, dar aceste metode sunt complicate, așa că nu o să le trecem.
Pentru coborârea gradientului stohastic simplă câteva valori bune pentru rata de
învățare sunt 0.05, 0.03, 0.01, dar în principiu sunt nevoie numeroase experimente
pentru a determina această valoare.
În dependență de rata de învățare putem aveam fie convergență înceată, adică
procesul de învățare poate dura mai mult decât ne-am dori, în situația în care rata
de învățare este prea mică (stânga); sau dacă setăm rata de învățare cu o valoare
bună, procesul de învățare va dura puțin, pentru că algoritmul poate identifica o
configurație de parametri buni foarte repede (centru). Dacă rata de învățare este
prea mare, putem avea chiar și situații în care învățarea devine imposibilă (dreapta).

În așa caz, învățarea automată nu este decât o aplicare a optimizării


matematice? Din păcate nu. Din păcate pentru că ar fi fost cu mult mai simplu în
felul dat. Nu pentru că deși procedura de optimizare este prezentă în cadrul
procesului de învățare, scopul acestei proceduri este de fapt de a obține o
performanță înaltă pe alte date decât cele cu care a fost efectuată operația de
optimizare. Adică, optimizarea în algoritmii de învățare supervizată este un rol
proxim la scopul de bază, de a învăța funcția generatoare a datelor care ne
interesează. În calitate de metaforă asta ar însemna să înveți foarte bine matematica
la școală cu speranța că asta îți va fi de folos în cariera de fizician pe care ți-o
dorești. De ce să nu “învățăm direct fizica” în cazul dat? Fiindcă “fizica”, sau funcția
ce cu adevărat descrie datele noastre, nu poate fi percepută complet și corect.

O clipă, am discutat despre funcții care estimează cât de rea sau bună este o rețea
neuronală, și despre faptul că rețelele neuronale sunt de fapt niște funcții mari și
complicate și dorim să le optimizăm pentru a avea, sperăm noi, un predictor robust
când va fi utilizat cu date reale. Dar am menționat că și faptul că avem nevoie de
gradienți, adică derivate, pentru a învăța. Deci cum se leagă totul împreună?

Fii atent, acuș o să fie rău. Ești gata? Ei bine, calculăm gradientul, deci derivatele,
pentru funcția ce ne estimează erorile. De exemplu funcția erorilor pătrate medii. Nu
pare complicat, dacă știi regulile de bază a derivării, nu? DAR, există un dar mare,
acea funcție implicit conține rețeaua noastră neuronală, cu alte cuvinte o funcție cu
sute de mii sau chiar milioane de parametri. Adică învățarea în cazul dat înseamna
estimarea valorilor de actualizare pentru toți parametrii noștri. aaaaaaaaa!!!!! Mai
mult de atât, rețeaua neuronală fiind o funcție foarte complexă, implică și niște
derivate complexe. Deci e rău de tot. În nici un caz nu vom realiza estimările date,
nici pentru o problemă mică de tot, dar intuiția acestui proces o vom acoperi.

N
1
∑ ( y i−nn(x i , ω t ))❑2
ω t+ 1=ωt + γ ∇
N i
Unde ωeste mulțimea tuturor parametrilor unei rețele neuronale, iar nn este rețeaua

neruonală. Simbolul ∑ ❑ (sigma) semnifică sumarea. Cu alte cuvinte

N

∑ ( y i−nn (xi , ωt ))❑2semnifică pentru toate perechile ( y i, x i) calculează suma erorilor


i

pătrate a predicțiilor rețelei neuronale nn.


(Stânga) Liniile roșii semnifică conexiunile/parametrii cu valori negative, iar valorile
albastre cele cu semnul pozitiv. Putem vedea cum semnalul traversează de la sursă
la predicție. (Dreapta) Observăm cum semnalul este propagat în direcția inversă,
astfel realizând adaptarea conexiunilor, respectiv învățarea. Sursa: 3Blue1Brown -
What is backpropagation really doing?

Cum am mai spus, o rețea neuronală este de fapt o funcție imensă, compusă
din numeroase operații de înmulțire și adunare a matricilor, plus aplicarea unor
funcții non-liniare. Asta sugerează că pentru a deriva o astfel de funcție imensă o să
fie nevoie de regula derivării a unei funcții compuse, dar cu mici adaptări pentru a
obține o eficiență computațională sporită. În general derivata unei funcții compuse
de genul f(g(x)) o să fie egală cu f’(g(x))g’(x) . Sau sub altă formă:
dz dz d ω 1 d ωn
= ⋅ ⋅...⋅
dx d ω 1 d ω 2 dx
Unde ω sunt parametrii intermediari, spre exemplu conexiunile într-o rețea
neuronală.

Concluzie
Acum defininitiv putem spune că posezi o intuiție bună referitor la cum
funcționează algoritmii de învățare aprofundată și chiar cunoști anumite trucuri cum
să înveți asemenea algoritmi pentru a avea o performanță bună în situații și pe date
reale. Mai departe în cadrul cursului o să faci cunoștință și cu alți algoritmi mai
simpli, dar care deseori pot rezolva numeroase probleme reale și sunt cu mult mai
rapizi și interpretabili față de rețelele neuronale. De asemenea vei învăță încă multe
alte trucuri necesare în a excela la rezolvarea problemelor utilizând inteligența
artificială.

Exerciții

1. Descrie cum lucrează un algoritm ce utilizează abordarea conexionistă?


Argumentează prin ce acest tip de algoritmi este superior învățării automate
clasice?
2. Descrie, pas cu pas, cum un algoritm ar învăța să decidă dacă o secvență de
text este o poezie sau o nuvelă?
3. Rulează exemplul propus. EXAMPLE1 - Teacheble Machines + poate inca un exemplu
din resursa

Test

1. Care este diferența dintre un sistem cu IA simbolic și unul ce utilizează


abordarea statistică?
2. Cum lucrează un algoritm de învățare supervizată?

S-ar putea să vă placă și