[STRUCE1] 3. laboratorijska vježba - 2021/2022
tomekbeli420
Heads up, pazite kad implementirate gradijentni spust kod logističke regresije
linija 8 u pseudokodu mora biti
w_0 \gets w_0 + \eta \Delta w_0
dakle sa plusom, jer ako ste akumulirali negativan gradijent u w_0 onda ga treba zbrojiti kod ažuriranja a ne ponovno oduzimati
cloudies
tomekbeli420 Di si bio u nedjelju kad sam izgubila cijelo popodne zureci u kod i kad mi nije bilo jasno zasto ne radi s minusom :')
kix7
tomekbeli420 Otkud ti ova slika? U natuknicama piše ok kolko vidim
[obrisani korisnik]
cloudies to kad prerano počinjete s labosima heh
tomekbeli420
[obrisani korisnik] brt u sljedeća dva tjedna moram složit 4 labosa pa reko prvo ću ovu zvjerku jebenu
tomekbeli420
Fish99 Skripta P06 - Logistička regresija, stranica u PDF-u numerirana sa 17
dora
Je su li ovo dobre tezine u 1.c? [ 6.44150959 -2.11012128 0.53522851]
Lyras
AE te i ja dobijem
Me1
AE [ 4.45449454 -1.71089242 0.68413507] 0.13521872720206748
ja dobivamo ove tezine i ovu pogrešku unakrsne entropije, ove tvoje dobivamo kad maknem uvjet za prestanek iteracije kod premale promjene greške između dva koraka
gladiator
dobijam “math domain error” u funkciji za pogrešku unakrsne entropije. Problem nastaje kad pokušam logaritmirati izraz koji je 0. Kako ovo zaobići?
viliml
gladiator Možeš clipati input na [eps, 1-eps] gdje je eps neki mali broj.
Ali mislim da ne bi smio nikada uopće dobiti točno 0, pazi da nisi nešto drugo krivo.
tomekbeli420
gladiator e jučer sam se cijelu noć zajebavao sa ovim problemom, evo što sam zaključio
Problemi nastaju prilikom evaluacije \ln{\left(1 - \sigma(x)\right)} što se više x povećava (taj x će kod nas biti onaj \mathbf{w}^{\mathrm{T}} \mathbf{x} + w_0, no nebitno za ovaj konkretan problem, bitno je da je to neki realan broj koji je input u sigmoidalnu funkciju)
i prilikom evaluacije \ln{\left(\sigma(x)\right)} što se više x smanjuje.
Koji je uzrok problema? Output sigmoide. Pa ako ideš računati upravo tako, za relativno veliki x će ti u jednom trenutku ispasti \sigma(x) = 1 zbog računalne nepreciznosti, odnosno ne može računalo prikazati takav broj koji je toliko blizu 1. Npr. meni već za x \geq 36.7 ispada tako. To je onda problem jer će ti dojavljivati greške/bacati exceptione ako ideš računati \ln{\left(1 - \sigma(x)\right)} jer će pokušati računati \ln{0}. Kako to zaobići?
Pa ako malo drukčije izrazimo, dobijemo
\ln{\left(1 - \sigma(x)\right)} = \ln{\left(1 - \frac{1}{1+ e^{-x}}\right)} = \ln{\left(\frac{e^{-x}}{1+e^{-x}}\right)} = \ln{\left(e^{-x}\right)} - \ln{\left(1 + e^{-x}\right)} = -x - \ln{\left(1 + e^{-x}\right)}
Što neće biti problematično za relativno velike x. Možeš otići korak dalje i primijetiti da će za relativno velike x izraz e^{-x} biti blizu 0, pa onda gornji izraz u tom slučaju aproksimirati na samo -x.
Isto vrijedi i za drugi problematični slučaj računanja \ln{\left(\sigma(x)\right)} kada je x relativno mali (kod mene je to x \leq -700)
Opet preformuliraš izraz kao i gore
\ln{\left(\sigma(x)\right)} = \ln{\left( \frac{1}{1+e^{-x}} \right)} = -\ln{\left( 1+e^{-x} \right)}
Što je sasvim u redu jer će u logaritam onda ući dosta veliki broj zbog ovog e^{-x}. Opet, ako hoćeš jednostavnu aproksimaciju, onda možeš ju ostvariti argumentiranjem (ili limesima) da ovih 1 nadodanih na e^{-x} nije značajna pa onda aproksimirati gornji izraz sa samo x.
Zero dobije se kao argument eta
i cijelo vrijeme je ista, ne moraš raditi linijsko pretraživanje
micho
gladiator umjesto log(x)
napravi log(min(1, x + 1e-6))
. Ne stavljaj premali epsilon jer ćeš uzrokovati jedan drugi problem. Bolja rješenja od ovoga će zahtijevati funkciju koja nema takvih problema, kao npr. izraz kolege @tomekbeli420 . Jedini problem kod tog izraza je što nije uvijek primjenjiv, npr. tu se moglo radi sigmoide.
viliml
gladiator
tomekbeli420
M̵̧̩͑̀͝î̶͍̉ć̴̝̾́̀o̶̺̟̣͂̽
Ozbiljno, kako svi vi dobivate nule?
Meni su svi rezultati uvijek između 0.005 i 0.995.
Ovo nikad ne bi uopće trebao biti problem osim ako je input beskonačan, težina beskonačna, ili greškom računate nad h >= 0.5
umjesto h
.
Također, vidim da samo math.log
uopće baca math domain error, np.log
pristojna vraća negativno beskonačnost kao što bi trebao. A u svakom slučaju bi inače trebalo koristiti np.log
, bolji je u svakom pogledu, pogotovo kad se u projektu već koristi numpy na hrpi drugih mjesta. To vrijedi općenito, sve iz standardne biblioteke što se može zamijeniti numpyom treba se, život će vam biti lakši.
Zero
Kako se dobiva stopa ucenja?
tomekbeli420
M̵̧̩͑̀͝î̶͍̉ć̴̝̾́̀o̶̺̟̣͂̽ Kako to misliš nije primjenjiv?
micho
tomekbeli420 ako imaš neku drugu funkciju osim sigmoide
[obrisani korisnik]
Me hmm ja dobivam kao kolega kad mi je max_iter == 2000, i ne breaka mi zbog uvjeta, a kad povećam broj iteracija na npr. 4000 -> breaka zbog uvjete i dobijem težine:
[ 7.73426648 -2.38474752 0.46232798]
micho
viliml Ozbiljno, kako svi vi dobivate nule?
Ja ne dobivam ali je sasvim moguće dobiti 0 radi nepreciznosti float32. A numpy neće baciti error jer ima +-inf vrijednost (koja je dio float specifikacije), no to ne znači da nećeš uletiti u probleme jer će ti opet poharati brojke.
Zapravo je korištenje numpyja gore jer si sakrivaš pravu pogrešku i teže ćeš debuggirati. Kao i neke druge stavke numpyja koje su jednostavno krivo implementirane, ali o tom po tom ako ćete ga koristiti dovoljno da si poželite iskopati oči. Dobro ga je koristiti jedino jer je brži od math
.
A i mislim dobro je ovakve stvari pohvatati na faksu, ovakve greške vam ruše produkcijske modele ko iz šale i nevjerojatno ih je teško naći. T5 je npr. bacao NaN gradijente nakon cca 2000000 ulaznih primjeraka jer nisu clippali logite.