Miten kouluttaa tekoäly ymmärtämään luonnollista kieltä? – osa 4

Me Onervalla kehitämme Onerva Bottia eli keskustelevaa tekoälyä vanhushoivaan. Tässä blogisarjassa on aiemmin käsitelty asiaa yleisemmällä tasolla ja käymällä tarvittavien osien toimintaperiaatteita läpi (osa 2 ja osa 3). Tällä kertaa keskustelemme siitä, miksi tekoäly tarvitsee paljon laadukkaita koulutusesimerkkejä, miksi koulutusesimerkkien saatavuus on lähes aina ongelma ja kuinka voimme osittain ratkaista saatavuusongelmaa ”rikastamalla” koulutusaineistoa.

Aloitetaan esimerkillä.

Ihan hyvin
Hyvin menee
Ihan hyvin menee
Menee ihan hyvin
Ihan mukavasti
Mukavasti menee
Ihan mukavasti menee
Menee ihan mukavasti
Hyvin sujuu
Ihan hyvin sujuu
Sujuu oikein hyvin
No terve, kyllähän tässä ihan kohtuu hyvin sujuu

Käyttämällä vain muutamaa eri sanaa voimme vasta kysymykseen ”mites menee?” yli kymmenellä eri tapaa. Mitä pitemmäksi vastaus venyy sitä enemmän vaihtoehtoja kertyy. Jo alkutervehdyksiä kertyy helposti kymmeniä erilaisia ”huomenta”, ”päivää”, ”moi”, ”hei”, ”terve”, ”no terve”… Kun alkutervehdykset yhdistetään eri vaihtoehtoihin lausauhduksesta ”hyvin menee”, esimerkiksi ”mukavasti sujuu”, ”mainiosti menee”, ”hyvin kulkee”, …, niin saadaan satoja ellei tuhansia vaihtoehtoja. Ja kun tähän lisätään vielä pikku sanoja ”ihan”, ”aika”, ”oikein”, ”kyllähän”, ”tässä”… räjähtää yhdistelmien määrä miljooniin.

Ja yllä oleva esimerkki oli lyhyt, suora vastaus kysymykseen. Vastaushan voi olla muutama lause tai pitkäkin selitys, joka sisältää tietoa vaikkapa kivusta tai huolista. Pitkät selitykset nostavat tietysti erilaisten mahdollisten lauseiden yhdistelmien määrän tähtitieteellisiin lukemiin. Neuroverkon pitäisi oppia ne kaikki.

Sitten tarvitaan tietysti myös erilaisia loogisia rakenteita. Yksinkertaisin looginen muutos on lienee ”ei” sanan lisääminen eli negaatio. Neuroverkon näkökulmasta ”ei” lisää hieman vaihtoehtojen määrää, mutta ennen kaikkea se lisää päättelyn monimutkaisuutta. Eli ”hyvää” on positiivinen, mutta ”ei hyvää” on negatiivinen. Loogisuuden kannalta vielä hankalampi on ”ei tässä nyt niin huonosti mene, (pitkä selitys jostain aiheesta) tai no, eihän tässä hyvinkään mene”. Tässä lauseessa ”tai no” kumoaa kaiken aiemman eli sillä on pitkä ”looginen kantama”. Siitä kuinka neuroverkko oppii ymmärtämään tällaisia loogisia rakenteita, keskusteltiin tämän blogisarjan edellisessä osassa. Mutta jos kerta neuroverkko voi oppia ymmärtämään näitä lauseita, niin missä on ongelma? Ei kun treenaamaan? Miksi kouluttaminen on työlästä?

Ongelmana on että neuroverkko oppii juuri sitä mitä sille opetetaan.

Ikävänä esimerkkinä maailmalta löytyy vaikkapa Microsoftin Tay-tekoäly, joka oppi hetkessä Twitteristä käyttäytymään rasistisesti ja seksistisesti. Myös useat kasvontunnistusta tekevät keinoälyt toimivat hyvin valkoisille miehille, mutta huonosti tummille naisille. Miksi? Ovatko tekoälyt sisäsyntyisesti ilkeitä rasisteja? Ei, tekoäly ainostaan oppi koulutusaineistonsa mukaisesti. Twitterissä Tay ajautui ”huonoon seuraan” ja kasvontunnistuksia koulutettaessa valkoisten miesten dataa oli helpoiten saatavilla. Saatamme siis vahingossa siirtää tekoälylle ihmisten ennakkoluuloja tai datan vajaavaisuuksia, jos emme huolehdi koulutusaineiston laadusta.

Jos neuroverkko ei saa riittävän kattavaa koulutusaineistoa, se oppii päättelemään väärin.

Jos palaamme lauseiden pariin, niin ennen koulutusta kaikki sanat ovat neuroverkolle merkityksettömiä. Jos liian pienessä koulutusaineistossa on sattumalta sana ”aamu” usein positiivisten lausahdusten yhteydessä, yhdistää neuroverkko koulutuksensa aikana sanan ”aamu” positiiviseksi asiaksi, vaikka kielellisesti sanalla ei sitä merkitystä ole.

(Tosin kielikuvissa ”aamu” saattaa usein esiintyä positiivisenä asiana, joten sinäänsä huono esimerkki.)

Isompi ongelma on se, että yleensä eri tyyppisiä vastauksia on hyvin eri määrä ja tiettyä vastaustyyppiä esiintyy hyvin paljon enemmän kuin muita. Esimerkiksi ”ihan hyvin” -tyyppisiä vastauksia esiintyy selkeästi enemmän kuin ”ei tässä nyt niin huonosti mene, tai no, eihän tässä hyvin mene” -tyyppisiä vastauksia. Tämä on ongelma, sillä neuroverkko tarvitsisi kattavan ja tasapainoisen otoksen eri vastaustyypeistä. Itseasiassa neuroverkko tarvitsisi runsaasti juuri jälkimmäisen kaltaisia esimerkkejä, koska ne ovat loogisesti vaikeampia.

Mikä avuksi? Mistä saada tasapainoista valmista dataa? Luultavasti ei mistään.

Vähintäänkin data pitää analysoida ja eri vastaustyyppejä pitää tasapainottaa tavalla tai toisella. Mutta usein tämäkään ei riitä.

Osittain ongelmaan auttaa sanojen upotus -mentelmä, jossa käytetään hyväksi ohjaamatonta oppimista valtavalla datamassalla. Tästä keskusteltiin blogisarjan kakkososassa. Tällöin saadaan samankaltaisille sanoille samantyyppiset kontekstit (upotusvektorit), jotka toivottavasti tuottavat oikeanlaisia tulkintoja myös sanoille, joita omassa koulutusdatassamme ei ilmene. Tämä ei ole kuitenkaan täydellinen ratkaisu vaan ainoastaan pieni helpotus. Ja se auttaa vain sanojen osalta. Lauseet ja niiden logiikka on sen ulottumattomissa. Lisäksi useat upotukset luokittelevat ”hyvän” ja ”huonon” varsin lähelle toisiaan, koska niitä käytetään samankaltaisten sanojen kanssa, esimerkiksi ”ruoka oli hyvää” tai ”ruoka oli huonoa”. Lauseen merkityksen kannalta ne ovat vastakohtia eli ”positiivinen kommentti = kyllä” ja ”positiivinen kommentti = ei”.

No, onko ainoa vaihtoehto sitten kerätä 10 000 tai 100 000 tasapainoisesti jakautunutta vastausvaihtoehtoa? Ei toki.

Voimme käyttää hyväksi sanojen upotuksen ideaa, mutta tehdä sitä korkeammalla tasolla. Voimme käyttää synonyymejä ja antonyymejä sekä saman kategorian sanoja, mutta myös usemman sanan ilmaisuja. Voimme määritellä vaihtoehtoisia lisäsanoja ja ilmaisuja sekä poistaa ylimääräisiä sanoja. Voimme lisätä muista lähteistä otettua tekstiä edustamaan kysymyksen kannalta merkityksetöntä tekstiä. Voimme luoda uusia esimerkkejä aliedustettuihin vastaustyyppeihin ottamalla mallia yliedustettujen vastaustyyppien esimerkkeistä, mutta vaihtamalla niiden logiikka haluttuun vastaustyyppiin.

Eli itseasiassa käännämme alkuperäisen ongelman tavallaan eduksi. Luomme malliesimerkistä tuhansia tai miljoonia esimerkkejä yksinkertaisin toimenpitein.

Kuinka tämä toteutetaan käytännössä? Otetaan esimerkiksi ”hyvin menee”. Positiivinen vastaus, sille määrittelimme jo alussa useita vaihtoehtoja. Valitaan satunnaisesti joku sen vaihtoehto, vaikka ”sujuu mainioisti”. Lisätään satunnainen alkutervehdys ”no moi” ja muutama täytesana ”no moi, tänään sujuu oikein mainiosti”. Eli ”hyvin menee” oli runko, jonka ympärille voimme rakentaa helposti kymmeniä tuhansia lauseita. Vastaavasti voimme menetellä ”ei hyvin mene” ja ”… tai no, …” tyyppisille lauseille. Erityisesti luomme aliedustettuja ”… tai no, …” -tyyppisiä lauseita yhdistelemällä ”hyvin menee” ja ”ei hyvin mene” -tyyppejä.

Käytämme seuraavaa prosessia. Keräämme aitoja esimerkkejä. Analysoimme ne ja muodostamme mallilauseita (eli lauserunkoja). Luomme koneellisesti näiden pohjalta satunnaisesti satoja tuhansia esimerkkejä, joissa eri loogiset rakenteet ja vastaustyypit ovat tasapainossa. Lisäksi sopiviin mallilauseisiin lisätään wikipediasta tai vastaavasta lähteestä satunnaisia lauseita merkityksettömäksi tekstiksi.

Nyt voimme käyttää kymmeniä tai satoja tuhansia koneellisesti luotuja lauseita koulutuksessa ja testata neuroverkon toimivuutta aidoilla alkuperäisillä esimerkeillä. Kun aitoja esimerkkejä saadaan lisää, sieltä tunnistetaan uusia lauserunkoja – varsinkin niitä, joissa neuroverkko oli epävarma tai jotka luokiteltiin väärin. Tämän jälkeen voidaan heti luoda riittävä määrä esimerkkejä, jotta päästä kouluttamaan botille myös nämä uudet tuntemattomat lausetyypit Onko täydellinen ratkaisu? Ei. Onko riittävän hyvä? Todennäköisesti kyllä useimmissa tapauksissa.

Käsin lauseiden rikastaminen isossa mittakaavassa on tietysti varsin työlästä, mutta kehitämme käyttäjäystävällistä työkalua, jolla kuka tahansa pääsee rikastamaan lausedataa.

Eikö tätä voisi tehdä täysin koneellisesti? Emmekö voi käyttää samoja rikastamismenetelmiä (data augmentation) kuin äänelle tai kuville? Valitettavasti kieli on hyvin eri tyyppistä dataa kuin ääni tai kuva, jotka ovat ”matalan tason tiivistämätöntä tietoa todellisuudesta”. Ajattele vaikka valokuvaa pojasta. Kuvan tieto on värejä ja kirkkauksia kuvan eri pisteissä. Kieli taas on varsin korkean tason tietoa, sillä esimerkiksi sana ”poika” sisältää jo hyvin laajan tietokokonaisuuden: ihminen, lapsi, miespuolinen, nisäkäs, elollinen, todennäköisesti osaa juosta ja puhua, todennäköisesti kaksi jalkaa ja kättä sekä pää, …

Toisaalta samalla on hävitetty valtava määrä informaatiota. Kuvasta voi helposti tunnistaa kuka kuvassa on, mutta lauseesta ”kuvassa on poika” ei.

Lauseet ovat siis hyvin tiivistettyä tietoa, johon on kerätty asian kannalta oleellinen informaatio todellisuudesta ja jätetty valtava määrä informaatiota huomiotta.

Lauseen korvaaminen toisella samaa tarkoittavalla lauseella on varsin hankalaa ja yleisessä tapauksessa tarvitaan kielen varsin korkean tason ymmärtämistä – ja joskus jopa kontekstin ymmärtämistä – jos halutaan korvata lause toisella. Lisäksi eri toimialoilla saattaa olla omia tapoja ilmaista asioita. ”Lauri sukelsi” tarkoittaa varsin eri asiaa rannalla kuin jalkapallokentällä. Tämä aiheuttaa oman ongelmansa lauseiden korvaamiseen toisilla ja niiden siirtämisessä toimialasta toiseen.

Datan määrä ei siis ole ainoa asia mikä merkitsee koneoppimisessa. Vaikka koneoppiminen on varsin anteeksiantavaa datan laadun suhteen, laaduton data tuottaa edelleen laadutonta lopputulosta. Siksi laadun varmistaminen on tehtävä ennen opetuksen aloitusta ja huomioitava myös opetuksen ja testauksen aikana.

Datan laatua ja määrää voidaan lisätä rikastamalla dataa. Kielidatan osalta rikastaminen on varsin työlästä, muttei mahdotonta.

Tärkeintä on tarttua toimeen ja alkaa kerätä dataa mahdollisimman aikaisessa vaiheessa. Hyvillä työkaluilla datan kerääminen ja rikastaminen sujuu nopeammin.

Seuraavassa osassa rakennamme koodiesimerkein yksinkertaisen pitkän työmuistin neuroverkon, joka ymmärtää selkeää suomea.

Lue myös tämän blogisarjan muut osat: Osa 1, Osa 2, Osa 3