Vahvistusoppiminen kerailla + OpenAI: Perusteet

Vahvistusoppiminen on monien mainitsema yhtenä yhdyskäytäväteknologiasta / konseptista, jotka ovat syntyneet koneoppimisen teoreettisista opinnoista. Käymme läpi erittäin nopean yleiskatsauksen vahvistusoppimisesta ennen sukellusta koodiin.

Nopea tausta

Vahvistusoppiminen (RL) on yleinen kattotermi jokaiselle algoritmille, joka ei vaadi nimenomaisia ​​datapareja ja niitä vastaavia haluttuja merkintöjä, kuten perinteisessä ohjatussa oppimisessa tapahtuu, mutta vaatii jonkin verran numeerista osoitusta siitä, kuinka näyte on. Tämä laatu näytteen ”hyvyydellä” ei ole merkitystä absoluuttisessa merkityksessä. Voit kuvitella tämän yleisesti tuloksena videopelissä. Jos näytöllä on pistemäärä “218”, jolla ei ole todennäköisesti mitään merkitystä sinulle, pelaajalle, paitsi jos olet tietoinen siitä, kuinka vaikeaa tai helppoa on ansaita piste ja mistä pisteestä aloitat. Ja se on pohjimmiltaan sen taustan laajuutta, johon me kaivaamme: RL: stä käydään tulevaisuudessa syvällisempiä keskusteluja, mutta koodi, jonka lähetämme tässä viestissä, on hyvin perustana oleva esimerkki RL: stä, joten se ei sisällä mitään edelleen sekaantuminen aihepiireihin.

Keras toteaa

Tervetuloa kaikille, jotka ovat vasta aloittamassa AI / ML-ohjelmoinnissa! Kenttä on kasvanut niin paljon viime vuosina, että on melko ylivoimaista hypätä juuri nyt. Mutta on vielä runsaasti aikaa osallistua ja oppia tällä massiivisella kentällä! Tämän mukaisesti Keras on kirjasto, jota käytän ensisijaisesti tuleviin opetusohjelmiini, myös tämä. Keras on pääosin käärekirjasto Tensorflowille ja Theanolle. Sen käyttöliittymä on melko samanlainen kuin tflearnin paljastama, mutta on hiukan yleisempi sovellettaessa Theanoon taustana. Huomaa kuitenkin! Theanon mitat eroavat hiukan Tensorflowin mitoista. Siksi suosittelen, että säädät Kerasiasi käyttämään TF: tä sen taustana, jotta vältetään turhautumiset, joiden mitat menevät eteenpäin (sen tulisi olla oletusasetus asennuksen yhteydessä, jos TF on jo asennettu).

Voit myös tehdä tämän yhtä helposti TF: llä, mutta Keras antaa meille mukavan joustavuuden aloittaessamme sen, että meidän ei tarvitse seurata mittoja konvoluutioiden ja kaiken sen läpi. Joka tapauksessa, tarpeeksi sanoja: aika siirtyä koodiin!

Koodi

Tutkimme täällä alkeellisinta OpenAI-ympäristöä: CartPole! Viimeisenä pikahuomautuksena löydät ohjeet OpenAI-kuntosalin paketin asentamiseen täältä: https://gym.openai.com/docs. Vain “sudo pip install gym” -ohjelman ajamisen pitäisi toimia useimmilla alustoilla.

CartPole-ympäristössä on hyvin yksinkertainen lähtökohta: tasapainota kärryn napa.

Tiedonkeruu

Kaikkien koneoppimisongelmien ensimmäinen osa on tietojen kerääminen, eikä tämä eroa. Onneksi OpenAI: n kuntosaliympäristö tarjoaa erittäin suoraviivaisen tavan kerätä tietoja: voimme käytännössä vain suorittaa simulaation läpi useita kertoja ja suorittaa satunnaisia ​​toimenpiteitä joka kerta. OpenAI Gym -ympäristöt on rakennettu kahteen pääosaan: havainto- ja toimintatilaan. Havaitsemme entisen ympäristöstä ja käytämme sen selvittämiseksi, kuinka se voidaan parhaiten päivittää toiminnon avulla, ts. Navan nykytilan perusteella (havainto), määritetäänkö siirtääkö kärry vasemmalle vai oikealle (toiminta).

Seurauksena on, että meidän on tehtävä toimenpide, joka sopii toimintatilan sallittujen toimien alaan, joka on tässä tapauksessa koko 2 (vasen tai oikea). Otamme, että lähtötila on yksi kuuma koodattu, syynä siihen, että haluamme, että hermoverkko ennustaa lopulta todennäköisyyden siirtyä vasemmalle ja oikealle, ottaen huomioon ympäristön nykyinen tila. Tässä tapauksessa voisimme päästä eroon siitä, että ulostulona olisi vain yksi 1x1-kelluva matriisi (ts. Skalaari) ja pyöristää se lopputuloksemme saavuttamiseksi, mutta yhden kuuman koodauksen käytäntöä voidaan soveltaa laajemmin.

Joten toimintojen ja vastaavien havaintojen keräämiseksi ensimmäinen ajatus voi olla yksinkertaisesti:

_ _ alueella (10000):
    havainto = env.reset ()
    koulutus_näyteX, koulutus_näyteY = [], []
    askel alueella (sim_steps):
        action = np.random.randint (0, 2)
        one_hot_action = np.zeros (2)
        one_hot_action [action] = 1
        training_sampleX.append (havainto)
        training_sampleY.append (one_hot_action)
        
        havainto, palkinto, tehty, _ = env.step (toiminta)
        jos valmis:
            tauko
    trainingX + = training_sampleX
    koulutusY + = koulutus_näyte

Jos kuitenkin harjoittelemme tätä, lopullinen ennustaja ei todennäköisesti tee parempaa kuin satunnainen mahdollisuus. Loppujen lopuksi ”roskat sisään, roskat ulos”: me emme tekisi muuta kuin syöttäisimme hermoverkkoon sekä hyviä että pahoja näytteitä ja odotamme sen oppivan yksinomaan hyvästä. Jos otamme askeleen taaksepäin, tämä on kuitenkin täysin epätodennäköistä, koska yksittäinen otos ei ole erotettavissa muista, edes vertaamalla hyvien kokeiden ja huonojen kokeiden tuloksia.

Joten sen sijaan tarkastelemme vain näytteitä, jotka johtavat korkeiden pisteiden saaneisiin kokeisiin. Toisin sanoen haluamme suodattaa näytteet sallimaan vain sellaiset näytteet, jotka lopulta johtavat korkeisiin tuloksiin kokeissaan. Tässä tapauksessa valitsimme mielivaltaisesti 50: n "vähimmäisrajaksi" pidettäväksi "hyvänä kokeiluna" ja valitsemme vain nämä otokset:

def kokoelmatiedot (env):
    min_score = 50
    sim_steps = 500
    koulutusX, koulutusY = [], []
    tulokset = []
    _ _ alueella (10000):
        havainto = env.reset ()
        pisteet = 0
        koulutus_näyteX, koulutus_näyteY = [], []
        askel alueella (sim_steps):
            action = np.random.randint (0, 2)
            one_hot_action = np.zeros (2)
            one_hot_action [action] = 1
            training_sampleX.append (havainto)
            training_sampleY.append (one_hot_action)
            
            havainto, palkinto, tehty, _ = env.step (toiminta)
            pisteet + = palkinto
            jos valmis:
                tauko
        jos pistemäärä> min_score:
            scores.append (pisteet)
            trainingX + = training_sampleX
            koulutusY + = koulutus_näyte
    trainingX, trainingY = np.array (trainingX), np.array (trainingY)
    tulosta ("Keskiarvo: {}". muoto (np.mean (pisteet)))
    print ("Median: {}". muoto (np.median (pisteet)))
    paluu koulutusX, koulutusY

Malli määritelmä

Nyt kun meillä on tietoja, meidän on määriteltävä malli. Ennen kuin teet mitään koneoppimisongelmia, on aina syytä palata taaksepäin miettiä, mitä mallinnamme, erityisesti mitä odotetut panokset ja toivotut tulokset ovat. Tapauksessamme tulemme vastaanottamaan ympäristön nykyisen tilan (ts. “Havainnot” aikaisemmasta) ja haluamme ennustaa liikkumisen todennäköisyydet kumpaankin suuntaan. Tästä voidaan helposti selvittää, kumpi näistä kahdesta otetaan, ottamalla max arg.

Tässä käytetty malli on hyvin yksinkertainen: useita täysin kytkettyjä kerroksia (mm. Tiheät kerrokset Kerassa). Nämä ovat usein viimeisiä kerroksia, joita käytetään syvissä CNN: issä (Convolution Neural Networks), koska ne yhdistävät kaikki ominaisuuskartat tai syöttökerrokset lopulliseen skalaariarvoon. Täysin kytketyt kerrokset muodostavat olennaisesti hermoverkkojen selkärangan, ja niiden avulla ne pystyvät kartoittamaan tehokkaasti korkean ulottuvuuden toimintoja, jättäen huomioimatta kaikki nykyaikaiset parannukset konvoluutioiden, LSTM: ien, keskeytysten jne. Kanssa.

Ainoa näistä parannuksista, joka on tässä yhteydessä merkityksellinen, on keskeyttäminen, koska se auttaa varmistamaan, että emme ole liian suuria harjoitustietoihin. Joten oleellisesti voileipämme Dropout-kerroksen jokaisen täysin kytketyn kartoituksen välillä varmistaaksemme, että kukaan kartoituskerros ei ole riippuvainen pienestä yhteyksien alajoukosta, jotka näkyvät erityisesti harjoitustiedoissa.

Lopuksi meidän on määritettävä häviöfunktio, jota vastaan ​​harjoitetaan. Koska koodasimme lähtötilan yhtenä kuumana 2D-vektorina, luonnollisesta valinnasta tulee kategorinen ristin entropia, koska haluamme tunnistaa tuloksen joko vasemmalle ([1,0]) tai oikealle ([0,1]). En käsittele perusteellisesti sitä, mitä ristien entropia tarkoittaa, mutta se on erittäin hyödyllinen tehtävä ymmärtää, kun otetaan huomioon sen esiintyvyys tällaisissa ongelmissa. Korkealta tasolta ristin entropia on, kun otetaan huomioon kaksi jakaumaa (todellinen taustalla oleva jakauma ja sen mallimme), mitta siitä, kuinka paljon tietoa me tarvitsemme välittääksemme jotain, joka on saatu mallijakauman todellisesta jakaumasta.

Siksi määrittelemme mallin seuraavasti:

alkaen keras.models tuo Sequential
alkaen keras.layers tuo Dense, Dropout
def luoda_malli ():
    malli = peräkkäinen ()
    model.add (Tiheä (128, input_shape = (4,), aktivointi = "relu"))
    model.add (poisto (0,6))
    
    model.add (tiheä (256, aktivointi = "relu"))
    model.add (poisto (0,6))
    
    model.add (tiheä (512, aktivointi = "relu"))
    model.add (poisto (0,6))
    
    model.add (tiheä (256, aktivointi = "relu"))
    model.add (poisto (0,6))
    
    model.add (tiheä (128, aktivointi = "relu"))
    model.add (poisto (0,6))
    model.add (Tiheä (2, aktivointi = "softmax"))
    
    model.compile (
        tappio = "categorical_crossentropy",
        Optimizer = "Adam",
        metrics = [ "tarkkuus"])
    paluu malli

Muutama hienovaraisempi malli teknisistä kohdista: Jokaisessa mallin kerroksessa on ReLU-aktivoinnit, jotta malli voi harjoitella nopeammin kuin kyllästyvillä aktivointitoiminnoilla, kuten tanh ja sigmoid. Malli kouluttaa todennäköisesti myös näissä tapauksissa, mutta lähentyminen vie paljon kauemmin kuin käyttämällä ReLU-aktivointia.

ennustus

Sieltä voimme vain hankkia harjoitustietomme, kouluttaa mallin ja iteroida useiden kokeiden avulla nähdäksemme kuinka hyvin mallimme toimii!

Tuo kuntosali
Tuo numerot kuin np
tietojen tuonnista kerätä tietoja
mallin tuonnista create_model
def ennustaa ():
    env = gym.make ("CartPole-v0")
    koulutusX, koulutusY = kerätä_tietoja (env)
    malli = luo_malli ()
    malli.fit (koulutusX, koulutusY, aikakaudet = 5)
    
    tulokset = []
    lukumäärät = 50
    sim_steps = 500
    kokeilualueelle (num_kokeet):
        havainto = env.reset ()
        pisteet = 0
        askel alueella (sim_steps):
            toiminta = np.argmax (malli.ennustaa (
                observation.reshape (1,4)))
            havainto, palkinto, tehty, _ = env.step (toiminta)
            pisteet + = palkinto
            jos valmis:
                tauko
        scores.append (pisteet)
    
    Tulosta (np.mean (tulokset))

Täysi koodi

Siinä vaihe vaiheelta tässä on OpenAI Cartpole Keras -sovelluksen täydellinen lähdekoodi!

Pidä silmällä seuraava Keras + OpenAI -opetus!

Kommentoi ja napsauta sitä alla näyttääksesi tuen!