Neurónová sieť na generovanie textu - 1. časť, príprava
Námetom trojdielneho miniseriálu je e vytvorenie a natrénovanie vlastnej neurónovej siete. Natrénujeme ju na väčšom objeme textu v prirodzenom jazyku, v našom prípade na štyroch knihách Následne túto neurónovú sieť použijeme na generovanie textu krátkej poviedky. Zadáte prvých päť slov a algoritmus bude generovať ďalšie slová poviedky.
Kompletný príklad je na GitHube https://github.com/lubolacko/ML-v-Pythone-priklady

Na trénovanie neurónovej siete použijem štyri knihy od Karla Maya, tri diely Winnetoua a knihu Poklad v striebornom jazere. Vo všetkých knihách „účinkujú“ plus mínus rovnaké postavy a dej sa odohráva v rovnakom prostredí.
Štyri knihy sú samozrejme na natrénovanie neurónovej siete, ktorá má generovať texty veľmi málo. Reálne neurónové siete tohto typu sú trénované na obrovskom objeme textov napríklad z tisícov, alebo skôr stoviek tisícov slov. Určite si položíte otázku, prečo aj my v sprievodnom príklade k tejto kapitole nenatrénujeme neurónovú sieť na stovkách, alebo aspoň na desiatkach kníh. Pochopíte, keď spustíte trénovanie. Aj s využitím výpočtových možností moderných grafických kariet, ktoré realizujú výpočty mnohonásobne rýchlejšie než procesory to bude trvať pomerne dlho.
Môžete použiť online prostredie Google Colaboratory, alebo príklad vyskúšať v lokálnom prostredí Jupyter Notebook s knižnicou PyTorch a a podporu NVIDIA CUDA. V online prostredí Google Colab môžete na urýchlenie výpočtov využiť GPU a NVIDIA Cuda aj v prípade ak na lokálnom počítači nemáte nainštalovanú kompatibilnú karu NVIDIA. GPU tento typ výpočtov zvládne mnohonásobne rýchlejšie ako procesor. V prostredí Google Colaboratory nastavte runtime prostredie na T4 GPU.
V prípade ak použijete Google Colaboratory potrebujete nakopírovať všetky texty z ktorých sa neurónová sieť bude učiť na Disk Google. Ak využijete Jupyter Notebook na lokálnom počítači súbory nakopírujte do jeho pracovného adresára.

Vývojové prostredie Jupyter Notebook
Vo videu je kompletný postup inštalácie a konfigurácie NVIDIA CUDA, Pythonu, knižnice PyTorch a vývojového prostredia Jupyter Notebook
Princíp
Bez ohľadu na objem textu na ktorom budeme neurónovú sieť trénovať, bude potrebné text najskôr vyčistiť od nealfanumerických a grafických znakov a transformovať na postupnosť slov a keˇže neurónové siete pracujú s číslami, tak následne na postupnosť čísel.
Príprava údajov, odstránenie neabecedných znakov
Najskôr načítame knihu, alebo knihy, na ktorých sa bude neurónová sieť učiť. Pre jednoduchosť bude kniha v textovom súbore s príponou txt. Nie je problém načítať ani knihu vo formáte PDF, stačí nainštalovať a importovať knižnicu PyPDF2. Naše štyri spomínané knihy máme v pracovnom adresári v súboroch
Knihy majú podobný rozsah, na ilustráciu štatistiky vo Worde ukazujú že text knihy Poklad v striebornom jazere má 293 strán A4 a obsahuje 167 954 slov. Vy samozrejme môžete použiť akékoľvek knihy, ktorú máte k dispozícii.
Pred spustením Jupyter Noteboooku je potrebné v konzolovej aplikácii nainštalovať knižnicu Natural Language Toolkit (nltk) príkazom:
pip install nltk
Knižnicu môžete nainštalovať aj priamo v prostredí Jupyter Notebook, vtedy bude pred príkazom pip výkričník.
!pip install nltk
Kód pre spustenie na lokálnom PC v prostredí Jupyter notebook.
Máme k dispozícii text, ktorý má spolu 3 494 393 znakov.
Variant, - načítanie z Google drive (pre jednu knihu)
Z textu potrebujeme vytvoriť zoznam slov. Pri tejto transformácii potrebujeme odstrániť bodky čiarky, pomlčky, otázniky výkričníky, úvodzovky... tak aby zostali len slová. V ďalšom kroku teda text konvertujeme na zoznam slov a vynecháme nealfanumerické znaky. Na tento účel využijeme knižnicu Natural Language Toolkit (ntlk), konkrétne funkciu word_tokenize()
nechali sme si vypísať prvých 30 slov a aj v takomto skrátenom výpise vidíme, že sa v zozname slov nachádzajú aj bodky, čiarky, úvodzovky, otáznik a podobne. Preto potrebujeme zoznam slov vyčistiť od neabecedných znakov. Reťazec obsahujúci zoznam väčšiny neabecedných znakov získame z knižnice string ako string.punctuation.
Neabecedné znaky z takto získaného zoznamu a tiež úvodzovky hore, úvodzovky dole a dlhšiu pomlčku uvádzajúcu priamu reč vymažeme a vytvoríme nový zoznam slov do ktorého uložíme len slová skladajúce sa z písmen. Funkcia len() poskytne zoznam unikátnych slov, čiže vytvoríme slovník.
V našom prípade máme 573 340 slov, pričom slovník je tvorený 43 392 unikátnymi slovami. Nakoľko neurónové siete nepracujú so slovami, ale a matematikou, čiže číslami, je potrebné previesť slová z textových reťazcov na čísla a identifikovať všetky jedinečné slová, čiže vytvoriť zoznam všetkých slov, ktoré sa v texte vyskytujú. Vytvorím indexy, pričom index, čiže číslo bude zastupovať príslušné slovo. To je zároveň aj odpoveď na prípadnú otázku, či záleží na tom v akom jazyku sú texty na trénovanie. Nezáleží, jedinou podmienkou v takomto jednoduchom príklade siete trénovanej na niekoľko málo knihách je aby s jazyky nemiešali, napríklad slovenčina s češtinou. Pri trénovaní neurónovej siete nás zaujíma len to ako zvyknú slová po sebe nasledovať.
Pomocou funkcie enumerate() slová z našej dátovej množiny očíslujeme a vynecháme duplicitné slová. . Pre názornosť si to najskôr ukážeme na sekvencii niekoľko málo slov, pričom v sekvencii sú úmyselne aj duplicitné slová. Premenné v tomto vysvetľujúcom mini príklade majú predponu temp_ a v príklade s trénovaním neurónovej siete nebudú použité. Najskôr zistíme unikátne slová
Z 11-tich slov je 9 unikátnych, ktoré tvoria slovník. Pomocou funkcie enumerate() slová v slovníku očíslujeme
Vráťme sa však k textu z knihy. Zrealizujeme na ňom rovnaké úpravy – vytvorenie slovníka a transformáciu slov na čísla Vypíšeme len prvých 10 čísel
Rozdelenie dát do dávok
Je výpočtovo náročné vyhodnotiť stovky tisíc hodnôt naraz, takže aby sme nepreťažili neurónovú sieť budeme ju trénovať po dávkach. Preto údaje na trénovanie rozdelíme do dávok. Veľkosť dávky bude daná hodnotou parametra davka. V prvom pokuse nastavíme veľkosť dávky na 5.
V trénovacej množine budú slová za sebou usporiadané ako pätica vstupov a jeden výstup, pričom v každej ďalšej n-tici budú o jedno posunuté. Ku každej pätici bude ako výstup priradené slovo, ktoré za päticou nasleduje. Inak povedané, existuje určitá pravdepodobnosť, že za piatimi slovami zo vstupov by v generovanom texte malo nasledovať príslušné slovo, Prípadne za štyrmi slovami zo vstupov a piatym slovom iným. V ďalšej n-tici bude posun o jedno slovo. Najlepšie to pochopíte na príklade z úryvku textu
Veľká horúčava zahnala zámožnejších cestujúcich do kajút a kabín Väčšina z tých, čo mali iba palubný lístok, sa utiahla za sudy, debny a rozličnú batožinu, kde bol aspoň aký-taký tieň.
Vytvoríme päticu vstupov a jeden výstup
Tréningové údaje budú tyvoriť n-tice, pričom prvých päť slov bude zoznam vstupov a šiesty prvok oddelený od vstupov bude cieľ. Aby sme nepreťažili našu neurónovú sieť budeme jej údaje predkladať po dávkach piatich slov ako vstupov. Neurónová sieť sa na základe piatich za sebou idúcich slov snaží uhádnuť šieste slovo. Počet n-tíc, ktoré takto vytvoríme bude počet_slov mínus dávka, pretože posledných 5 slov z textu knihy už nemáme čím doplniť.
Údaje na trénovanie budú uložené v štruktúre typu zoznam a uložené budú po n-ticiach, pričom n-ticu budú tvoriť čísla reprezentujúce slová počnúc hodnotou premennej i, čiže
data [i], data [i+1], data [i+2], data [i+3], data [i+4], data [i+5]
Vytvoríme množinu údajov na trénovanie neurónovej siete. Vypíšeme len prvých 6 skupín slov
Trénovacia množina má ako vstupy pätice za sebou idúcich slov (technicky ich indexov), zakaždým o jeden index posunuté.
Trénovaciu množinu máme pripravenú, takže v pokračovaní môžeme vytvoriť a natrénovať neurónovú sieť.
Zobrazit Galériu