Gradient Descent i Java

1. Introduktion

I denne tutorial lærer vi om Gradient Descent-algoritmen. Vi implementerer algoritmen i Java og illustrerer den trin for trin.

2. Hvad er gradientafstamning?

Gradient Descent er en optimeringsalgoritme, der bruges til at finde et lokalt minimum af en given funktion. Det bruges meget inden for maskinlæringsalgoritmer på højt niveau for at minimere tabsfunktioner.

Gradient er et andet ord for hældning, og nedstigning betyder at gå ned. Som navnet antyder, går Gradient Descent ned ad hældningen af ​​en funktion, indtil den når slutningen.

3. Egenskaber ved gradientafstamning

Gradient Descent finder et lokalt minimum, som kan være forskelligt fra det globale minimum. Det lokale startpunkt er angivet som en parameter til algoritmen.

Det er en iterativ algoritme, og i hvert trin forsøger det at bevæge sig ned ad skråningen og komme tættere på det lokale minimum.

I praksis går algoritmen tilbage. Vi illustrerer og implementerer backtracking Gradient Descent i denne vejledning.

4. Trin-for-trin illustration

Gradient Descent har brug for en funktion og et startpunkt som input. Lad os definere og plotte en funktion:

Vi kan starte på ethvert ønsket tidspunkt. Lad os starte kl x=1:

I det første trin går Gradient Descent ned ad skråningen med en foruddefineret trinstørrelse:

Dernæst går det længere med samme trinstørrelse. Denne gang ender det dog med en større y end sidste trin:

Dette indikerer, at algoritmen har passeret det lokale minimum, så den går baglæns med en sænket trinstørrelse:

Efterfølgende, når den nuværende y er større end den foregående y, trinstørrelsen sænkes og negeres. Iterationen fortsætter, indtil den ønskede præcision er opnået.

Som vi kan se, fandt Gradient Descent et lokalt minimum her, men det er ikke det globale minimum. Hvis vi starter kl x= -1 i stedet for x= 1, det globale minimum vil blive fundet.

5. Implementering i Java

Der er flere måder at implementere Gradient Descent på. Her beregner vi ikke afledningen af ​​funktionen for at finde hældningsretningen, så vores implementering fungerer også for ikke-differentierbare funktioner.

Lad os definere præcision og stepCoefficient og giv dem indledende værdier:

dobbelt præcision = 0,000001; dobbelt trin Koefficient = 0,1;

I det første trin har vi ikke en tidligere y til sammenligning. Vi kan enten øge eller mindske værdien af x for at se om y sænker eller hæver. En positiv stepCoefficient betyder, at vi øger værdien af x.

Lad os nu udføre det første trin:

dobbelt tidligereX = initialX; dobbelt tidligereY = f.apply (forrigeX); currentX + = stepCoefficient * previousY;

I ovenstående kode, f er en Fungereog initialX er en dobbelt, der begge leveres som input.

Et andet vigtigt punkt at overveje er, at Gradient Descent ikke garanteres at konvergere. For at undgå at sidde fast i løkken, lad os have en grænse for antallet af gentagelser:

int iter = 100;

Senere mindsker vi iter ved en ved hver iteration. Derfor kommer vi ud af sløjfen ved maksimalt 100 iterationer.

Nu hvor vi har en forrigeX, kan vi oprette vores løkke:

mens (forrige trin> præcision && iter> 0) {iter--; dobbeltstrømY = f.apply (currentX); hvis (nuværendeY> forrigeY) {stepCoefficient = -stepCoefficient / 2; } forrigeX = nuværendeX; currentX + = stepCoefficient * previousY; forrigeY = nuværendeY; previousStep = StrictMath.abs (currentX - previousX); }

I hver iteration beregner vi det nye y og sammenlign det med det foregående y. Hvis nuværende Y er større end forrigeændrer vi vores retning og formindsker trinstørrelsen.

Sløjfen fortsætter, indtil vores trinstørrelse er mindre end den ønskede præcision. Endelig kan vi vende tilbage nuværendeX som det lokale minimum:

returstrømX;

6. Konklusion

I denne artikel gik vi gennem Gradient Descent-algoritmen med en trinvis illustration.

Vi implementerede også Gradient Descent i Java. Koden er tilgængelig på GitHub.


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