Submitted by zslotyi on Thu, 07/02/2020 - 10:07

Amióta számítógépek léteznek, azt halljuk, hogy a számítógépek csak gépek, amelyek nem csinálnak semmi mást, mint amit mondanak nekik. (Ha próbáltál már programozni, és a tapasztalataid nem feltétlenül erősítik meg az előző mondat igazságtartalmát, hadd egészítsem ki egy kicsit: a számítógépek nem azt csinálják, amit mondani akarunk nekik, hanem azt, amit mondunk nekik - így már stimmel?)

Ahhoz tehát, hogy a számítógép elvégezzen helyettünk egy feladatot, nem csak hogy pontosan el kell mondani, hogy mit várunk tőle, hanem azt is, hogy hogyan csinálja. Ráadásul mindezt úgy kell elmondanunk neki, hogy ő is megértse.

Lássunk egy példát!

Vegyünk egy szövegrészletet (nevezzük az egyszerűség kedvéért ‘string-nek’): “XY”. Valamilyen rejtélyes oknál fogva azt szeretnénk, ha a számítógép ezt a szövegrészletet, stringet megfordítaná.

Mit tegyünk?

Ha rendelkezésünkre áll a “megfordít” parancs, tehát, ha a számítógép tudja, hogy mit értünk egy string “megfordítása” alatt, a dolgunk rendkívül egyszerű. Kiadjuk az utasítást: fordítsd meg az XY-t, hátradőlünk, és egy nagyot kortyolunk a kezünk ügyében lévő hideg limonádéból.

De mi van, ha nincs ilyen parancsunk? Ha a világon korábban még senki nem vette a fáradságot arra, hogy megtanítsa a számítógépet sztringeket megfordítani. Ilyenkor nincs más lehetőségünk, mint hogy lépésről lépésre végigvezetjük a programot a feladat megoldásán. (Megjegyzés: egy sztring megfordítása tipikus beugrókérdés például egy állásinterjún vagy teszten. Mint a legtöbb ilyen feladatnak, több megoldása is lehetséges, az alább felvázolt csak egy az alternatívák közül.)
 

  1. bontsuk a sztringet alkotóelemeire (mondjuk az egyszerűség kedvéért betűire vagy karaktereire): X, Y
  2. tároljuk el ezeket a karaktereket külön elemekként egy olyan struktúrában, ami emlékszik magukra az elemekre és a sorrendjükre is. Mondjuk hozzunk létre egy listát, aminek az elemei (1) X (2) Y
  3. Hozzunk létre egy ugyanilyen struktúrát, listát üresen
  4. Válasszuk ki az első lista legutolsó elemét, és tároljuk el a második lista első helyén
  5. Válasszuk ki az első lista legutóbb kiválasztott elem előtti elemét, és tároljuk el a második lista következő helyén
  6. Ismételjük meg az (5.) lépést egészen addig, amíg az első lista végére nem érünk
     

Ha minden jól ment, és semmit nem rontottunk el, akkor hat lépésben megtanítottuk a számítógépet sztringeket megfordítani. Ráadásul a 4-6 lépések meglehetősen hasonlítanak egymásra, így egy kis odafigyeléssel az algoritmust tovább áramvonalasíthatnánk. A számítógép pedig a fenti elv alapján hűségesen megfordít majd nekünk magyar vagy francia szöveget, egy rövid kötőszót vagy a Háború és Békét. (Néhány apróságot figyelmen kívül hagytunk, de ezektől most az egyszerűség kedvéért tekintsünk is el).

A probléma azonban adott. A megoldásra a számítógépet nekünk kellett megtanítanunk, rávezetnünk. Ha egy ilyen egyszerű feladatra ilyen hosszan kell tanítani a számítógépet, akkor mi lesz a bonyolultabb feladatokkal? Vagy azokkal, amikre mi magunk sem tudjuk a megoldást?

Itt jön képbe a Machine Learning

Határozzuk meg újra a korábbi feladatot, úgy téve, mintha a számítógéphez hasonlóan a mi szótárunkból is hiányozna a “felcserél” parancs. Mi tehát az, amit akarunk?

Azt szeretnénk, hogy az algoritmusunk - bármi legyen is az - az XY bemenet esetén az YX kimenetet adná eredményül. Látszólag kevés a különbség, ám ahogy ez lenni szokott, az apró különbségeknek a későbbiekben fontos következményei vannak.

A jó hír, hogy a machine learning lehetővé teszi, hogy ha megmutatjuk az adott kiindulási alapot (XY) és az elvárt végterméket (YX), akkor a számítógép magától rájöjjön, hogy mi a feladata, és hogyan végezze azt el.

Van azonban néhány buktató.

Egy példa sosem elég

Egy átlagos intelligenciával rendelkező 12 éves számára ránézésre, a másodperc tört része alatt egyértelmű, hogy ha a bemenet XY és a várt kimenet YX, akkor a feladat megcserélni a bemenet karaktereit. Mi lehet itt a probléma?

Az egyik probléma, hogy egyetlen példa arra sem elég, hogy a feladatot egyértelműen meghatározza. A várt kimenetet ugyanis többféle módon is megkaphatjuk.

Nézzük a fenti példát:

XY -> YX

Mi volt tehát a feladat? Megcserélni a karaktereket? De melyikeket? Csak a nagybetűket vagy az összeset? Csak az elsőt és az utolsót, vagy az összeset? Lehet, hogy nem is felcseréltük, hanem inverz-abc sorrendbe raktuk őket?

Mindezekre a kérdésekre nem fogunk tudni válaszolni addig, amíg nem határozzuk meg egy másik bemenet elvárt kimenetét is.

Mutassunk meg tehát egy újabb példát a számítógépnek!

xyn -> nyx
Amint látjuk ez bizonyos kérdéseket tisztázott: Már tudjuk, hogy nem csak a nagybetűkkel kell a műveletet elvégeznünk, sőt a fordított abc sorrendet is kizárhatjuk. Még mindig nem tudjuk azonban, hogy a string összes- vagy csak az első és utolsó karakterét kell-e felcserélnünk.

A példa triviálisnak tűnik, de talán illusztrálja azt, hogy a feladat pontos leírásához - amennyiben csak példákon keresztül szeretnénk meghatározni azt - a példák egy megfelelően nagy készletére van szükségünk.

Egy viszonylag egyszerű feladatnál - például egy string megfordítása - lehet, hogy elég lesz néhány példa is, de az olyan problémáknál, amilyenek megoldására a machine learninget a hétköznapi életben használják, más nagyságrendekben kell gondolkoznunk.

Egy viszonylag egyszerű alkalmazási területnél talán egy néhány százas példakészlet megfelelő eredményt hozhat, de a kereskedelmi alkalmazásokat - mint amilyen például az iPhone arcfelismerője vagy a egyes természetes szövegfeldolgozó alkalmazások (Natural Language Processing vagy NLP), nem ritka, hogy több százmilliós vagy akár milliárdos példaszámmal fejlesztik és tréningezik.

A struktúrát nekünk kell felépítenünk

A számítógép bizonyos keretek között ki tudja találni, hogy - kisiskolás szóhasználattal élve - mit csinál a gép. Jó esetben még azt is, hogy hogyan, illetve még jobb esetben a hogyannal nekünk nem is kell törődnünk, hiszen a várt bemenet a várt kimenetet hozza válaszul.

A gépet magát azonban nekünk kell megépítenünk.

A bemenet és a kimenet közé olyan szerkezeteket kell helyeznünk, amelyek alkotóelemei lehetővé teszik, hogy a számítógép ne csak megoldja, hanem ki is találja a feladatot.

Bár sokféle ilyen szerkezet létezik, a machine learning területén az utóbbi bő tíz évben leginkább a neurális hálózatok (neural networks) előretörését láthatjuk.

A neurális hálózatok az idegrendszer neuronjaihoz hasonlóan különálló, de egymással összetett és szoros kapcsolatban álló egységekből állnak, amelyek önmagukban külön-külön működnek ugyan, de megfelelően összehangolva elképesztően komplex feladatok megoldására képesek. A neurális hálózatok és az idegrendszer neuronjai közötti hasonlóság mértéke külön vita tárgya (tipp: a hasonlóság meglehetősen felületes), de a megnevezés megfelelően érzékelteti a hálózatok szerkezetét, összetettségét illetve segít illusztrálni azt a koncepciót, hogy miközben a bemenetet és a hozzá tartozó kimenetet látjuk, nem igazán tudjuk részleteiben értékelni, hogy mi történik a “fekete dobozon belül”.

A neurális hálózatok - a természetben megtalálható idegrendszerekhez hasonlóan - változatos formákban, szerkezetekben és bonyolultságban léteznek. A konstrukciójukat általában az általuk végzett feladathoz optimalizálják, így vannak közöttük olyanok, amelyek csupán néhány- míg mások akár több százezer vagy több millió neuronból állnak.

Kutatásuk, fejlesztésük mára egy teljesen különálló, és elképesztő ütemben bővülő tudományterületté vált.

Az oldal, amit olvasol erre a területre hív kalandozni. Nézz körül, és tarts velünk