Bevezetés a neuroevolúcióba

Hogyan talált egy neurális hálózat kiskaput a játékomban?

Kifejlesztett egy mesterséges intelligenciát, hogy játsszon egy játékot, de úgy döntött, hogy kigúnyolja!

Mielőtt megvizsgálná, hogyan egy mesterséges intelligencia trollkodta a játékomat, ismerkedjünk meg a „Neuroevolution” alapjaival, hogy megértsük, miérttörtént.

A neuroevolúció
1. Genetikai algoritmus
2. Neurális hálózat

Genetikai algoritmus

Az algoritmus mögött meghúzódó koncepciót Darwin evolúcióelmélete ihlette.

Ezek a genetikai algoritmus főbb szakaszai…

  1. Hozzon létre egy véletlen sokaságot
  2. Számítsa ki a népesség minden egyes tagjának fittségét
  3. Hajtsa végre a természetes kiválasztást
  4. Végezzen crossover-t a természetesen kiválasztott tagokkal
  5. Véletlenszerűen alkalmazza a mutációt az utódokon a keresztezés eredményeként
  6. Létrejön az új populáció, dobja el a régi generációt, és folytassa a 2. lépéssel

Nézze, ezt az emberi vagy más élőlények valós világbeli evolúciójából merítheti, de végül is ne feledje, hogy a Genetic Algorithm alapvetően egy keresési algoritmus.

Tekintsük ezt a grafikont, tegyük fel, hogy itt egy (x,y) pontot szeretne keresni úgy, hogy a z értéke a maximális legyen. Kezdetben a grafikon teljesen feltáratlan lenne, így a kezdeti ponton kívül nem igazán biztos a z értékben a grafikon bármely más pontjában.

Számos keresési algoritmust alkalmazhatunk, hogy ezt megtegye helyettünk, de nézzük meg, hogyan csinálná ezt a Genetic Algorithm.

Lépés: Véletlen populáció

Először a GA-ban (Genetic Algorithm) kezdünk néhány véletlenszerű ponttal, vagy mondhatunk véletlenszerű találgatásokat a megoldási térből. Például a fenti grafikonon azt látjuk, hogy az „x” értéke bármi lehet -3 és +3 között, és ugyanez a tartomány vonatkozik az „y”re is.

Tehát véletlenszerű találgatásaink így nézhetnek ki…

Ha a GA-ról beszélünk, ezvéletlen populációgeneráció volt. Alapvetően egy (x,y) párból álló véletlenszerű sokaságot hoztunk létre, mindegyiknek lesz valamilyen z értéke. Ezek az „x” és az „y”értékek génnek tekinthetők.

lépés: Fitness számítás

Most jön az fitness számítás, ez azért van, mert meg akarjuk ítélni, hogy a véletlenszerű tippek közül melyik jobb a többinél, és szükségünk van valami konkrét összehasonlításra.
Tehát meg kell határoznunk egy fitnesz funkciót, amely megmondja, hogy mennyire fitt ez a véletlenszerű találgatás. Ebben a példában ez nagyon egyszerű, mivel (x,y) párra van szükségünk maximális „z” értékkel, így valamilyen véletlenszerű találgatás esetén a „z” értékük szolgálhat a fitnesz pontszámaként.

fitness(x, y) = z-érték

Tehát, ha figyelembe vesszük a fitneszfüggvényt, minden ponthoz kikeressük a z-értéket, és az alábbiak szerint összefüggést kapunk közöttük.

fitness(-2,2, 2,3) › fitness(0,1, -2,4) › fitness(2,0, 1,4) › fitness(1,0) , 2.0)

lépés: Természetes szelekció

Most természetes kiválasztást hajtunk végre, ami azt jelenti, hogy véletlenszerűen választunk ki egy véletlenszerű találgatást, de a véletlenszerű kiválasztás a valószínűségi eloszláson alapul. Ez azt jelenti, hogy a magasabb fitneszértékkel rendelkezők nagyobb valószínűséggel válnak természetes úton kiválasztásra. A nagyon alacsony edzettségűek előfordulhat, hogy nem kerülnek kiválasztásra.

„A legalkalmasabbak túlélése” – Charles Darwin

Tegyük fel például, hogy a (-2,2, 2,3) és (0,1, -2,4) párok kerülnek kiválasztásra.

lépés: Crossover

A következő lépés a crossover, vagy egyszerűen csak azt mondjuk, hogy a két természetesen kiválasztott pár génje összekeveredik, és egy új hibrid párt alkot, azaz utódokat!

A fenti diagram szemlélteti, hogy ebben a példában hogyan történhet keresztezés. Mindkét szülő génjeit összekeveri, hogy egyetlen utódot képezzen.
A természetes szelekciót többször megismételjük, és keresztezzük egymást, hogy utódokat generáljunk.

lépés: Mutáció

Most ezeken az új utódokon „Mutációt” hajtunk végre, ami azt jelenti, hogy véletlenszerűen megváltoztatjuk a gének értékét. Bár a mutáció előfordulása a mutációs rátától függ, ha a mutációs ráta 100%, akkor az összes keletkezett utód mutációt szenved, ha a mutációs ráta 5%, akkor csak az utódok 5%-a mutációt szenved. .

A fenti ábra bemutatja, hogy az 'y' értéke véletlenszerűen -2,3-ra mutálódott.
A mutációt azért hajtják végre, hogy fenntartsák a sokféleséget a populációban, mert ha a populáció nagyjából változatlan marad, akkor t nem tudjuk annyit felfedezni a grafikont, amennyire szükségünk van, és ennek eredményeként nem érjük el a legmagasabb pontot.

Most, a mutáció alkalmazása után egy vadonatúj utódpopulációnk van, ami valószínűleg jobb, mint az előző populáció vagy mondhatni az előző generáció, mivel hajlamosak vagyunk jobb tagokat kiválasztani egy populációból (természetes szelekcióval), majd keverni. génjeiket (crossover révén).

Ezen a ponton elvetjük a régi generációt, és újra elkezdjük végrehajtani ugyanazokat a lépéseket az erőnléti számításból ezen az új generáción.

Ahogy ez a ciklus folytatódik, egy idő után minden tag ugyanahhoz a ponthoz konvergál, ami a megoldási tér legmagasabb pontja lesz, és ez a célunk, és ekkor leáll az algoritmus.

👇 Ajánlott videók ebben a témában 👇
Genetikus algoritmus: Bevezetés | A kódoló vonat
Tanulás: Genetikai algoritmusok | MIT OCW

Neurális hálózat

A neurális hálózat ötlete magából az emberi agyból származik. Ez a koncepció elmagyarázza, hogyan tanulunk meg dolgokat, amelyek alapján ugyanezt a koncepciót alkalmazhatjuk arra, hogy a számítógép megtanuljon dolgokat!

A mesterséges neurális hálózat (ANN) a biológiai neurális hálózaton alapul, bár nem teljesen ugyanaz, az ANN a tényleges biológiai neurális hálózat absztrakciójának tekinthető.

Idegsejt

A neurális hálózat egymáshoz kapcsolódó neuronokból áll. Tehát, mielőtt megvizsgálnánk a neurális hálózatot, vessünk egy pillantást egyetlen „neuronra”, amelyet az ANN-ban használunk. Ezt a mesterséges idegsejtet Perceptronnak neveztük el, mivel kissé eltérő módon valósulnak meg, de továbbra is nevezzük neuronnak, hogy a biológiai analógiát egyelőre megtartsuk.

Képzelje el ezt a neuront függvényként, amely egy csomó bemenetet (valós szám) vesz fel, és egyetlen kimenetet ad. Tehát most az a kérdés, hogy ez a függvény mit csinál a bemeneteivel a kimenet létrehozása érdekében.
A neuron fenti ábráján látható, hogy minden bemeneti érték egy élen keresztül kerül átadásra a neuronnak, és ennek az élnek van egy 'súly'hoz kapcsolódik.

azaz amikor az „x1” bemenet egy olyan élen keresztül jut el a neuronhoz, amelynek súlya „w1” a diagramon látható módon, az idegsejt értéke x1 * w1 lesz.

Ezután a különböző bemeneti élektől kapott összes ilyen érték összeadódik, majd egy 'elfogultság' nevű érték is kapcsolódik a neuronhoz, amelyet levonnak ebből az összegből, majd ezt az eredményt átadják a aktiválási funkciót

Mi ez az aktiválási funkció? Erre számos lehetőség kínálkozik, tegyük fel, hogy ez egy szigmoid függvény.

Ez a függvény bármilyen valós számot vesz, és 0 és 1 közé szorítja.

Tehát ennek az aktiválási függvénynek a kimenete a neuron kimenete. Ez a torzítás egy küszöbérték beállítására szolgál az aktiválási funkcióba való belépés előtt.

Rendben, egy neuron rendben van, de mi a haszna?
Például megvalósíthatja az AND Gatet egy neuronnal!

Mivel a kimenet a szigmoid függvény által adott érték, 0 és 1 között változhat. Tehát ha kimenet ‹ 0,5et kapunk, akkor a eredmény = 0
Hasonlóan, ha kimenet › 0,5, akkor az eredmény = 1

legyen w1 = 2,0, w2 = 2,0 és bias = 3,0

Most teszteljük ezt az összes bemenettel

ha x = 0, y = 0
kimenet
= szigmoid(x*w1 + y*w2 -bias)
= szigmoid(0*2 + 0* 2 -3)
= szigmoid(-3)
= 0,04743

kimenet ‹ 0,5, eredmény = 0

hax = 0, y = 1
kimenet
= szigmoid(x*w1 + y*w2 -bias)
= szigmoid(0*2 + 1* 2 -3)
= szigmoid(-1)
= 0,26894

kimenet ‹ 0,5, eredmény = 0

ha x = 1, y = 0
kimenet
= szigmoid(x*w1 + y*w2 -bias)
= szigmoid(1*2 + 0* 2 -3,5)
= szigmoid(-1)
= 0,26894

kimenet ‹ 0,5, eredmény = 0

ha x = 1, y = 1
kimenet
= szigmoid(x*w1 + y*w2 -bias)
= szigmoid(1*2 + 1* 2 -3,5)
= szigmoid(1,0)
= 0,73106

kimenet › 0,5, eredmény = 1

De hogyan találtunk ilyen súlyokat és elfogultságokat? Ez a „súlyok és torzítások beállítása”részahol a tanulásilogikara vezet. A bemeneti és kimeneti séma beállítása után nem kell mást tennünk, mint megtalálni a megfelelő értékeket ezeknek a súlyoknak és torzításoknak! Alapvetően ennyi a tanulás dióhéjban! Hamarosan visszatérünk a tanulási részhez.

Most valószínűleg úgy érzi: "ÉS a kapu unalmas... Nem csinálhatnánk még egy kicsit klassz dolgokat?"
Természetesen! Biztosan meg fogjuk tenni, de előtte hadd mondjam el, hogy egyetlen neuron nem elegendő mindenféle probléma megoldásához, mivel csak lineárisan elválasztható problémákat képesek megoldani.

Informálisan azt mondják: több idegsejtre van szüksége a klassz dolgokhoz!

Többrétegű mesterséges neurális hálózat

Többrétegű ANN a megmentésre!
Háromféle rétege van:

  1. Bemeneti réteg
  2. Rejtett réteg
  3. Kimeneti réteg

Több rejtett réteg is lehet, ez a felhasználási esettől függ. Az egyes rétegekben lévő neuronok száma is használati esetfüggő. Mindegyik neuron kapcsolódik a következő réteg összes neuronjához (bár részben összekapcsolhatók). Minden idegsejtnek van egy torzítási értéke, és minden kapcsolatnak súlya van hozzá. A bemenetektől a kimenetekig rétegenkénti feldolgozás folyamatát előrecsatolásnak nevezik.

Ennek megértéséhez képzeljük el ezt az egész neurális hálózatot egy függvénynek, amely bemeneteket és kimeneteket tud visszaadni.
Például megtervezheti az ANN-t úgy, hogy egy téglalap oldalait bemenetként és területként használja. a téglalap kimenete, de ezt egyedül is megtehetjük egyszerű logikával.
De akkor használjuk a neurális hálózatot, amikor egy egyenes logikát levezetni nem olyan egyszerű. Tekintsük egy olyan számítógépes program írásának problémáját, amely leképezi a kézzel írt számjegyeket, és kitalálja, melyik számjegyről van szó. Ebben az esetben a bemeneti neuronok minden pixelből állnak, a kimenetek pedig 10 neuronból állnak az összes számjegyhez, és kísérletezhet a rejtett rétegekkel.

Oké, ez a bemeneti és kimeneti rész rendben van, de mi a helyzet a súlyokkal és a torzításokkal? Ez az, ami lehetővé teszi ezeket a kimeneteket, megfelelő súlyok és torzítások nélkül a neurális hálózat csak egy hülyeség!

Szóval, hogyan tanul egy neurális hálózat?

Ennek többféle megközelítése létezik. Az egyik az, hogy az ANN-t véletlenszerű súlyozással inicializáljuk, és valamilyen címkézett adatkészlettel betanítjuk, és a hibák alapján folyamatosan módosítjuk súlyait és torzításait visszaterjesztéssel, amely a gradiens süllyedésnek nevezett koncepciót használja. Ezt a fajta tanulást nevezik Felügyelt tanulásnak.

Használhatjuk a Megerősítő tanulást is. Itt az ügynökök a véletlenszerűen inicializált állapotában kezdenek el teljesíteni, és akcióik eredményei alapján folyamatosan alkalmazkodnak. Alkalmazhatjuk a genetikai algoritmust, hogy elérjük ezt a fajta viselkedést, lássuk ezt a következő részben.

👇 Ajánlott videó ebben a témában 👇
De mi az a neurális hálózat? | 3kék1barna

Neuroevolúció

A neurális hálózatok fejlesztése genetikai algoritmus segítségével „neuroevolúció”.
Ennek ellenére a „neuroevolúció” kifejezésnek van értelme, igaz?

Neurális hálózat + evolúció = Neuroevolúció

Először azonosítjuk a problémafelvetést, és megtervezzük a megfelelő neurális hálózati architektúrát. De ahhoz, hogy megfelelően működjön, meg kell találnunk a megfelelő súlyokat és torzításokat, így most a GA jön a képbe.

Több ANN-t generálunk, amelyeket véletlenszerű súllyal inicializálunk a kapcsolatokhoz, így az ANN-ok véletlen sokaságát. Tehát itt az összes véletlenszerűen generált súlyozás csak néhány hülye ANN-t eredményezne, de mivel ez véletlenszerű, egyes ANN-ok kevésbé hülyék, mások pedig hülyébbek. Tudjuk, hogy ennek a neurális hálózatnak mit kell tennie, így teljesítménye alapján ki tudjuk számítani a alkalmasságát. Itt a súlyok és a torzítások az ANN génjei. A fitnesz értékek és a valószínűségi eloszlás alapján természetes szelekció fog bekövetkezni. A crossover esetén a természetesen kiválasztott ANN súlyozása és torzítása keveredne egy hibrid ANN létrehozásához. A mutáció során bizonyos súlyok és torzítások véletlenszerűen módosulnak kissé. A természetes szelekció, keresztezések és mutációk révén, ahogy haladunk előre az új generációkkal, az ANN-ok javulni kezdenek a fitnesz funkció által vezérelt irányba.

Ez még mindig egy keresési algoritmus. Korábban, amikor a legjobb (x, y)pontot próbáltuk megtalálni a GA segítségével, valójában az X-tengely és az Y- kétdimenziós terét kutattuk. tengely. Hasonlóan itt is tételezzünk fel egy dimenziót az ANN minden kapcsolatának súlyához és az egyes neuronok torzításaihoz. Ezt vizuálisan nehéz elképzelni, de alapvetően az összes súly és torzítás dimenzióterét vizsgáljuk, és megpróbáljuk megtalálni a legjobb súlyokat és torzítási vektor abban a térben.

Ahogy ezt a ciklust futva tartjuk, végül az ANN-nak úgy kell viselkednie, ahogy azt vártuk.

👇 Ajánlott videó ebben a témában 👇
Bevezetés a neuroevolúcióba | A kódoló vonat

Egy neurális hálózat huncutsága

Engem ez a „Flappy Bird with Neuroevolution” kódolási kihívás ihletett, ahol a neuroevolúció segítségével lehetővé teszik, hogy a számítógép megtanulja önállóan játszani a játékot. "nézd meg projektjük élő verzióját".

Szóval, szerettem volna egy hasonló projektet csinálni egy másik játékon, ezért elkezdtem keresni egy egyszerű játékot, ahol alkalmazni tudnám ezt az algoritmust.

Némi kutatás után úgy döntöttem, elkészítem a saját játékomat 😛, majd ezt az algoritmust használom erre.

Ennek a projektnek most 2 része volt:

  1. Tervezze meg és valósítsa meg a játékot
  2. Alkalmazzon rá neuroevolúciós algoritmust

Most, a játék megtervezésekor… röviden, kitaláltam ezt a játékot, melynek neve ’menekülési ugrás’ (egy barátom segített a névvel kapcsolatban 🙃 )

Itt a nyílbillentyűkkel irányíthatod azt a piros golyót, és szöknöd kell át vagyugornod a csövek közötti téren (fekete sávok), mielőtt megszorítja téged (a piros golyó), ekkor mindkét cső bezárul, kezdetben ismeretlen, ezért gyorsan kell ítéletet hoznod, amikor megjelennek. Ha asztali számítógépet használ, azonnal kipróbálhatja ezt a játékot erről a linkről. Próbáld ki, és nézd meg, mennyit szerezhetsz, később pedig nézd meg, mennyit ért el az AI önmagában!

Ok, tudom, hogy a játék nem olyan tisztességes kinézetű, bár szerintem elég jó ehhez a kísérlethez, nem? nem túl könnyű és nem túl nehéz, szerintem korrekt játék.

De az élet soha nem úgy ment, ahogy én érzek 😅, mégis elmentem vele, hogy lássam, hova vezet.

A neuroevolúcióhoz több labdával indítjuk el a játékot, mindegyiknek saját ANN-ja van (amint az a fenti ábrán látható), ami meghozza helyettük a döntést. Az ANN minden egyes keretnél bemenetet vesz, és az ANN kimenet alapján intézkedik.

A fenti függvény a „Ball” osztályból származik. Megmutatja, hogyan továbbítja a bemeneteket az ANN-nak, és hogyan használja az ANN kimeneteit annak eldöntésére, hogy ugorjon vagy mozog.

Hagyjuk az összes labdát együtt játszani ugyanabban a játékban. A labda túlélése másodpercben a játékban az erőnlétüknek tekinthető. Egy labda meghal, ha beszorul a csövek közé. Amikor az összes labda meghal, minden labdára megvan a fitneszpontszámunk, amely alapján természetes szelekciót, crossovert, mutációt és akkor megjelenik az új generáció.

Szóval, így néz ki, most, ha láttad, hogyan tanult meg az a "flappy madár" egyedül játszani ezzel az algoritmussal, el tudod képzelni, hogyan kellett volna ennek a játéknak mennie. Meg kellett volna tanulnia úgy játszani, mint általában, valami hasonlót ahhoz, amit az első bemutatott animáción játszottam.

Szóval néhány generáción keresztül futtattam, és meglepett, hogy mit csinál a játékkal, olyan érzésem volt, mintha a számítógép kinevetné a játékomat 😂

Tehát ez az algoritmus talált egy helyet, ahol rendszeres időközönként ugrálhat, és legyőzheti a játékot! Azta! Bár kezdetben kissé szomorú voltam, amikor rájöttem, hogy a játékomat túl könnyű játszani, aztán rájöttem, hogy egy AI mondta ezt nekem, rájöttem, hogy véletlenül egy mesterséges intelligencia segítségével kiskaput kerestem egy játékban. , jobb érzés volt így.

Bár soha nem javítottam ki ezt a kiskaput 😜, valószínűleg csak így fogom tartani a kódot.

Ez az!

Ha látni szeretné ezt a szimulációt, és játszani szeretne vele, Nézze meg ezt
Ha meg szeretné tekinteni ezt a kódot, itt található egy link a GitHub-tárhelyére