Autoencoders zijn NN's die de eigen input proberen te reproduceren maar dan meestal via een smalle laag in het NN zodat er een soort 'compressie' plaatsvindt. Ik wil eens kijken of dat een rol kan spelen in NLP (natural language processing) met letters. Ik voer een heleboel woorden in een kleine, eenlaags NN en kijk of deze weer gereproduceerd kunnen worden. De maximale woordlengte is 15 karakters.
Met 1 laag van 50 'neuronen' haal ik een validation loss van 0.1838 na ongeveer 8 epochs. Het is grappig om te zien hoe goed die dan woorden kan terugfilmen:
Do Do
NOT MNS
count boumt
on on
the shd
rating r`thne
and `oc
Let op dat bijvoorbeeld 'NOT' en 'MNS' wel verschillen maar dat alle letters dicht bij elkaar in het alfabet (de ascii code) liggen.
Met een dubbele laag van 2x50 komt het NN maar tot 0.1839. Niet veel verschil maar toch een duidelijke richting lijkt het.
Als ik een loss functie definieer met mse (mean squared error - hij stond op 'binary_crossentropy' kan ook niet goed zijn achteraf gezien) duikt de validation loss naar beneden van .1838 naar 0.0079. Als ik vervolgens bij de printout van de woorden niet met 'int' afrond maar met 'round' krijg ik een uiterst betrouwbaar resultaat. Maar een enkel foutje hier en daar:
turns turns
out, out,
unfortunately unfortunateky
yes. yes.
Jackson Jackson
needs needs
to to
Lisa Lisa
to to
help help
him him
assassinate assassinate
the the
Director Director
of of
Homeland Homeland
Security Security
by by
moving moving
Het blijkt dus in ieder geval mogelijk om in 1 layer met 100 neuronen 611.526 verschillende woorden!!! met een behoorlijke betrouwbaarheid vast te leggen. Natuurlijk moet hierbij wel worden bedacht dat de validatieset voor een belangrijk deel dezelfde woorden zal bevatten als de trainset.
Nu eens kijken wat het resultaat is bij een kleinere layer van 50.
Ofschoon de validation loss gelijk is (0.0079) is het resultaat beduidend slechter:
turns tvrns
out, out1
unfortunately vnfprtun`tcl{
yes. zds3
Jackson Kackson
needs neecs
to to
Lisa Mis`
to to
help help
him him
Vreemd. Niet dat het resultaat slechter is maar wel dat de validation loss gelijk blijft. Snap ik even niet.
Ik schrijf een functietje om gewoon wat woorden te testen. Het NN blijkt ook heel goed Nederlands te kunnen hoewel ik denk dat er alleen Engelstalige woorden in de trainset zitten. Hier wat voorbeelden:
>>> test("apple")
apple
>>> test("olifant")
olifant
>>> test("banaan")
banaan
>>> test("citruspers")
citrvspers
>>> test("equivalent")
equivalent
>>> test("superdouper"
... )
superdouper
>>> test("een en twee")
den#dn#twee
Grappig, niet waar?
Maar ook :
>>> test("100")
100
>>> test("101")
101
>>> test("104")
104
>>> test("10194")
10183
>>> test("4579474874874c")
8479573764763c☺
>>> test("4579474874874C")
7479573775763C☺
>>> test("abcdefghi")
abcddfghi
>>> test("abCdefghi")
abCddfghi