Za firbce: Kako se Machine Learning model dejansko uči iz ene napake?
V prejšnjem zapisu smo Machine Learning zelo poenostavili na: Podatki → Napoved → Napaka → Popravek → Ponovi Ampak kaj pravzaprav pomeni »popravek«?
Kaj se v modelu spremeni, ko ugotovi, da je napovedal napačen rezultat?
Poglejmo na zelo preprostem primeru.
Začnimo z modelom za ceno stanovanja
Recimo, da želimo iz velikosti stanovanja napovedati njegovo ceno.
Imamo stanovanje:
80 m²
Prava prodajna cena je:
300.000 €
Naš model pa trenutno napove:
260.000 €
Model je torej zgrešil za:
40.000 €
Kaj naredi zdaj?
Ne reče samo:
Ups, narobe.
Nekje mora spremeniti številke, s katerimi računa.
Te številke imenujemo parametri modela.
Kaj so parametri?
Pri zelo preprosti linearni regresiji lahko model izgleda približno tako:
Cena = velikost × parameter + začetna vrednost
Na primer:
Cena = velikost × 3.000 € + 20.000 €
Za stanovanje veliko 80 m² bi model izračunal:
80 × 3.000 + 20.000 = 260.000 €
To je njegova napoved.
Prava cena pa je 300.000 €.
Torej očitno trenutni vrednosti:
- 3.000
- 20.000
nista najboljši.
In ravno ti dve številki lahko model med učenjem spreminja.
Model mora ugotoviti, katero številko premakniti
Tu postane stvar zanimiva.
Model ima več možnosti.
Lahko poveča parameter:
3.000 → 3.100
Lahko spremeni začetno vrednost:
20.000 → 25.000
Lahko spremeni oboje.
Toda kako ve, katera sprememba bo pomagala?
Tu pridemo do gradienta.
Gradient je namig za smer
Beseda gradient zveni precej matematično.
Osnovna ideja pa ni tako grozna.
Gradient modelu pove:
Če malo spremenim ta parameter, kaj se bo zgodilo z napako?
Bo napaka:
- večja,
- manjša,
- ali skoraj enaka?
Če povečanje nekega parametra zmanjša napako, ga je smiselno premakniti v to smer.
Če napako poveča, gremo v drugo smer.
Gradient je torej nekakšen matematični kažipot.
Predstavljaj si hrib
Pogosta primerjava za gradient descent je hribovita pokrajina.
Predstavljaj si, da stojiš nekje na pobočju.
Tvoj cilj je priti v najnižjo točko doline.
Problem je, da ne vidiš cele pokrajine.
Lahko pa pogledaš tla neposredno okoli sebe in ugotoviš:
V katero smer gre najbolj navzdol?
Narediš majhen korak.
Potem ponovno pogledaš.
Narediš še en korak.
In še enega.
To približno počne gradient descent.
Samo da namesto nadmorske višine zmanjšuje napako modela.
Loss function je pokrajina
Da model sploh ve, kaj pomeni »bolje«, potrebujemo neko številko, ki predstavlja napako.
To naredi loss function.
Recimo:
Napoved:
260.000 €
Prava cena:
300.000 €
Razlika:
40.000 €
Pri regresiji se pogosto uporablja nekaj podobnega kvadratu napake:
napaka²
Zakaj kvadrat?
Med drugim zato, ker:
- negativne in pozitivne napake ne izničijo druga druge,
- večje napake postanejo precej bolj pomembne,
- matematika za optimizacijo je priročna.
Če model zgreši za 10, je:
10² = 100
Če zgreši za 20:
20² = 400
Dvakrat večja napaka je tako lahko precej bolj kaznovana.
Zdaj lahko model naredi popravek
Recimo, da model ugotovi:
Če parameter 3.000 malo povečam, bo moja napaka manjša.
Gradient descent nato naredi majhen popravek.
Na primer:
3.000 → 3.050
Zdaj ponovno izračuna napoved:
80 × 3.050 + 20.000 = 264.000 €
Še vedno ni 300.000 €.
Ampak napaka je manjša.
Model je šel v pravo smer.
Nato naredi nov popravek.
In novega.
In novega.
Zakaj ne naredi kar ogromnega popravka?
Dobro vprašanje.
Če model ugotovi, da mora parameter povečati, bi lahko rekel:
Super, povečajmo ga za 10.000.
Toda to bi ga lahko odneslo daleč mimo dobre rešitve.
Zato obstaja še ena pomembna nastavitev:
Learning rate
Learning rate določa, kako velik korak model naredi pri vsakem popravku.
Majhen learning rate:
majhni, previdni koraki
Velik learning rate:
veliki, agresivni koraki
Če je learning rate premajhen, se model lahko uči zelo počasi.
Če je prevelik, lahko dobro rešitev ves čas preskakuje.
Predstavljaj si, da želiš priti na dno doline.
Če delaš korake po 20 centimetrov, bo trajalo dolgo.
Če skačeš po 500 metrov, boš verjetno ves čas pristajal na drugi strani doline.
Potrebujemo nekaj vmes.
Ena napaka še ne pomeni veliko
Do zdaj smo govorili samo o enem stanovanju.
V resničnem Machine Learningu imamo lahko:
100.000 stanovanj
ali milijone drugih primerov.
Model zato ne želi postati odličen samo pri enem stanovanju.
Želi najti parametre, ki dobro delujejo na velikem številu podatkov.
Recimo:
| Velikost | Prava cena |
|---|---|
| 40 m² | 180.000 € |
| 60 m² | 230.000 € |
| 80 m² | 300.000 € |
| 100 m² | 350.000 € |
Model naredi napoved za več primerov.
Izračuna napake.
Nato parametre premakne tako, da se skupna napaka zmanjša.
To ponavlja znova in znova.
Epoch
Ko model med učenjem enkrat pregleda celoten učni dataset, temu pogosto rečemo:
epoch
Če imamo 100.000 primerov in model vidi vseh 100.000, je zaključil eno epoho.
Nato jih lahko pregleda ponovno.
In ponovno.
Na primer:
Epoch 1
Model je precej slab.
Epoch 5
Začenja zaznavati povezave.
Epoch 20
Napovedi so precej boljše.
Epoch 100
Mogoče se skoraj nič več ne izboljšuje.
Toda več učenja ni vedno nujno bolje.
Do tega še pridemo.
Zakaj modela ne učimo vedno na vseh podatkih hkrati?
Pri velikih datasetih je lahko izračun gradienta za milijone primerov naenkrat zelo drag.
Zato podatke pogosto razdelimo v manjše skupine.
Tem skupinam rečemo:
batch
Recimo, da imamo milijon primerov.
Namesto da model računa vse naenkrat, mu damo:
256 primerov
Model:
- naredi napovedi,
- izračuna napako,
- izračuna gradient,
- popravi parametre.
Nato dobi naslednjih 256 primerov.
In postopek ponovi.
Tukaj pridemo do dejanskega »učenja«
Model se torej ne uči tako, kot se človek nauči novega pravila.
Nikjer nujno ne nastane stavek:
Stanovanja v Ljubljani so dražja.
Namesto tega se lahko zgodijo milijoni majhnih sprememb parametrov.
Parameter:
0,18273 → 0,18301
Drug parameter:
-1,024 → -1,019
Tretji:
4,712 → 4,698
Posamezna številka sama po sebi pogosto ne pomeni nič zanimivega.
Toda skupaj lahko milijoni ali milijarde takšnih parametrov predstavljajo zelo zapleten vzorec.
Kako to izgleda pri nevronski mreži?
Pri nevronski mreži je ista ideja precej povečana.
Namesto dveh parametrov jih imamo lahko:
- tisoče,
- milijone,
- milijarde.
Model dobi vhod.
Na primer sliko mačke.
Gre skozi mrežo in napove:
Mačka: 30 %
Pes: 60 %
Drugo: 10 %
Pravi odgovor je:
Mačka
Model je torej precej zgrešil.
Loss function izračuna napako.
Nato pride pomemben korak:
backpropagation
Kaj je backpropagation?
Backpropagation poskuša ugotoviti:
Koliko je posamezen parameter v mreži prispeval k napaki?
Mreža ima lahko ogromno povezanih izračunov.
Napaka nastane na koncu.
Backpropagation pa gre matematično nazaj skozi mrežo in izračuna, kako bi morali spremeniti posamezne parametre.
Nato gradient descent te parametre malo popravi.
Zelo poenostavljeno:
Napoved naprej → napaka → izračun vpliva nazaj → popravek parametrov
Temu procesu rečemo training.
In to se zgodi ogromnokrat
En popravek skoraj nikoli ne naredi pametnega modela.
Moč pride iz ponavljanja.
Model lahko naredi:
milijone ali milijarde majhnih popravkov.
Vsak popravek je majhen.
Skupaj pa lahko povzročijo ogromno spremembo v obnašanju modela.
Na začetku je lahko napoved skoraj naključna.
Po dovolj učenju pa model začne zaznavati kompleksne vzorce v podatkih.
Ampak obstaja problem
Kaj če model postane preveč dober pri podatkih, na katerih se je učil?
Recimo, da si zapomni skoraj vsako stanovanje v učnem datasetu.
Na teh podatkih ima fantastične rezultate.
Nato mu pokažemo novo stanovanje, ki ga še nikoli ni videl.
In model odpove.
Temu rečemo:
overfitting
Model se ni dovolj dobro naučil splošnih vzorcev.
Preveč se je prilagodil podatkom, ki jih že pozna.
Zato modelov običajno ne preverjamo samo na podatkih, na katerih se učijo.
Del podatkov pustimo ob strani.
Training in test podatki
Podatke lahko na primer razdelimo:
80 % → training data
20 % → test data
Na training podatkih se model uči.
Test podatkov med učenjem ne uporablja.
Na koncu mu pokažemo testne podatke in preverimo:
Kako dobro dela na primerih, ki jih še nikoli ni videl?
To je precej bolj pomembno kot vprašanje:
Kako dobro si zapomnil učne podatke?
Ker pravi cilj Machine Learninga ni pomnjenje.
Cilj je:
generalizacija.
Da model iz naučenih vzorcev zna pravilno sklepati tudi pri novih primerih.
Torej: kaj se zgodi po eni napaki?
Če zelo poenostavimo:
1. Model dobi podatke
80 m² stanovanje.
2. Naredi napoved
260.000 €.
3. Primerja jo s pravilnim odgovorom
300.000 €.
4. Loss function izračuna napako
Model vidi, da trenutni parametri niso idealni.
5. Gradient pokaže smer
Izračunamo, katere spremembe parametrov bi zmanjšale napako.
6. Learning rate določi velikost koraka
Parametre malo premaknemo.
7. Model poskusi ponovno
Nova napoved je mogoče nekoliko boljša.
In potem vse skupaj ponovi.
Tisočkrat.
Milijonkrat.
Včasih še precej večkrat.
Tu Machine Learning postane malo bolj zanimiv
Na prvi pogled imamo samo kup številk in matematičnih operacij.
Toda če imamo:
dovolj podatkov + primeren model + dobro optimizacijo
lahko iz teh majhnih popravkov nastane sistem, ki zazna vzorce, ki bi jih bilo človeku zelo težko zapisati kot klasična pravila.
In to je ena pomembnih razlik med klasičnim programiranjem in Machine Learningom.
Pri klasičnem programu pogosto napišemo pravila.
Pri Machine Learningu pa modelu pokažemo primere in mu dovolimo, da skozi optimizacijo sam poišče uporabne parametre.
Ni čarovnija.
Je pa rezultat milijonov majhnih matematičnih popravkov lahko presenetljivo zmogljiv.
Majhna opomba za firbce
Vsi Machine Learning algoritmi se ne učijo na popolnoma enak način.
Gradient descent in zgornji opis sta posebej pomembna pri linearnih modelih in nevronskih mrežah.
Decision tree in random forest na primer gradita svoja pravila nekoliko drugače.
Osnovno vprašanje pa ostane podobno:
Kako iz podatkov zgraditi model, ki bo dobro deloval tudi na novih primerih?
In ravno tu se začne ena naslednjih zanimivih tem:
Kako vemo, ali je model dejansko dober?
Training accuracy je namreč lahko zelo varljiva.
Next post ☺️
#MachineLearning #AI #DataScience #GradientDescent #NeuralNetworks #ZaFirbce