Silazak gradijenta u Javi

1. Uvod

U ovom uputstvu naučit ćemo o algoritmu spuštanja gradijenta. Implementirat ćemo algoritam u Javi i ilustrirati ga korak po korak.

2. Što je gradijentno spuštanje?

Gradient Descent je algoritam za optimizaciju koji se koristi za pronalaženje lokalnog minimuma zadane funkcije. Široko se koristi u algoritmima strojnog učenja na visokoj razini kako bi se funkcije gubitka svele na najmanju moguću mjeru.

Gradijent je druga riječ za nagib, a spust znači spuštanje. Kao što i samo ime govori, Gradient Descent se spušta kosinom funkcije sve dok ne dosegne kraj.

3. Svojstva gradijentnog spuštanja

Gradient Descent pronalazi lokalni minimum, koji se može razlikovati od globalnog minimuma. Početna točka je dana kao parametar algoritmu.

To je iterativni algoritam, i u svakom koraku pokušava se spustiti niz padinu i približiti lokalnom minimumu.

U praksi se algoritam vraća unatrag. U ovom ćemo uputstvu ilustrirati i implementirati povratno praćenje spuštanja gradijenta.

4. Ilustracija korak po korak

Gradient Descent kao ulaz treba imati funkciju i polaznu točku. Definirajmo i zacrtajmo funkciju:

Možemo započeti u bilo kojoj željenoj točki. Krenimo od x=1:

U prvom koraku, Gradient Descent se spušta niz padinu s unaprijed definiranom veličinom koraka:

Dalje, ide dalje s istom veličinom koraka. Međutim, ovaj put završava na većem g nego zadnji korak:

To ukazuje na to da je algoritam prošao lokalni minimum, pa se vraća unazad s smanjenom veličinom koraka:

Naknadno, kad god je struja g je veći od prethodnog g, veličina koraka se spušta i negira. Ponavljanje traje sve dok se ne postigne željena preciznost.

Kao što vidimo, Gradient Descent je ovdje pronašao lokalni minimum, ali to nije globalni minimum. Ako krenemo od x= -1 umjesto x= 1, naći će se globalni minimum.

5. Implementacija u Javi

Postoji nekoliko načina za primjenu Gradient Descent. Ovdje ne izračunavamo izvod funkcije da bismo pronašli smjer nagiba, tako da naša implementacija radi i za funkcije koje se ne mogu razlikovati.

Definirajmo preciznost i stepCoefficient i dajte im početne vrijednosti:

dvostruka preciznost = 0,000001; dvostruki koeficijent koraka = 0,1;

U prvom koraku nemamo prethodni g za usporedbu. Vrijednost možemo povećati ili smanjiti x da vidim je li g spušta ili povisuje. Pozitivno stepCoefficient znači da povećavamo vrijednost x.

Izvršimo sada prvi korak:

dvostruki prethodniX = početniX; dvostruki prethodniY = f.apply (previousX); currentX + = stepCoefficient * prethodnoY;

U gornjem kodu, f je Funkcija, i početnaX je dvostruko, oba se daju kao ulaz.

Još jedna ključna stvar koju treba uzeti u obzir je da Gradient Descent nije zajamčeno konvergencija. Da ne bismo zapeli u petlji, imajmo ograničenje broja ponavljanja:

int iter = 100;

Kasnije ćemo smanjiti iter po jedan u svakoj iteraciji. Slijedom toga, izaći ćemo iz petlje na maksimalno 100 ponavljanja.

Sad kad imamo prethodniX, možemo postaviti našu petlju:

while (previousStep> preciznost && iter> 0) {iter--; dvostruka strujaY = f.apply (currentX); if (trenutnoY> prethodnoY) {stepCoefficient = -stepCoefficient / 2; } prethodniX = trenutniX; currentX + = stepCoefficient * prethodnoY; prethodniY = trenutniY; previousStep = StrictMath.abs (currentX - previousX); }

U svakoj iteraciji izračunavamo novo g i usporedite ga s prethodnim g. Ako trenutnoY je veći od prethodniY, mijenjamo smjer i smanjujemo veličinu koraka.

Petlja se nastavlja sve dok naša veličina koraka nije manja od željene preciznost. Napokon se možemo vratiti currentX kao lokalni minimum:

povratna strujaX;

6. Zaključak

U ovom smo članku prošetali algoritam Gradient Descent s detaljnom ilustracijom.

Također smo implementirali Gradient Descent u Javi. Kôd je dostupan na GitHub-u.


$config[zx-auto] not found$config[zx-overlay] not found