CANON_leto2024 CANON_leto2024 CANON_leto2024

ML v Pythone 10 – trénovanie neurónovej siete, príprava

1

Námetom tohto a budúceho dielu je 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 jednej, alebo viacerých 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.

Jedna kniha je 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ť 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. Ak máte výkonnú grafickú kartu, prípadne dosť trpezlivosti môžete skúsiť vytvoriť trénovaciu množinu spojením slov z viacerých kníh, či iných textov.

Môžete použiť online prostredie Google Colaboratory, alebo príklad vyskúšať v lokálnom prostredí Jupyter Notebook. Ktorý je súčasťou platformy Anaconda. 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.

Natrénovanie neurónovej siete na texte knihy obsahujúcej 90 370 slov vo virtuálnom prostredí Google Colaboratory s nastaveným runtime prostredím T4 GPU s desiatimi iteráciami trvalo 78 minút. Na PC s grafickou kartou NVIDIA GeForce RTX 4060 rovnaká úloha trvala 79 minút, takže GPU vo virtuálnom prostredí Google Colab má takmer identický výkon s grafickou kartou RTX 4060.

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 obidvoch prípadoch odporúčame vytvoriť pre tieto materiály zložku.

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.  V našom príklade sme na natrénovanie použili knihu Rivers of Babylon od Petra Pišťanka, ktorá je charakteristická mierne „gangsterským“ štýlom jazyka. Uvidíme či sa to prejaví aj na vygenerovanom texte mini poviedky. Najskôr krátka ukážka textu, prvý odstavec z knihy

Ráno sa kotolník zobúdza s takou nenávisťou v duši, že mu ani jesť nechutí. Vylihuje na drevenej lavici, škrabe si svrbiacu kožu, napnutú na vysadených rebrách, a tupo sa obzerá. Neskúša premýšľať nad zdrojom tejto nenávisti. Kotolňa je temná, so zájdenými a obitými stenami. Vychladnuté kotly sa rysujú v tme. Preháňa sa v nich vietor.

Z textu vytvoríme zoznam slov. Pri tejto transformácii zároveň zmiznú bodky čiarky, pomlčky, otázniky výkričníky, úvodzovky...  takže zostanú len slová. Následne vytvoríme trénovaciu množinu tak, aby sme neurónovej sieti mohli dávať informácie po dávkach. V našom prípade bude veľkosť dávky 5 slov. Trénovaciu množinu teda potrebujeme usporiadať do n-tíc tak, aby vždy päť slov tvorilo vstupy, pričom 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 nášho textu

ráno sa kotolník zobúdza s -  takou
sa kotolník zobúdza s takou - nenávisťou
kotolník zobúdza s takou nenávisťou - v
zobúdza s takou nenávisťou v - duši
s takou nenávisťou v duši - že
takou nenávisťou v duši že - mu
nenávisťou v duši že mu - ani
v duši že mu ani - jesť
duši že mu ani jesť– nechutí

Príprava údajom na trénovanie neurónovej siete

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. V našom príklade sme na natrénovanie použili knihu Rivers of Babylon od Petra Pišťanka, ktorú máme na Google disku v súbore Rivers of Babylon.txt. Vy samozrejme môžete použiť akúkoľvek knihu, ktorú máte k dispozícii. Príkaz na výpis textu je v komentári, je to predsa len dlhý text. Štatistiky vo Worde ukazujú že text knihy má 175 strán A4 a obsahuje 90 366 slov. Skôr než začnete, odporúčame v prostredí Google Colaboratory nastaviť runtime prostredie na T4 GPU

#načítanie knihy z Google drive
from google.colab import drive
 
drive.mount('/content/drive')
kniha1 = open('/content/drive/My Drive/ML Neuronova siet/Rivers of Babylon.txt', 'r')
kniha1 = kniha1.read()
#kniha1

Variant pre spustenie na lokálnom PC v prostredí Jupyter notebook.

#načítanie knihy
kniha1 = open('./Rivers of Babylon.txt', 'r', encoding="utf8")
kniha1 = kniha1.read()
#kniha1

Pred spustením Jupyter Noteboooku je potrebné v konzolovej aplikácii nainštalovať knižnicu nltk, prípadne aj platformu PyTorch a podporu NVIDIA CUDA ak ju ešte nemáte nainštalovanú

pip install nltk

V prvom kroku potrebujeme knihu premeniť na zoznam slov a vynechať nealfanumerické znaky a zoskupenia znakov. Na tento účel využijeme knižnicu Natural Language Toolkit (ntlk), konkrétne funkciu word_tokenize()

import nltk
nltk.download('punkt')
from nltk.tokenize import word_tokenize
 
slova = word_tokenize(kniha1.lower())
slova [:30]

nechali sme si vypísať prvých 30 slov a aj v takomto výpise vidíme, že sa v zozname slov nachádzajú aj bodky, čiarky a podobne. Preto potrebujeme zoznam slov vyčistiť od neabecedných znakov. Reťazec neabecedných znakov získame z knižnice string ako string.punctuation.

punct = string.punctuation
punct

!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~

Neabecedné znaky 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.

import string
zoznam_slov = []
neabecedne_znaky = string.punctuation
neabecedne_znaky
 
for slovo in slova:
        for char in slovo:
            if char in neabecedne_znaky:
                slovo = slovo.replace(char, "")
        if slovo not in neabecedne_znaky:
            zoznam_slov.append(slovo)
print("Počet slov:", len(zoznam_slov), "unikátnych", len(set(zoznam_slov)))
zoznam_slov [:30]

V našom prípade máme 90 374 slov, čo sa takmer zhoduje s údajom zo štatistiky Wordu, pričom slovník je tvorený 19 679 unikátnymi slovami

V nasledujúcom kroku je potrebné previesť textové reťazce na číselné hodnoty, pretože neurónové siete nepracujú s prirodzeným jazykom, ale s „jazykom matematiky“. 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 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. 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é

temp_zoznam_slov = ['ráno','sa','kotolník','zobudí','potom','sa','kotolník','naje','ráno','sa','aj','umyje','potom','sa','ustrojí']
temp_slovnik= set(temp_zoznam_slov) #unikátne slová
temp_slovnik
 
---výpis---
 {'aj', 'kotolník', 'naje', 'potom', 'ráno', 'sa', 'umyje', 'ustrojí', 'zobudí'}

Z 15-tich slov je 8 unikátnych, ktoré tvoria slovník. Pomocou funkcie enumerate() slová v slovníku očíslujeme

temp_indexy_slov = {slovo: i for i, slovo in enumerate(temp_slovnik)}
temp_indexy_slov
 
---výpis---
{'naje': 0,
 'zobudí': 1,
 'aj': 2,
 'potom': 3,
 'kotolník': 4,
 'umyje': 5,
 'ustrojí': 6,
 'ráno': 7,
 'sa': 8}

Teraz náš text „Ráno sa kotolník zobudí potom sa kotolník naje ráno sa aj umyje potom sa ustrojí“ reprezentovaný postupnosťou slov zmeníme na postupnosť čísel.

[7, 8, 4, 1, 3, 8, 4, 0, 7, 8, 2, 5, 3, 8, 6]

Kde 7 = ráno, 8 = sa, 4 = kotolník....  Index konkrétneho slova môžeme zistiť príkazom

temp_indexy_slov['umyje']
 
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é. V našom ilustračnom príklade

temp_trenovacia_mnozina = [([temp_zoznam_indexov_slov[i],
                             temp_zoznam_indexov_slov[i+1],
                             temp_zoznam_indexov_slov[i+2],
                             temp_zoznam_indexov_slov[i+3],
                             temp_zoznam_indexov_slov[i+4]],
                             temp_zoznam_indexov_slov[i+5]) for i in range(2) ]
temp_trenovacia_mnozina
 
---výpis---
[([7, 8, 4, 1, 3], 8),
 ([8, 4, 1, 3, 8], 4)]

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

slovnik= set(zoznam_slov) #unikátne slová
print("Slovná zásoba na trénovanie má", len(zoznam_slov),"slov, unikátnych slov je", len(slovnik))
indexy_slov = {slovo: i for i, slovo in enumerate(slovnik)}
zoznam_indexov_slov = [indexy_slov[slovo] for slovo in zoznam_slov]
zoznam_indexov_slov[:10]
#zoznam_slov[:10]
#indexy_slov
 
---výpis---
Slovná zásoba na trénovanie má 90374 slov, unikátnych slov je 19679
[11144, 10597, 35, 1616, 10292, 19348, 5882, 17642, 5834, 3793]

Definujeme štruktúru našich tréningových údajov. Budú to 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ť

Vytvoríme množinu údajov na trénovanie neurónovej siete. Vypíšeme len prvých 10 skupín slov

davka=5
pocet_slov = len(zoznam_slov) #pocet slov knihy
trenovacia_mnozina = [([zoznam_indexov_slov[i], zoznam_indexov_slov[i+1], zoznam_indexov_slov[i+2], zoznam_indexov_slov[i+3], zoznam_indexov_slov[i+4]], zoznam_indexov_slov[i+5]) for i in range(pocet_slov-davka) ]
trenovacia_mnozina[:10]
 
---výpis---
[([11144, 10597, 35, 1616, 10292], 19348),
 ([10597, 35, 1616, 10292, 19348], 5882),
 ([35, 1616, 10292, 19348, 5882], 17642),
 ([1616, 10292, 19348, 5882, 17642], 5834),
 ([10292, 19348, 5882, 17642, 5834], 3793),
 ([19348, 5882, 17642, 5834, 3793], 16707),
 ([5882, 17642, 5834, 3793, 16707], 8332),
 ([17642, 5834, 3793, 16707, 8332], 7706),
 ([5834, 3793, 16707, 8332, 7706], 16665),
 ([3793, 16707, 8332, 7706, 16665], 8472)]

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ú v pokračovaní ukážeme ako neurónovú sieť vytvoriť a natrénovať.

Rekapitulácia doterajších dielov

Strojové učenie v Pythone 1 – prostredie Google Colab

Strojové učenie v Pythone 2 – knižnica Pandas na prácu s údajmi

ML v Pythone 3 – export a import údajov vo formáte CSV a Excel

Strojové učenie v Pythone 4 – práca s údajmi

ML v Pythone 5 – vizualizácia údajov pomocou grafov

ML v Pythone 6 – animované grafy a ich export ako video

ML v Pythone 7 – Využitie grafickej karty NVIDIA na výpočtovo náročné úlohy

ML v Pythone 8 – príklad rozpoznávanie obrazu

ML v Pythone 9 – trénovanie neurónu

Luboslav Lacko

Všetky autorove články
Python neuronova siet umelá inteligencia

1 komentár

testosterone therapy and finasteride reakcia na: ML v Pythone 10 – trénovanie neurónovej siete, príprava

1.3.2024 21:03
<a href="http://propeci.cfd">fincar 5mg</a> According to the risk level of the embedded algorithms, the digital therapeutics may be classified as medical devices
Reagovať

Pridať komentár

Mohlo by vás zaujímať

Mohlo by vás zaujímať