Sunday, January 1, 2017

Lietuvių kalbos generavimas grįžtamais neuronų tinklais

(Ironiska, bet posta tesiu sveplai)

Neseniai isbandziau torch-rnn su keleta viesu Lietuviu kalbos darbu is Vikisaltiniai. Gana seniai norejau atlikti kazka panasaus, nors tikiu jog universitetuose studentai jau senokai tai isbande, bet prisitukinu kaip pirmasis :) Ikvepimas kilo paskaicius apie CSS, Linux C source code, Shakespeare, Google Deep Dream bei kitus generatorius ir kaip lengvai galima istreniruoti neuronu tinklus.


Sis postas skirtas aprasyti kaip visa tai atlikau ir ka noreciau padaryti ateityje. Gidas skirtas MacOS ir reikalauja bazines komandines eilutes patirties.


Is pradziu isidiegiau Ubuntu VM per Vagrant, kol kompiliavosi Torch, Lua, etc parsisiunciau Wikipedijos backupus, susiradau programa kuris vercia Wiki formata i paprasta teksta, tuomet dar siektiek apvaliau rankiniu budu ir pradejau eksperimenta.


Pradzioje naudojau char-rnn, bet veliau atradau jog yra isleista nauja modifikacija torch-rnn, bei Docker atvaizdai, kas labai palengvina idiegima. Toliau aprasysiu kaip paleisti torch-rnn per Docker. Naudojau MacOS terminala duomenu paruosimui, taciau manau jog galima naudoti beveik identiskas komandas ir per Docker terminala Windows. Tinkla treniravau tik ant CPU, kadangi Docker ant MacOS nepalaiko GPU.


Duomenu paruosimas

Parsisiuskite ltwikisource is Wikimedia atsarginiu kopiju. Tiesioginiai adresai i kopijas bus greiciausia pakite, tad deti beprasmiska. Na galbut. Naudojau ltwikisource-20161220-pages-meta-current.xml.bz2 byla. Ispakavus archyva, su wikiextractor perverciam xml i txt:

python WikiExtractor.py ltwikisource-20161220-pages-meta-current.xml \

-o ltwikisource -b 1G --filter_disambig_pages -q --min_text_length 50

Tuomet su standartine programa sed pasalinam nereikalingus HTML zymas:
cd ltwikisource/AA
sed  '/^<[^>]*>$/d' wiki_00 > ltwikisource.txt

Proceso gale turetume gauti apie 5MB textine byla. Ta pacia procedura atlikau su pilna Lietuviskos WikiPedijos (ltwiki) kopija, gavosi 182MB byla.


Treniravimas

Is pradziu isirasom ir paleidziam Docker - virsutineje meniu juostoje atsiras ikona su statusu Docker is Running. Tuomet terminale rasom:
docker run --rm -ti crisbal/torch-rnn:base bash

Pasileidus konteineriui gausit unikalu id, pvz:

> root@3fcabc2ae266:~/torch-rnn#
kur 3fcabc2ae266 yra unikalus id, kurio prireiks perkeliant duomenis i konteineri. Is atskiro terminalo lango rasom:
docker cp ltwikisource.txt 3fcabc2ae266:/root/torch-rnn/data/ltwikisource.txt

Gryze i Docker konteiri paruosiam duomenis:
python scripts/preprocess.py \
--input_txt data/ltwikisource.txt \
--output_h5 data/ltwikisource.h5 \
--output_json data/ltwikisource.json

Priklauso nuo duomenu dydzio truks keles sekundes ar minutes. Tuomet galim paleisti treniravima:
th train.lua \
-input_h5 data/ltwikisource.h5 \
-input_json data/ltwikisource.json \
-gpu -1

Turetu pasimatyti toks tekstas:
Running in CPU mode
Epoch 1.00 / 50, i = 1 / 73600, loss = 5.540401
Epoch 1.00 / 50, i = 2 / 73600, loss = 5.432357
Epoch 1.00 / 50, i = 3 / 73600, loss = 5.253773

Po keletos iteraciju, loss parametras nukris iki daugmaz 2.5. Po standartiniu 50 epochu (ir nakties darbo), mano modelio loss nukrito iki 1.8. Pasak gwern, rezultatai is maziau 1 geri, maziau .8 - labai geri.

Darba galima pagreitiniti sumazinus tinklo dydi, panaudojant rnn_size parametra. Standartiskai jis yra 128. Docker nustatymuose galima pakeisti branduoliu kiek bei suteikiamos atmintines kieki, kas nelabai paspartino skaiciavimo.

Bandymas
Baigus (arba nutraukus) treniravima, galima sugeneruoti teksta su:
th sample.lua -checkpoint cv/checkpoint_10000.t7 -length 2000 -gpu -1

SVARBU: Nepamirskite modeli perkelti is konteinerio - isjungus Docker, informacija juose dingsta. Tai galima atlikti is isorinio terminalo:
docker cp 3fcabc2ae266:/root/torch-rnn/cv-backup/checkpoint_10000.t7 checkpoint_10000.t7 

Rezultatai:
Jūs dar yn turi daišnėnai. Pastebėjo prigilti pilkas eda armenybą, arba per myli skausmo aukai,
Iš visokius. O jis vis Lygssnėlė, desakyje, Palikti tolimėdamas laukė,
Ir turėdama Poną lūpa mus užsigrandę taip nesūgią, malkos idados, bet prisidegiai vienos gyvačius, išeina mirusių priešingą
Valando svetima daryti krūtinyt): nė ant laikomę



Kas susidėjusiu. Ko vyšios perskirgėti motikuo.

Fedras daugumus,
Visus ligviaus vakarais,
Tai tuai dar, žinai!

Panasu jog modelis gana gerai ismoko atkartoti sakiniu ir paragrafu struktura, kartais net eilerasciu. Nemazai zodziu atitinka musu kalba, taciau kai kurie yra isgalvoti. 

Butu idomu istreniruoti modeli kiek daugiau, galbut ideti daugiau neuronu i tinkla arba palikti treniruote daugiau epochu. Taip pat reiketu pabandyti iveikti ta 182MB byla. Tam reiketu pasinaudoti arba AWS arba Google Cloud GPU sankaupom (clusters).

Taip pat bandziau paleisti Tensorflow ant savo MacBook su GPU palaikimu, taciau kilo labai daug problemu su CUDA kompiliavimu.

Cia pateikiu apdorotas duomenu bylas, bei savo modeli kuri galite panaudoti iskarto isidiegus Docker. Taip pat, jei yra norinciu, pateikiu pilna wiki archyva.