HyperOpt Demystified

Hur man automatiserar modelljustering med HyperOpt

Älskar du att trimma modeller? Om ditt svar är "ja", är det här inlägget inte för dig.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
En tecknad film från min morfar — webbplats.

I den här bloggen kommer vi att täcka den extremt populära automatiserade hyperparameterjusteringsalgoritmen som kallas Trädbaserade Parzen Estimators (TPE). TPE stöds av paketet med öppen källkod, HyperOpt. Genom att utnyttja HyperOpt och TPE kan maskininlärningsingenjörer snabbt utveckla högoptimerade modeller utan manuell inställning.

Utan vidare, låt oss dyka in!

HyperOpt är ett pythonpaket med öppen källkod som använder en algoritm som kallas Tree-based Parzen Esimtors (TPE) för att välja modellhyperparametrar som optimerar en användardefinierad målfunktion. Genom att helt enkelt definiera den funktionella formen och gränserna för varje hyperparameter söker TPE grundligt men ändå effektivt igenom komplex hyperrymd för att nå optimum.

TPE är en sekventiell algoritm som utnyttjar bayesiansk uppdatering och följer sekvensen nedan.

  1. Träna en modell med flera uppsättningar av slumpmässigt valda hyperparametrar, vilket returnerar objektiva funktionsvärden.
  2. Dela upp våra observerade objektiva funktionsvärden i "bra" och "dåliga" grupper, enligt något tröskelvärde (γ).
  3. Beräkna poängen för "lovande", vilket är rättvist P(x|bra) / P(x|dåligt).
  4. Bestäm hyperparametrarna som maximerar lovande genom blandningsmodeller.
  5. Anpassa vår modell med hjälp av hyperparametrarna från steg 4.
  6. Upprepa steg 2–5 tills ett stoppkriterie.

Här är en exempel på snabbkod.

Ok det var många stora ord. Låt oss sakta ner och verkligen förstå vad som händer.

1.1 – Vårt mål

Dataforskare är upptagna. Vi vill ta fram riktigt bra modeller, men gör det på ett effektivt och idealiskt sätt.

Vissa steg i ML-modelleringslivscykeln är dock mycket svåra att automatisera. Utforskande dataanalys (EDA) och funktionsteknik, till exempel, är vanligtvis ämnesspecifika och kräver mänsklig intuition. Modellinställning, å andra sidan, är en iterativ process där datorer kan utmärka sig.

Vårt mål genom det här inlägget är att förstå hur man kan utnyttja algoritmer för att automatisera modelljusteringsprocessen.

För att hjälpa oss att tänka på det målet, låt oss använda en analogi: vi är pirater som letar efter begravda skatter. Det är också viktigt att notera att vi är mycket effektiva pirater som vill minimera vår tid på att leta efter den begravda skatten. Så, hur ska vi minimera den tid som ägnas åt att söka? Svaret är använd en karta!

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 1: exempel 3D hyperparameter sökutrymme. Placeringen av skattkistan är ett globalt optimum. Bild av författare.

I figur 1 har vi en fiktiv karta som visar var vår skatt finns. Efter mycket klättring och grävande skulle det inte vara så svårt att nå den skatten eftersom vi vet exakt var den finns.

Men vad händer när vi inte har en karta?

När vi får i uppdrag att trimma en modell får vi tyvärr ingen karta. Vår terräng, som motsvarar hyperparmeterns sökutrymme, är okänd. Dessutom är platsen för vår skatt, som motsvarar den optimala uppsättningen hyperparametrar, också okänd.

Med den inställningen, låt oss prata om några potentiella sätt att effektivt utforska detta utrymme och hitta en skatt!

1.2 — Potentiella lösningar

Den ursprungliga metoden för modellinställning är "manuell" - ingenjören kommer faktiskt att manuellt testa många olika konfigurationer och se vilken hyperparameterkombination som ger den bästa modellen. Även om den är informativ är den här processen ineffektiv. Det måste finnas ett bättre sätt...

1.2.1 — Rutnätssökning (sämsta)

Vår första optimeringsalgoritm är rutnätssökning. Rutnätssökning testar iterativt alla möjliga kombinationer av hyperparametrar inom ett användarspecificerat rutnät.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 2: exempel på rutnätssökningslayout. Bild av författare

Till exempel, i figur 2, där du ser en röd prick är där vi kommer att omskola och utvärdera vår modell. Detta ramverk är ineffektivt eftersom det återanvänder dåliga hyperparametrar. Till exempel, om hyperparameter 2 har liten inverkan på vår objektiva funktion, kommer vi fortfarande att testa alla kombinationer av dess värden och därigenom öka det nödvändiga antalet iterationer med 10x (i det här exemplet).

Men innan du går vidare är det viktigt att notera att rutnätssökning fortfarande är ganska populärt eftersom det garanterat kommer att hitta ett optimum givet ett korrekt angivet rutnät. Om du bestämmer dig för att använda metoden, se till att du transformerar ditt rutnät för att återspegla den funktionella formen av dina hyperparametrar. Till exempel, max_depth för a slumpmässig skogsklassificerare är ett heltal — låt det inte söka över ett kontinuerligt utrymme. Det är också osannolikt att den har en enhetlig fördelning - om du känner till den funktionella formen för din hyperparameter, transformera rutnätet för att återspegla det.

Sammanfattningsvis, rutnätssökning är föremål för dimensionalitetens förbannelse och räknar om information mellan utvärderingar, men används fortfarande flitigt.

1.2.2 — Slumpmässig sökning (bra)

Vår andra algoritm är slumpmässig sökning. Slumpmässig sökning försöker med slumpmässiga värden inom ett användarspecificerat rutnät. Till skillnad från rutnätssökning är vi inte hänvisade till att testa alla möjliga kombinationer av hyperparametrar, vilket ökar effektiviteten.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 3: exempel på slumpmässig sökning. Bild av författare.

Här är ett coolt faktum: slumpmässig sökning kommer att hitta (i genomsnitt) en topp 5 % hyperparameterkonfiguration inom 60 XNUMX iterationer. Som sagt, precis som med rutnätssökning måste du omvandla ditt sökutrymme för att återspegla den funktionella formen för varje hyperparam.

Slumpmässig sökning är en bra baslinje för hyperparameteroptimering.

1.2.3 – Bayesiansk optimering (bättre)

Vår tredje kandidat är vår första Sequential Model-Based Optimization (SMBO) algoritm. Den viktigaste konceptuella skillnaden från de tidigare teknikerna är vi använd iterativt tidigare körningar för att fastställa framtida utforskningspunkter.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 4: Bayesian optimeringsexempel — src. Bild av författare.

Bayesiansk hyperparameteroptimering ser ut att utveckla en probabilistisk fördelning av vårt hyperparametersökutrymme. Därifrån använder den en förvärvsfunktion, till exempel förväntad förväntad förbättring, för att omvandla vårt hyperrymd till att bli mer "sökbart". Slutligen använder den en optimeringsalgoritm, såsom stokastisk gradientnedstigning, för att hitta de hyperparametrar som maximerar vår förvärvsfunktion. Dessa hyperparametrar används för att passa vår modell och processen upprepas tills konvergens.

Bayesiansk optimering överträffar vanligtvis slumpmässig sökning, men den har vissa grundläggande begränsningar som att kräva numeriska hyperparametrar.

1.2.4 — Trädbaserade Parzen-estimatorer (bäst)

Slutligen, låt oss prata om stjärnan i showen: Tree-Based Parzen Estimators (TPE). TPE är en annan SMBO-algoritm som vanligtvis överträffar grundläggande bayesiansk optimering, men det främsta försäljningsargumentet är att den hanterar komplexa hyperparameterrelationer via en trädstruktur.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 5: exempel på hierarkisk struktur för TPE — src. Bild av författare.

Låt oss använda figur 5 för att förstå detta trädstruktur. Här tränar vi en Support Vector Machine (SVM) klassificerare. Vi kommer att testa två kärnor: linear och RBF. En linear kärnan tar inte en breddparameter men RBF gör det, så genom att använda en kapslad ordbok kan vi koda denna struktur och därigenom begränsa sökutrymmet.

TPE stöder också kategoriska variabler som traditionell Bayesiansk optimering inte gör.

Snabb ansvarsfriskrivning innan du går vidare, det finns många andra paket för justering av hyperparameter. Var och en stöder en mängd olika algoritmer, av vilka några inkluderar slumpmässig skog, gaussiska processer och genetiska algoritmer. TPE är en mycket populär och allmän algoritm, men är inte nödvändigtvis den bästa.

Generellt sett är TPE en riktigt robust och effektiv hyperparameteroptimeringslösning.

Nu när vi har en allmän förståelse för några populära hyperparameteroptimeringsalgoritmer, låt oss göra en djupdykning i hur TPE fungerar.

För att återgå till vår analogi, vi är pirater som letar efter begravda skatter men har ingen karta. Vår kapten behöver skatten ASAP, så vi måste gräva på strategiska platser som har stor sannolikhet att ha skatter, med hjälp av tidigare grävningar för att bestämma platsen för framtida grävningar.

2.1 — Initiering

Till att börja med, vi definiera begränsningarna för vårt utrymme. Som nämnts ovan har våra hyperparametrar ofta en funktionell form, max/min-värden och hierarkisk relation till andra hyperparametrar. Med hjälp av vår kunskap om våra ML-algoritmer och vår data kan vi definiera vårt sökutrymme.

Därefter måste vi definiera vår objektiva funktion, som används för att utvärdera hur "bra" vår hyperparameterkombination är. Några exempel inkluderar klassiska ML-förlustfunktioner, som RMSE eller AUC.

Bra! Nu när vi har ett begränsat sökutrymme och ett sätt att mäta framgång är vi redo att börja söka...

2.2 — Iterativ Bayesiansk optimering

Bayesiansk optimering är en sekventiell algoritm som hittar punkter i hyperrymden med stor sannolikhet att vara "framgångsrik" enligt en objektiv funktion. TPE utnyttjar bayesiansk optimering men använder några smarta knep för att förbättra prestanda och hantera sökutrymmes komplexitet...

2.2.0 — Den konceptuella installationen

Det första tricket är modellering P(x|y) istället för P(y|x)...

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 6: villkorad sannolikhet som TPE ser ut att lösa. Bild av författare.

Bayesiansk optimering ser vanligtvis ut att modellera P(y|x), vilket är sannolikheten för ett objektiv funktionsvärde (y), givna hyperparametrar (x). TPE gör tvärtom - det ser ut att modellera P(x|y), vilket är sannolikheten för hyperparametrarna (x), givet det objektiva funktionsvärdet (y).

Kort sagt, TPE försöker hitta de bästa objektiva funktionsvärdena och sedan bestämma de associerade hyperparametrarna.

Med den mycket viktiga inställningen, låt oss komma in på den faktiska algoritmen.

2.2.1 — Dela upp vår data i "bra" och "dåliga" grupper

Kom ihåg att vårt mål är att hitta de bästa hyperparametervärdena enligt någon objektiv funktion. Så, hur kan vi utnyttja P(x|y) att göra det?

Först delar TPE upp våra observerade datapunkter i två grupper: god, betecknad g(x), och illa, betecknad l(x). Gränsen mellan bra och dåligt bestäms av en användardefinierad parameter gamma (γ), som motsvarar den objektiva funktionspercentilen som delar upp våra observationer (y*).

Så, med γ = 0.5, vårt objektiva funktionsvärde som delar upp våra observationer (y*) kommer att vara medianen för våra observerade punkter.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 7: uppdelning av p(x|y) i två uppsättningar. Bild av författare.

Som visas i figur 7 kan vi formalisera p(x|y) med hjälp av ovanstående ramverk. Och för att rulla på med piratanalogin...

Piratperspektiv: när vi tittar på de platser vi redan har utforskat, listar l(x) platser med väldigt lite skatter och g(x) listar platser med massor av skatter.

2.2.32— Beräkna "Lovande"-poängen

För det andra definierar TPE hur vi ska utvärdera en oobserverad hyperparameterkombination via "lovande" poäng.

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 8: definition av lovande poäng. Bild av författare.

Figur 8 definierar vår lovande poäng (P), vilket bara är ett förhållande med följande komponenter...

  • Täljare: sannolikheten att observera en uppsättning hyperparametrar (x), givet att motsvarande målfunktionsvärde är "god. "
  • Nämnare: sannolikheten att observera en uppsättning hyperparametrar (x), givet att motsvarande målfunktionsvärde är "illa. "

Ju större "lovande" värde, desto mer sannolikt är våra hyperparametrar x kommer att ge en "bra" objektiv funktion.

Piratperspektiv: lovande visar hur sannolikt en given plats i vår terräng kommer att ha massor av skatter.

Snabbt åt sidan innan du går vidare, om du är bekant med Bayesiansk optimering, fungerar denna ekvation som en förvärvsfunktion och är proportionell mot Förväntad förbättring (EI).

2.2.3— Skapa en sannolikhetstäthetsuppskattning

För det tredje ser TPE ut att utvärdera poängen för "lovande" via blandningsmodeller. Tanken med blandningsmodeller är att ta flera sannolikhetsfördelningar och sätta ihop dem med en linjär kombination - src. Dessa kombinerade sannolikhetsfördelningar används sedan för att utveckla uppskattningar av sannolikhetstäthet.

I allmänhet är blandningsmodelleringsprocessen...

  1. Definiera fördelningstypen för våra poäng. I vårt fall, om vår variabel är kategorisk använder vi en omvägd kategorisk fördelning och om den är numerisk använder vi en gaussisk (dvs normal) eller enhetlig fördelning.
  2. Iterera över varje punkt och infoga en fördelning vid den punkten.
  3. Summera massan av alla fördelningar för att få en uppskattning av sannolikhetstäthet.

Observera att denna process körs individuellt för båda uppsättningarna l(x) och g(x).

Låt oss gå igenom ett exempel i figur 9...

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 9: exempel på trunkerade gaussiska fördelningar som passar till 3 hyperparameterobservationer. Bild av författare.

För varje observation (blå prickar på x-axeln) skapar vi en normalfördelning ~N(μ, σ), där...

  • μ (mu) är medelvärdet av vår normalfördelning. Dets värde är platsen för vår punkt längs x-axeln.
  • σ (sigma) är standardavvikelsen för vår normalfördelning. Dess värde är avståndet till närmaste angränsande punkt.

Om punkter ligger nära varandra blir standardavvikelsen liten och därmed blir fördelningen mycket hög och omvänt, om punkter är spridda, blir fördelningen platt (figur 10)...

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 10: exempel på inverkan av standardavvikelse på formen av en normalfördelning. Bild av författare.

Piratperspektiv: NA — pirater är inte bra med blandmodeller.

En annan snabb sida innan du går vidare: om du läser litteraturen kommer du att märka att TPE använder "stympade" gaussianer, vilket helt enkelt betyder att gausserna begränsas av det intervall som vi anger i vår hyperparameterkonfiguration istället för att sträcka sig till +/- oändligt .

2.2.4 — Bestämma nästa punkt att utforska!

Låt oss sammanföra dessa bitar. Hittills har vi 1) skaffat objektiva funktionsobservationer, 2) definierat vår "lovande" formel och 3) skapat en uppskattning av sannolikhetstäthet via blandningsmodeller baserade på tidigare värden. Vi har alla bitar för att utvärdera en given punkt!

Vårt första steg är att skapa en genomsnittlig sannolikhetstäthetsfunktion (PDF) för båda g(x) och l(x).

Hyperparameter hyperparameter tuning modell tuning maskininlärning data vetenskap sklearn modell mllib spark hyperopt tree parzen estimator tpe tree based parzen esimtator mlflow dataabricks
Figur 11: överlagring av den genomsnittliga sannolikhetstätheten givet 3 observerade punkter. Bild av författare.

Ett exempel på process visas i figur 11 — den röda linjen är vår genomsnittliga PDF och är helt enkelt summan av alla PDF-filer dividerat med antalet PDF-filer.

Med den genomsnittliga PDF-filen kan vi få sannolikheten för ett hyperparametervärde (x) vara i g(x) or l(x).

Låt oss till exempel säga att de observerade värdena i figur 11 tillhör uppsättningen "bra", g(x). Baserat på vår genomsnittliga PDF är det osannolikt att ett hyperparametervärde på 3.9 eller 0.05 hör till den "bra" uppsättningen. Omvänt verkar ett hyperparametervärde på ~1.2 vara mycket troligt att tillhöra den "bra" uppsättningen.

Nu är detta bara ena halvan av bilden. Vi tillämpar samma metodik för den "dåliga" uppsättningen, l(x). Eftersom vi vill maximera g(x) / l(x), lovande punkter bör placeras var g(x) är hög och l(x) är låg.

Ganska cool, eller hur?

Med dessa sannolikhetsfördelningar kan vi ta prov från våra trädstrukturerade hyperparametrar och hitta den uppsättning hyperparametrar som maximerar "lovande" och därmed är värda att utforska.

Piratperspektiv: nästa plats vi gräver är den plats som maximerar (sannolikheten att ha massor av skatter) / (sannolikheten att ha liten skatt).

Nu när du vet hur det fungerar, här är några praktiska tips för att implementera TPE via open source-paketet, HyperOpt.

3.1 — Struktur för en HyperOpt-app

Generellt finns det tre huvudsteg när man använder HyperOpt...

  1. Definiera sökutrymmet, vilket bara är intervallen och funktionsformerna för hyperparametrarna du vill optimera.
  2. Definiera passningsfunktionen, som kallar din model.fit() funktion på en given tåg/provdelning.
  3. Definiera den objektiva funktionen, vilket är någon av de klassiska noggrannhetsmåtten, som RMSE eller AUC.

Tyvärr kräver dessa automatiserade inställningsmetoder fortfarande designinput från dataforskaren - det är inte en helt gratis lunch. Men anekdotiskt sett är TPE ganska robust mot felspecifikation av hyperparameter (inom rimliga gränser).

3.2— Tips och tricks

  • HyperOpt är parallelliserbar via båda Apache Spark och MongoDB. Om du arbetar med flera kärnor, oavsett om det är i molnet eller på din lokala dator, kan detta drastiskt minska körtiden.
  • Om du parallelliserar inställningsprocessen via Apache Spark, använd en SparkTrialsobjekt för enkelnods ML-modeller (sklearn) och en Trails objekt för parallelliserade ML-modeller (MLlib). Koden finns nedan.
  • MLflow är en öppen källkodsmetod för att spåra dina modellkörningar. Den integreras enkelt med HyperOpt.
  • Begränsa inte sökutrymmet för tidigt. Vissa kombinationer av hyperparametrar kan vara förvånansvärt effektiva.
  • Det kan vara svårt att definiera sökutrymmet, särskilt om du inte känner till det funktionell form av dina hyperparametrar. Av personlig erfarenhet är TPE dock ganska robust mot felaktig specifikation av dessa funktionella former.
  • Att välja en bra objektiv funktion räcker långt. I de flesta fall skapas fel inte lika. Om en viss typ av fel är mer problematisk, se till att bygga in den logiken i din funktion.

3.3— Ett kodexempel

Här är lite kod för att köra HyperOpt på ett distribuerat sätt. Det var anpassat från koden i boken, Machine Learning Engineering in Action — här är git repo.

Några trevliga funktioner i detta utdrag inkluderar parallellisering via Apache Spark och modellloggning via MLflow. Observera också att det här utdraget optimerar en sklearn RandomForestRegressor - du måste ändra modell och passningsfunktion för att passa dina behov.

Och där har du det — HyperOpt i all ära!

För att slå hopp om nyckelpunkterna, låt oss snabbt sammanfatta.

Hyperparameterjustering är en nödvändig del av ML-modellens livscykel, men är tidskrävande. Algoritmer för sekventiell modellbaserad optimering (SMBO) utmärker sig när det gäller att söka efter optimum i komplexa hyperrymden, och de kan tillämpas på justering av hyperparameter. Trädbaserade Parzen Estimators (TPE) är en mycket effektiv SMBO och överträffar både Bayesian Optimization och Random Search.

TPE upprepar stegen nedan tills ett stoppkriterie:

  1. Dela upp observerade punkter i "bra" och "dåliga" uppsättningar, enligt någon hyperparameter, gamma.
  2. Anpassa en blandningsmodell till både den "bra" och "dåliga" uppsättningen för att utveckla en uppskattning av genomsnittlig sannolikhetstäthet.
  3. Välj den punkt som optimerar poängen för "lovande", vilket utnyttjar steg 2 för att uppskatta sannolikheten att hamna i seten "bra" och "dåliga".

Slutligen har vi en riktigt cool kodsnutt som visar hur man parallelliserar HyperOpt via SparkTrials. Den loggar också alla våra iterationer till MLflow.

HyperOpt Demystified Återpublicerad från källa https://towardsdatascience.com/hyperopt-demystified-3e14006eb6fa?source=rss—-7f60cf5620c9—4 via https://towardsdatascience.com/feed

<!–

->

Tidsstämpel:

Mer från Blockchain-konsulter