Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu...

49
Sveučilište u Rijeci – Odjel za informatiku Diplomski studij, Informacijski i komunikacijski sustavi Edvin Močibob Raspoznavanje slova uglate glagoljice Diplomski rad Mentor: Prof. dr. sc. Ivo Ipšić Rijeka, 8. rujna 2016.

Transcript of Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu...

Page 1: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Sveučilište u Rijeci – Odjel za informatiku

Diplomski studij, Informacijski i komunikacijski sustavi

Edvin Močibob

Raspoznavanje slova uglateglagoljice

Diplomski rad

Mentor: Prof. dr. sc. Ivo Ipšić

Rijeka, 8. rujna 2016.

Page 2: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Sveučilište u Rijeci – Odjel za informatiku

Diplomski studij, Informacijski i komunikacijski sustavi

Edvin Močibob

Raspoznavanje slova uglateglagoljice

Diplomski rad

Mentor: Prof. dr. sc. Ivo Ipšić

Rijeka, 8. rujna 2016.

Page 3: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Sadržaj1 Sažetak 2

2 Ključne riječi 2

3 Uvod 3

4 Korišteni softver 44.1 TensorFlow . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4

5 Teorija neuronskih mreža 55.1 Konvolucijske neuronske mreže . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65.2 Max-udruživanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95.3 Izbacivanje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

6 Podaci 106.1 Skupovi za testiranje . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

7 Segmentacija 127.1 Dodatna obrada . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

8 Implementirane neuronske mreže 168.1 Prva mreža . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 178.2 Konvolucijska mreža . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18

9 Rezultati klasifikacija 20

10 Zaključak 23

11 Literatura 24

12 Popis slika 26

13 Popis tablica 26

14 Prilozi 2714.1 Skripta segment.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2714.2 Skripta misal_data.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3614.3 Skripta data_samples.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3814.4 Skripta basic_net.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4114.5 Skripta conv_net.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4414.6 Skripta caller.py . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 46

1

Page 4: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

1 Sažetak

U radu iznosim kako sam izvršio klasifikaciju slova uglate glagoljice pomoću neuronskih mreža.Generirao sam vlastiti skup podataka za treniranje, dok sam za testni skup još iskoristio određenedijelove Misala po zakonu rimskog dvora. Klasifikaciju sam izvršio pomoću dvije neuronskemreže. Prva nema skrivenih slojeva dok je druga konvolucijska neuronska mreža. Obje mrežesu imale visoku uspješnost kod klasificiranja.

2 Ključne riječi

strojno učenje, neuronske mreže, konvolucijske mreže, klasifikacija, Python, TensorFlow, glago-ljica

2

Page 5: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

3 Uvod

Neuronske mreže su složene matematičke strukture kojima se mogu izgraditi moćni modeli stroj-nog učenja. Iako su poznate desetljećima tek su nedavno uzele maha u produkcijskim okruže-njima. To se može zahvaliti popularizaciji strojnog učenja i napretku na području računalnoghardvera koje je omogućilo izvršavanje kompleksnih modela u razumno vrijeme. Konkretne im-plementacije neuronskih mreža mogu imati kompleksnu arhitekturu i mnogo parametara. Iakoih to čini netransparentnima za intuitivno razumijevanje, postoje alati i biblioteke (kao npr.TensorFlow) kojima se olakšava njihova programska implementacija.

U radu sam iskoristio dvije neuronske mreže kako bi vršio klasifikaciju slova glagoljice. Odabraosam glagoljicu jer mi se to čini kao egzotičan projekt i jer sam siguran da nema puno istraživa-nja na području njenog automatiziranog raspoznavanja – barem kad se usporedi sa latiničnimpismom. Nadalje, osnovni algoritmi klasifikacije se ne bi trebali razlikovati u odnosu na oda-branu abecedu. U radu navodim kako sam prikupio i obradio podatke koji su poslužili kao ulazneuronskim mrežama. Slijede arhitekture, detalji implementacije neuronskih mreža i njihovapreciznost. U prilozima se može naći moj kompletan Python kod. Cilj mi je bio definirati mrežukoja bi imala preko 90% uspješnosti kod klasifikacije testnih skupova podataka.

Ovim radom želim prikazati jedan cjeloviti postupak strojnog učenja – od prikupljanja podatakado izrade, treniranja i testiranja modela klasifikacije.

3

Page 6: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

4 Korišteni softver

Za pripremu podataka koristio sam Python 3 u kombinaciji sa OpenCV 3. Odlučio sam se zaPython pošto je to ekspresivan (skriptni) jezik sa mnogo biblioteka te kvalitetnom dokumentaci-jom i podrškom. Također, već sam koristio Python u prošlosti. OpenCV je popularna bibliotekaspecijalizirana za računalni vid i strojno učenje [1]. Njome sam se poslužio kod manipuliranjaslika i segmentiranja slova sa skenirane stranice.

Za implementaciju neuronskih mreža koristio sam TensorFlow. Preciznije, koristio sam njegovuverziju 0.9.0 za Python. TensorFlow je relativno nov alat koji je Google pustio u javnost 2015. go-dine [2]. Pošto je TensorFlow relativno nov, uzeo sam priliku da ga istražim u diplomskom radu.Prednost mu je što je vrlo fleksibilan – daje korisniku veliku slobodu kod definiranja arhitekturei parametara neuronske mreže. Također, ima dobru dokumentaciju te mnogo implementira-nih funkcionalnosti (kao npr. razne aktivacijske funkcije i funkcije pogreške). I TensorFlow iOpenCV su slobodnog koda.

Dodatno sam koristio još neke Python biblioteke od kojih je možda dobro spomenuti NumPy.NumPy, koju koristi i TensorFlow, je biblioteka za znanstveno računanje (engl. scientific com-puting) sa naglaskom na performanse [3].

4.1 TensorFlow

TensorFlow je biblioteka za strojno učenje. Koristi se i za znanstvena istraživanja i u produkciji.Google je koristi za razne proizvode – od prepoznavanje govora do Gmaila1 i Google Photosservisa2. TensorFlow je razvio Google Brain tim za znanstvene i komercijalne potrebe Googlea.Isti tim ga i danas održava. Biblioteka je od 9. rujna 2015. pod Apache 2.0 otvorenom licencom3

i trenutno pruža Python i C/C++ programsko sučelje (engl. application programming interface,API) [4].

TensorFlow je nastao iz DistBelief sustava za strojno učenje koji je inicijalno bio pod vlasničkom(engl. proprietary) licencom. DistBelief je koristilo više od 50 Googleovih internih timova zaimplementaciju dubokih neuronskih mreža u razne komercijalne proizvode kao Google Search,Google Maps, Google Street View, Google Translate, YouTube i gore već navedeni Gmail teGoogle Photos. Nakon refaktoriranja DistBelief koda u robusniju i bržu biblioteku, nastajeTensorFlow. 2009. je znanstveni napredak u širenju unatrag (engl. backpropagation) omogućioznatno smanjenje grešaka u radu DistBelief neuronskih mreža [4]. Taj napredak omogućio jesmanjenje grešaka za barem 25% u Googleovom softveru za raspoznavanje govora [5].

TensorFlow je druga po redu generacija sustava za strojno učenje od strane Google Brain tima.Softver ima mogućnost izvršavanja na više CPU i GPU uređaja. Izvršavanje je podržano za64-bitne Mac OS X i Linux (i desktop i server) operacijske sustave, te za Android i Apple iOSmobilne operacijske sustave. Izračuni su u TensorFlowu izraženi kroz grafove toka podataka(engl. stateful dataflow graphs). U takvim grafovima čvorovi predstavljaju numeričke izračunea bridovi tokove podataka [6]. Ime TensorFlow potječe od riječi tenzor (engl. tensor) kojaoznačava multidimenzionalna numerička ili podatkovna polja [4].

Spomenimo i DeepDream koji uspješno implementira TensorFlow za potrebe automatske ano-tacije (engl. captioning) slika [4]. U listopadu 2015. je pomoću TensorFlowa implementiranRankBrain – Googleov sustav strojnog učenja koji omogućava kvalitetnije rezultate pretraživa-nja [7].

1Googleov servis elektroničke pošte.2Servis za skladištenje te dijeljenje slika i videa.3Kod TensorFlowa dostupan je javno na https://github.com/tensorflow/tensorflow.

4

Page 7: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

5 Teorija neuronskih mreža

Biološki (životinjski) mozgovi bili su inspiracija za nastanak umjetnih neuronskih mreža4. Moz-govi životinja su kompleksan sustav međusobno povezanih skupova neurona. Iako je pojedinineuron relativno jednostavan u strukturi i funkciji, guste mreže povezanih neurona mogu vršitisložene zadatke kao klasifikaciju i raspoznavanje uzoraka. Ljudski mozak sadrži oko 1011 ne-urona, svaki povezan sa otprilike 10 000 drugih neurona, čime dobivamo 1015 sinaptičkih veza.Umjetne neuronske mreže predstavljaju pokušaj imitiranja tipa nelinearnog učenja koji se zbivau mrežama neurona koje nalazimo u prirodi [8].

Neuron (slika 1) koristi dendrite kako bi sakupio signale, tj. izlazne informacije, drugih neurona.Neuron signale kombinira kako bi generirao nelinearni odgovor (tj. "opalio") ovisno da li jedostignut određeni prag. Generirani odgovor se zatim aksonom šalje drugim neuronima [8].

Slika 1. Struktura tipičnog biološkog neurona. Sa lijeva na desno: jezgra (engl. nucleus), dendrit (engl. dendrite), soma(engl. cell body), akson (engl. axon), mijelinska ovojnica (engl. myelin sheath), Ranvierovo suženje (engl. node of Ranvier),telodendron (engl. axon terminal) i Schwannova stanica (engl. Schwann cell). Slika preuzeta sa [9].

Slika 2 ilustrira osnovni neuron većine umjetnih neuronskih mreža. Ulazi xi (koji mogu bitiuzorci skupa podataka ili izlazi ranijih neurona) množe se pripadnim težinama i zatim zbrajajuzajedno sa sklonošću. Taj zbroj zatim služi kao ulaz aktivacijskoj funkciji f . Aktivacijskafunkcija računa izlaz neurona (y) koji se šalje dalje niz mrežu.

x2 w2 Σ f

Aktivacijskafunkcija

yIzlaz

x1 w1

x3 w3

Težine

Sklonostb

Ulazi

Slika 2. Ilustracija jednog neurona neuronske mreže. Ulazi se množe pripadnim težinama te sumiraju zajedno sa sklonošću.Aktivacijska funkcija uzima tu sumu kako bi proizvela izlaz neurona.

4U literaturi i ostalim materijalima strojnog učenja često se izostavlja riječ "umjetne". Tako se i u ovom radupod "neuronske mreže" misli na "umjetne neuronske mreže".

5

Page 8: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Pojedini neuroni se kombiniraju kako bi se izradila neuronska mreža. U slici 3 prikazana jejedna jednostavnija mreža. U praksi, neuronske mreže imaju puno veći broj neurona u ulaznomi skrivenim slojevima. Također, izlazni sloj može imati više neurona. U prikazanoj mreži nemapovratnih veza i svaki čvor je povezan sa svakim čvorom sljedećeg sloja. Primijetimo da vezepostoje samo između susjednih slojeva.

Ulaznisloj

Skrivenisloj

Izlaznisloj

1. ulaz

2. ulaz

3. ulaz

4. ulaz

5. ulaz

Izlaz

Slika 3. Shema jednostavne neuronske mreže sa ulaznim slojem, jednim skrivenim slojem i izlaznim slojem sa jednimčvorom.

U procesu treniranja, tj. učenja, neuronska mreža prilagođava svoje parametre (kao npr. težineveza među neuronima) kako bi bolje obavljala zadaću za koju je namijenjena. Funkcija pogreške(engl. loss function) služi kako bi mjerila koliko dobro mreža obavlja svoju zadaću tijekomtreniranja. Mijenjanjem parametara cilj je postići što manju vrijednost funkcije pogreške. Dabi računali funkciju pogreške tijekom treniranja uz uzorke nam trebaju i njihove točne klase.Time se neuronske mreže svrstavaju u metode nadziranog učenja.

Jedna od bitnih prednosti neuronskih mreža je da su dosta fleksibilne u odnosu na manje va-rijacije i šumove u podacima. No, u odnosu na npr. stabla odlučivanja, neuronske mreže neproizvode intuitivna i razumljiva pravila. U praksi neuronske mreže također zahtijevaju većavremena treniranja. Jedna potencijalna mana neuronskih mreža je da ulazi moraju biti normi-rani od 0 do 1 [8].

Kod neuronskih mreža bitno je paziti na pretjeranu prilagodbu modela na ulazne podatke, tj.na pretreniranost (engl. overfitting). Pretreniranost se dešava kada model predviđanja opisujeslučajne greške ili šum umjesto veze među podacima; takav model će "memorizirati" podatkeza treniranje umjesto da uči [10]. Slijedi da će model biti jako uspješan kod predviđanja napodacima za treniranje ali neuspješan na podacima za testiranje (tj. na neviđenim podacima).

5.1 Konvolucijske neuronske mreže

Jedan od ciljeva konvolucijskih mreža je iskorištavanje prostorne strukture ulaza mreže. Timeje ova vrsta mreže posebno dobra u klasificiranju slika. U konvolucijskim mrežama na ulazegledamo u njihovom "prirodnom" obliku, tj. kao na piksele u 2D matrici. Konvolucijske mreže

6

Page 9: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

koriste tri osnovna koncepta: lokalno receptivno polje (engl. local receptive field), dijeljene težinei udruživanje (engl. pooling).

I dalje spajamo ulazne piksele na neurone u sljedećem (skrivenom) sloju, no ne spajamo svepiksele na sve neurone. U ovoj vrsti mreže manji blokovi piksela (npr. 5 px × 5 px) spajajuse na jedan neuron sljedećeg sloja. Specifični manji blok piksela naziva se lokalno receptivnopolje danog neurona skrivenog sloja. I dalje će svaki ulazni piksel imati veze se težinama kojese mijenjaju tijekom treniranja mreže. Skriveni neuron određenog receptivnog polja će takođerimati svoju sklonost.

Lokalno receptivno polje mičemo kroz cijelu ulaznu sliku. Stopa kojom mičemo polje nazivase napredovanje (engl. stride). Za svako receptivno lokalno polje preko kojeg pređemo, postojiodgovarajući skriveni neuron u sljedećem skrivenom sloju. Polje možemo na primjer pomicatiza jedan piksel udesno (ako počnemo sa gornjeg-lijevog kuta) i zatim kad dođemo do kraja redaspustiti se za jedan piksel i početi opet sa lijeve strane.

Ako imamo ulaznu sliku veličine 28 × 28, receptivno polje veličine 5 × 5 i napredovanje od 1 × 1(1 piksel po horizontalnoj i 1 piksel po vertikalnoj osi kada dođemo do kraja retka) dobiti ćemoskriveni sloj dimenzija 24 × 24. Dobili smo 24 jer se možemo pomaknuti 23 puta (i horizontalnoi vertikalno) prije nego što dođemo do ruba slike. Slike 4 i 5 ilustriraju prva dva koraka uopisanom konvolucijskom sloju.

Ulazni neuroniPrvi skriveni sloj

Slika 4. Izračun prve konvolucije za receptivno polje veličine 5 × 5. Ulazni sloj je dimenzija 28 × 28, konvolucijski 24 × 24.

Ulazni neuroniPrvi skriveni sloj

Slika 5. Izračun druge konvolucije za primjer u slici 4.

Zadržimo se kod 5 × 5 lokalnog receptivnog polja sa napredovanjem od 1 × 1. Spomenuli smo

7

Page 10: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

da će svaki neuron gore opisanog skrivenog sloja imati sklonost i težine. Važno je naglasiti daće i svaki drugi neuron u istom skrivenom sloju dijeliti iste težine i istu sklonost. Konkretno,svaki od 24 neurona našeg skrivenog sloja ima izlaz iz jednadžbe 1 (j i k su indeksi kojimaidentificiramo pojedini skriveni neuron, σ može biti bilo koja aktivacijska funkcija, b je sklonost,wl,m je 2D tenzor težina).

σ

(b+

4∑l=0

4∑m=0

wl,maj+k,k+m

)(1)

ax,y iz gornje jednadžbe (koja predstavlja operaciju konvolucije) predstavlja specifični izlaz pret-hodnog sloja (kao npr. piksel na (x, y) koordinati ulazne slike). Ponovimo da je wl,m 5 × 5 tenzorkoji dijele svi neuroni skrivenog sloja.

Iz jednadžbe 1 možemo zaključiti da svi neuroni iz skrivenog sloja traže isto svojstvo (engl.feature) samo na drugim lokacijama slike. Svojstvo koje neuroni traže može biti npr. vertikalnirub u lokalnom receptivnom polju. Traženje istog svojstva svuda po slici posebno je korisnoako na primjer klasificiramo slike određenog objekta a objekt nije jednako centriran na svimslikama.

Mapiranje iz ulaznog sloja u skriveni sloj naziva se svojstvena mapa (engl. feature map). Težinesvojstvene mape su dakle dijeljene težine, kao i što je sklonost dijeljena sklonost. Dijeljene težinei dijeljenu sklonost nazivamo kraće i zrno (engl. kernel) ili filtar.

Dosad je navedeni konvolucijski sloj tražio samo jedno lokalno svojstvo. U praksi konvolucijskislojevi inače računaju veći broj svojstvenih mapa. Veći broj svojstvenih mapa naravno odgovaravećem broju svojstava koje konvolucijski sloj može detektirati.

Skriveni sloj dim. 3 × 24 × 24Ulazi dimenzija 28 × 28

Slika 6. Konvolucijski sloj u praksi računa više svojstvenih mapa. Ovdje je zbog preglednosti prikazano samo njih tri.

Prednost dijeljenih težina i sklonosti je ta da uvelike smanjuje broj parametara potrebnih zakonvolucijsku mrežu. Što imamo manje parametara za optimiziranje, to možemo brže istreniratimrežu. Uzmimo gornji primjer gdje za svaku svojstvenu mapu imamo 5× 5 = 25 težina i jednusklonost (ukupno 26 parametara). Kada bi u konvolucijskom sloju računali 20 svojstvenih mapaimali bi ukupno 20 × 26 = 520 parametara koji definiraju sloj. Za usporedbu, pretpostavimoulazni sloj sa 784 ulaznih neurona (za npr. sliku od 28 px × 28 px) koji je potpuno povezan narelativno mali skriveni sloj sa 30 neurona. Za takvu potpuno povezanu mrežu imali bi 784 ×30 težina i dodatnih 30 sklonosti što je ukupno 23 550 parametara. Vidimo kako opisani konvo-lucijski sloj ima oko 45 puta manje parametara nego drugi, potpuno povezani, sloj. Naravno,ne bi bilo korektno uspoređivati različite vrste mreža samo po broju parametara. No intuitivnomožemo vidjeti kako korištenje konvolucijskih slojeva može smanjiti broj parametara potrebnihza postizanje istih performansi kao u potpuno povezanim mrežama [11].

8

Page 11: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

5.2 Max-udruživanje

Konvolucijske mreže sadrže i slojeve udruživanja, najčešće odmah nakon konvolucijskih slo-jeva. Sloj udruživanja pojednostavljuje izlazne informacije konvolucijskog sloja. Konkretnije,sloj udruživanja uzima izračunata svojstva neurona iz konvolucijskog sloja i računa sažetu ver-ziju prethodnog sloja. Svaki neuron sloja udruživanja može, na primjer, zbrojiti blok od 2 ×2 neurona prethodnog sloja. Umjesto zbrajanja češće se koristi max funkcija kojom neuronudruživanja jednostavno računa maksimum iz, na primjer, 2 × 2 bloka neurona konvolucijskogsloja.

Recimo da imamo konvolucijski sloj dimenzija 24 × 24. Sloj udruživanja koji prolazi po bloko-vima veličine od 2 × 2 sa napredovanjem od 2 × 2 bi tada imao dimenzije 12 × 12. Drugačijerečeno, konvolucijski sloj dijelimo na 2 × 2 blokove od kojih uzimamo samo maksimum. Važnoje napomenuti da se max-udruživanje primjenjuje za svako svojstvo konvolucijskog sloja posebno(kao što je ilustrirano u slici 7).

3 × 24 × 24 neurona28 × 28 ulaznih neurona 3 × 12 × 12 neurona

Slika 7. Max-udruživanje se primjenjuje za svaku svojstvenu mapu posebno.

Jedan intuitivniji način gledanja na max-udruživanje je sljedeći: sloj udruživanja je način na kojimreža otkriva da li se bilo gdje u nekom dijelu slike pojavilo određeno svojstvo. Točna lokacijasvojstva nije bitna pa je odbacujemo (za određeno svojstvo znamo gdje se otprilike pojavilo uodnosu na druga svojstva). Time udruživanje smanjuje broj potrebnih parametara za daljnjeslojeve [11].

5.3 Izbacivanje

Izbacivanje (engl. dropout) je tehnika za smanjivanje pretreniranosti5. Ovom tehnikom se mi-jenja sama arhitektura neuronske mreže. Izbacivanje radi tako da se tijekom treniranja polaskrivenih neurona privremeno isključi iz mreže. Ulazi i izlazi mreže se ne diraju. Korak tre-niranja se zatim izvede bez isključenih neurona. U sljedećem koraku treniranja (nakon što seažuriraju težine i sklonosti mreže) privremeno će se isključiti drugi skup skrivenih neurona. Pro-ces isključivanja i uključivanja neurona se ponavlja tijekom cijelog treniranja. Tijekom testiranjamreže svi će neuroni biti uključeni. Kako bi kompenzirali to što sada imamo duplo više skrivenihneurona nego tijekom faze treniranja, vrijednosti izlaznih veza skrivenih neurona prepolovimo.

Sama tehnika izbacivanja možda nema intuitivnog smisla. Kako bi izbacivanje neurona mogloizbjeći pretreniranost? Kada bi zaista imali više različitih istreniranih mreža, mogli bi ih isko-ristiti za klasifikaciju istog uzorka. Zatim bi uzeli predviđenu oznaku koja se pojavila u većinislučajeva. Pošto je treniranje više mreža vremenski zahtjevno, izbacivanje se često koristi za

5Tehnike koje se koriste za smanjivanje pretreniranosti inače se nazivaju tehnike regularizacije (engl. regulari-zation techniques).

9

Page 12: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

izbjegavanje pretreniranosti. Na tehniku izbacivanja možemo gledati na način treniranja višerazličitih mreža. Različite privremene mreže koje dobijemo izbacivanjem će, u idealnom slučaju,pretrenirati na različite načine te time globalno smanjiti efekte pretreniranosti [11].

6 Podaci

Postojale su dvije opcije kod pribavljanja podataka za treniranje: a) naći i skenirati postojećeknjige i slične pisane materijale na glagoljici i b) skinuti postojeći glagoljički font i samostalnoispisati tekst. Izabrao sam drugu opciju pošto mi je omogućila veću fleksibilnost. Ovako sammogao sam odrediti veličinu slova na papiru (bitno kod skeniranja i segmentiranja), vrstu gla-goljice/fonta (iako nisam našao velik broj fontova koji su zadovoljavali moje uvjete), broj slovana papiru te njihovu distribuciju i raspored.

Prvi korak je bio izbor fonta glagoljice. Valja napomenuti da se u glagoljici isti znakovi koriste iza slova i za brojeve [12]. Zbog prirode klasifikacije, koja gleda samo izgled znaka bez njegovogkonteksta, u radu klasificiram samo slova. Postoji nekoliko osnovnih vrsta glagoljice: obla,uglata i kurzivna [12]. Kurzivni font bi otežao segmentiranje slova time što bi se pravokutniciopisani oko (susjednih) slova preklapali zbog načina pisanja te vrste glagoljice6. Između oble iuglate glagoljice izabrao sam uglatu iz dva razloga: to je endemska vrsta glagoljice za Hrvatskui ima manje oblina/krivulja od oblate što eventualno može smanjiti količinu korištene memorijeza spremanje pojedinih kontura slova7. Još jedna prednost izabrane vrste glagoljice je ta što sesvako slovo sastoji od jedne komponente/znaka što olakšava automatsku segmentaciju. Nemaslova koji se sastoji od više odvojenih oblika kao npr. latinično slovo "Č" koje se sastoji od kvačicei krivulje (ukupno dvije komponente).

Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG iEpistula Croatica sa [13], ispisao sam na računalu svakim fontom po stranicu teksta. Svakastranica sadrži hrvatsku abecedu od A do Ž ponovljenu više puta bez dodatnih razmaka izmeđuslova. Sve tri stranice zajedno čine osnovni skup podataka za treniranje sa ukupno 1512 uzoraka(glagoljičkih slova) po stranici, s time da se svaki uzorak ponavlja jednaki broj puta. Naravno,veličina mog skupa nije usporediva sa veličinom nekih standardnih skupova podataka za strojnoučenje (kao npr. MNIST skup8). Na broj uzoraka u mom skupu podataka najviše je utjecalapraktičnost kod ispisa i skeniranja te limitirani broj fontova. Bitno je napomenuti da sam zaskupove podatka iskoristio sva hrvatska slova osim dvoslovnih "DŽ", "LJ" i "NJ". U skupupodataka nalaze sa samo slova koja su dostupna u sva tri gore navedena fonta.

Kod skeniranja ispisanih stranica odabrao sam rezoluciju od 200 dpi i JPEG format. Ta rezo-lucija i format pokazali su se kao dobar izbor kod kasnije digitalne obrade slika. Na kraju samdobio skup sa 1512 uzoraka za svaki font, što je ukupno 4536 uzoraka (168 uzoraka po slovu).Za treniranje mreža iskoristio sam taj osnovni skup. Kako bi imao više uzoraka za treniranje,odlučio sam umjetno proširiti skup sljedećim tehnikama: a) pomicanjem slova, b) dodavanjemrotacije i b) dodavanjem šuma. Time mogu više puta segmentirati istu stranicu i dobiti različiteslike za ista slova. No osim što time mogu po volji povećati skup za učenje, opisane tehnikesluže i kako bi, barem donekle, izbjegao pretreniranost.

U donjoj slici naveo sam dio abecede za tri korištena fonta. Vidljivo je kako postoje razlike kododređenih slova – negdje manje, negdje veće. Tako na primjer kod slova "E" možemo primijetiti

6Kurzivni fontovi dostupni na [13] nemaju taj problem no ipak sam odabrao drugu vrstu glagoljice.7OpenCV može spremati konture segmenata na dva načina: a) spremati sve točke uz linije konture i b) izbaciti

točke koje se nalaze na ravnoj liniji između neke dvije točke [14]. U programskom kodu iskoristio sam metodupod b).

8Originalni MNIST skup podataka se sastoji od 60 000 uzoraka za trening i 10 000 uzoraka za testiranje. Uzorkečine slike ručno pisanih znamenki (0–9) fiksne veličine [15].

10

Page 13: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

da u trećem fontu nema središnje crte. Naravno, sva su tri fonta korektna – glagoljica je tijekomvremena mijenjala svoj oblik.

Slika 8. Prvih osam slova, od ukupno njih 27, korištenih u generiranju skupova podataka za treniranje. Primijetimo različitiznak za "E" u trećem fontu.

6.1 Skupovi za testiranje

Gore opisani skup podataka također koristim za testiranje. Pošto bi treniranje i testiranje naistom skupu (unatoč pomaku, rotaciji i šumu) dalo jako visoke rezultate, izradio sam još jedanskup za testiranje. Kako bi dobio bolji dojam o mogućnostima modela odlučio sam neuronskemreže također testirati na skupu podataka temeljenom na knjizi Misal po zakonu rimskogadvora9 (1483. god.). Misal, koji je pisan uglatom glagoljicom, dostupan je na [16] gdje ga jemoguće pregledati u digitalnom obliku.

Iz misala sam ručno segmentirao i označio 200 slova sa više nasumičnih stranica. Segmentacijusam obavio ručno pošto slike skeniranih stranica nisu u dovoljno visokoj rezoluciji. Automatskusegmentaciju otežava i različita veličina i boja slova te stanje stranica (vidljivo u slici 9). Spo-menutih 200 slova nisam birao nasumično. Segmentirao sam veća crna slova (postoje još crvenaslova i manje ilustracije). Bitno je napomenuti da sam birao samo ona slova koja su i u skupupodataka za treniranje (izostavio sam znakove za nepoznata slova, poluglasove i ligature10).Tako je skup za testiranje teoretski mogao imati najviše 27 različitih oznaka (slova).

9Misal po zakonu rimskoga dvora je prva hrvatska tiskana knjiga, otisnuta svega 28 godina nakon dovršetkaGutenbergove četrdesetdvoredne Biblije. Ujedno, to je prvi misal u Europi koji nije tiskan latiničnim slovima [16].

10Ligatura nastaje udruživanjem dva ili više grafema ili slova u jedan znak. Primjer latinične ligature bilo bislovo Æ (A i E) [17].

11

Page 14: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Slika 9. Dio 115. stranice misala dostupnog na [16].

7 Segmentacija

Segmentacija se vrši posebno za skup podataka za treniranje (automatski) i posebno za skuppodataka temeljenom na misalu (ručno). Ovdje donosim segmentiranje podataka za treniranjepomoću skripte segment.py (prilog 14.1). Skripti se proslijede imena skeniranih stranica za kojepostoje pripadne tekstualne datoteke sa oznakama svakog slova na stranici. Slijedi postupaksegmentacije koji je jednak za sve stranice.

a) Učitaj sliku u sivoj boji,

b) binarno odredi prag (engl. thresholding),

c) nađi konture svih slova na slici,

d) sortiraj slova redom kojim bi se čitala,

e) obradi i spremi slova te njihove oznake,

f) dodaj slova i oznake u zajednička polja svih stranica.

Nakon gornjih koraka na kraju se još lokalno spremi polje slova i polje oznaka koji sadrže podatkesa svih stranica. Slijedi detaljniji opis navedenih koraka.

Pošto mi je cilj klasificirati slova, informacija o njihovoj točnoj boji ili boji papira mi nije po-trebna. Zato ih učitavam u sivoj (crno-bijeloj) boji. Zbog relativno kvalitetnih slika skeniranogpapira, mogao sam automatizirati postupak segmentacije i označavanja slova sa njih. Prijedetektiranja samih slova (tj. segmentacije) na sliku primjenjujem binarno određivanje praga.OpenCV podržava više tehnika određivanja praga [18] od kojih sam isprobao: binarno, odsije-canjem (engl. truncate) i do-nule (engl. to zero). Postoji još metoda za određivanje praga, odkojih se ističu adaptivno određivanje praga11 i Otsu određivanje praga12. Pošto su skenirane

11Potrebno npr. kada je slika neravnomjerno osvijetljena. [18]12Najbolji rezultati se vide kod bimodalnih (engl. bimodal) slika – slike sa dva istaknuta vrha u histogramu.

[18]

12

Page 15: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

stranice relativno "čiste" (ravnomjerno osvijetljene, malo grešaka i jedna boja/nijansa fonta) njihnisam uzeo u obzir. Iz slike 10 vidljivo je da binarno određivanje praga sa ručno postavljenimpragom daje dovoljno dobre rezultate, tako da sam se odlučio za tu tehniku. Prag je određeneksperimentalno nakon isprobavanja više vrijednosti.

Slika 10. Testirane tehnike određivanja praga. Sve imaju vrijednost praga 200. Slika je generirana pomoću skriptedata_samples.py (prilog 14.3).

Slijedi postupak računanja kontura na svim objektima detektiranim nakon određivanja praga.Te konture će poslužiti za izračun pravokutnika koji opisuju pojedinačna slova. Primijetimo uslici 11 da se slova mogu sastojati od više objekata, svako sa svojom konturom. Od tih konturanajbitnija je ona koja slijedi vanjski rub slova. Zanimaju nas sve vanjske konture osim onihkoje su premale13 – takve konture označavaju mrlje i slične nepravilnosti u skeniranoj slici. Natemelju vanjskih kontura, oko slova se opisuju pravokutnici kojima se slova kasnije izoliraju saslike.

13Ručno je definirana širina i visina kontura koje su premale da bi bile slovo.

13

Page 16: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Slika 11. Pravokutnici opisani oko pronađenih kontura na dijelu slike sa podacima za treniranje. Slika je generirana pomoćuskripte data_samples.py.

Opisani pravokutnici se zatim sortiraju redoslijedom kojim bi se slova unutar njih čitala. Odlučiosam se za to sortiranje pošto datoteka sa oznakama slova slijedi taj redoslijed. Time ne mo-ram ručno označavati svako segmentirano slovo. Naravno, takav postupak pretpostavlja (osimuspješnog sortiranja) i da su sva slova uspješno segmentirana. Pošto slova u recima nisu svaiste visine, jednostavno naivno sortiranje (po y i zatim po x osi) nije bilo moguće. Moj pristupsortiranju uključuje sortiranje po detektiranim recima.

Prvo se pronađu granice između redaka time što se siva slika stranice zamuti (engl. blur) Ga-ussovim filtrom. Filtar ima oblik 95 px × 1 px kako bi na kraju dobio horizontalne mrlje namjestima redaka. Nakon filtra na sliku se primijeni binarno određivanje praga kako bi lakšepronašao konture redaka. Nakon što se nađu konture "mrlja" koje predstavljaju retke, one sesortiraju po y osi. Sa konturama redaka sada mogu dobiti y koordinate granica između njih.Tom informacijom mogu uspješno sortirati slova redom kojim bi se ona čitala. Donja slikaprikazuje dio skenirane stranice na kojoj su slova uspješno prepoznata i sortirana.

Slika 12. Primjer sortiranih segmenata na dijelu slike. Slika je generirana pomoću skripte data_samples.py.

14

Page 17: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

7.1 Dodatna obrada

Nakon izdvajanja slova njihove dimenzije se postave na 28 px × 28 px po uzoru na TensorFlowmreže iz [19] i [20]. Valja napomenuti da su segmentirana slova u programu izvedena kaovišedimenzionalna numerička polja. Pošto je u pitanju crno-bijela slika slova su predstavljenadvodimenzionalnim poljima gdje svaka vrijednost predstavlja jedan sivi piksel na koordinati(x, y).

Skripta segment.py može također dodati pseudo-slučajni pomak, rotaciju i šum na slova. Ovipostupci su potrebni kako bi umjetno proširio skup podataka. Pomak (x, y) se ostvaruje zacjelobrojne vrijednosti x, y ∈ [−1, 1]. Slova se rotiraju za realnu vrijednost n ∈ [−8°,+8°〉 uodnosu na njihov izvorni kut. Šum dodajem tako da svakom pikselu zbrojim pseudo-slučajnucjelobrojnu vrijednost14 iz [−80, 80]. Maksimalne i minimalne vrijednosti za umjetni pomak,rotaciju i šum postavljene su ručno; cilj mi je bio učiniti da se ista slova sa iste stranice dovoljnorazlikuju no i da ostanu čitljiva. Slika 13 sadrži nekoliko "čistih" uzoraka kojima je jedinopromijenjena veličina, dok slika 14 sadrži uzorke nakon primjene pomaka, rotacije i šuma.

Slika 13. Primjer uzoraka za font Glagoljica euglata. Uzorcima je postavljena fiksna širina i visina nakon automatskogsegmentiranja sa crno-bijele slike.

Slika 14. Primjer uzoraka (font Glagoljica euglata) kojima su primijenjeni pseudo-slučajni pomak, rotacija i šum.

Nakon obrade slova ona se spreme u polje u obliku pogodnom za TensorFlow neuronske mreže,što znači:

a) konverzija tipa vrijednosti polja,

b) normaliziranje vrijednosti polja da budu u rasponu [0, 1] i

c) "izravnavanje" polja tj. njihovo pretvaranje u jednodimenzionalna polja.

Navedenim koracima se na kraju dobiva polje u kojemu je svako slovo predstavljeno jednodimen-zionalnim podpoljem. Kako se normaliziraju vrijednosti piksela kod kojih je poznata minimalna(0) i maksimalna (255) vrijednost, iskorištena je min-max normalizacija [8] (jednadžba 2 gdje jeX izvorno polje a X∗ normalizirano polje).

X∗ = X −min(X)max(X)−min(X) = X

255 (2)

Postoji još jedno polje koje će TensorFlow zahtijevati: polje oznaka segmentiranih slova. Ovopolje sadrži više jednodimenzionalnih jednovrijednosnih (engl. one-hot) podpolja gdje svakopodpolje predstavlja oznaku jednog slova. Redoslijed tih podpolja podudara se sa redoslijedomslova unutar prvog polja. Jednovrijednosna podpolja imaju 27 elemenata što odgovara broju

14Kod dodavanja vrijednosti na piksel pazim da ne izađem iz segmenta [0, 255].

15

Page 18: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

mogućih slova. Od tih 27, jedan element jednovrijednosnog polja ima vrijednost 1 dok su ostalielementi 0. Pozicija jedinice u podpolju označava o kojem se slovu radi15. Polje u primjeru 3 jeilustracija jednovrijednosnog polja koji predstavlja oznaku slova E.

[0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]→ E (3)

Što se drugog skupa podataka za testiranje tiče, osnovna obrada se sastojala od dva koraka:pretvori slova u crno-bijelo i postavi im dimenzije na 28 px × 28 px. Na temelju tog osnovnogskupa generirao sam još tri različita skupa sljedećim tehnikama: binarno određivanje praga,globalno ujednačavanje histograma i adaptivno ujednačavanje histograma (CLAHE algoritam).Donja slika prikazuje skupove za testiranje generirane pomoću skripte misal_data.py (prilog14.2).

Slika 15. Primjer slova iz skupova za testiranje temeljenih na misalu. Na vrhu su slova iz osnovnog skupa po kojem sunastala tri donja skupa.

8 Implementirane neuronske mreže

Implementirao sam dvije neuronske mreže. Prva (basic_net.py u prilogu 14.4), napisanapo uzoru na [19], sadrži samo ulazni i izlazni sloj (nema skrivenih slojeva). Druga mreža(conv_net.py u prilogu 14.5) je konvolucijska neuronska mreža implementirana po uzoru na[20].

15Elementi jednovrijednosnog polja redom odgovaraju: A, B, C, Č, Ć, D, Ð, E, F, G, H, I, J, K, L, M, N, O,P, R, S, Š, T, U, V, Z i Ž. Redoslijed slova nije bitan dok god je konzistentan.

16

Page 19: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

8.1 Prva mreža

Ova mreža se sastoji samo od potpuno povezanog ulaznog i izlaznog sloja. Mreža ima ulaznisloj sa 784 čvorova. Svaki čvor predstavlja po jedan piksel određenog slova (28 px × 28 px =784 px). Izlazni sloj sadrži 27 čvorova pošto svaki uzorak iz skupa za treniranje i testiranjeodgovora jednom od 27 mogućih slova. Na temelju veličine ulaznog i izlaznog sloja definiranje dvodimenzionalni tenzor (tj. matrica) sa težinama veza između njih. Taj tenzor ima oblik784 × 27. Na temelju broja klasa u izlaznom sloju definiran je i jednodimenzionalni tenzor (tj.vektor) sklonosti duljine 27. I težine veza i sklonosti su na početku treniranja 0. U kodu su jošdefinirani tenzori koji će sadržavati slova, predviđene oznake i točne oznake tijekom treniranja.

Za fazu treniranja odabrao sam softmax regresiju koja pretvara nenormalizirani ulaz u distri-buciju vjerojatnosti pripadnosti određenoj klasi tj. oznaci. Softmax regresija, koja služi kaofunkcija aktivacije, primjenjuje se kao što je prikazano u jednadžbi 4.

y = σ(Wx+ b) (4)

Iz jednadžbe 4 vidimo da je prije softmaxa potrebno izračunati Wx+ b gdje je W tenzor težinaveza, x tenzor sa ulazima (pojedinim slovima) i b tenzor sa sklonostima [19]. Slijedi samadefinicija softmaxa [21] za izlaz z danog neurona (j je indeks neurona a K ukupni broj neuronaza trenutni sloj).

σ(z)j = ezj∑Kk=1 e

zk, j = 1, . . . ,K (5)

Kako bi mjerio koliko je mreža dobra u predviđanju iskoristio sam unakrsnu entropiju (engl.cross entropy) za funkciju pogreške. Unakrsna entropija definirana je u jednadžbi 6 gdje ypredstavlja izračunate vjerojatnosti a y′ prave vjerojatnosti [19].

Hy′(y) = −∑

i

y′i log(yi) (6)

U sklopu treniranja koristim gradijentni spust16 (engl. gradient descent) koji je implementirankao TensorFlow optimizator17. Pošto TensorFlow prije pokretanja samog treniranja poznajecijeli graf izračuna, može koristiti širenje unatrag (engl. backpropagation) za efikasno manipu-liranje derivacijama tj. izračun utjecaja varijabli na unakrsnu entropiju [19]. Gradijentni spustkoristi stopu učenja od 0.02 koja je eksperimentalno određena.

Slijedi treniranje koje je izvedeno nešto drugačije nego u [19]. Originalni model (koji ima punoveći skup podataka nego moj skup) vrši treniranje u 1000 iteracija, gdje u svakoj iteraciji iskoristi100 slučajnih uzoraka. Za moju mrežu, skup podataka za treniranje sastoji se od tri manjapodskupa na koja su primijenjene tehnike iz poglavlja 7.1 (pomak, rotacija, šum). Svaki od tihpodskupova sadrži tri stranice gdje je svaka stranica napisana različitim fontom. Kompletanskup se prije treniranja pseudo-slučajno ispremiješa. Treniranje se izvršava u 6804 iteracijagdje se svaki put uzmu dva uzorka. Slika 16 vizualizira preciznost na testnom skupu podatakatijekom treniranja. Slika je generirana pomoću TensorBoarda18.

16Gradijentni spust je tehnika nalaženja (lokalnog) minimuma funkcije na osnovu predznaka i vrijednosti gra-dijenta [22]. Gradijent je poopćenje derivacije.

17Optimizatori u TensorFlowu računaju gradijente i primjenjuju ih na varijable.18TensorBoard je alat za vizualizaciju raznih aspekata TensorFlow programa.

17

Page 20: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Slika 16. Preciznost na testnom skupu podataka temeljenom na misalu tijekom treniranja za prvu mrežu.

8.2 Konvolucijska mreža

Ovdje iznosim arhitekturu konvolucijske neuronske mreže sa više skrivenih slojeva. Za razlikuod prethodne mreže, težine se ovdje inicijaliziraju na pseudo-slučajne vrijednosti pomoću koris-nički definirane funkcije weight_variable. Razlog tomu je tzv. razbijanje simetrije. Da su svepočetne težine iste, svi neuroni u prvom skrivenom sloju bi dobili isti ulaz. Prije nastavka spo-menimo ReLU (engl. rectified linear unit) neurone. Oni koriste aktivacijsku funkciju prikazanuu jednadžbi 7 (gdje je x ulaz neurona) [23].

f(x) = max(0, x) (7)

Sklonosti su inicijalizirane na 0.1 kako bi se izbjegao veći broj "mrtvih" ReLU neurona. MrtviReLU neuron uvijek izbacuje isti izlaz tj. 0. Ako postavimo sklonost na malu pozitivnu vrijednost(u našem slučaju na 0.1), neuron će imati veću šansu da proizvede vrijednost različitu od 0.

U nastavku sve konvolucijske slojeve izraditi ćemo pomoću korisnički definirane funkcije conv2d.Napomenimo da je u njoj definirano napredovanje od 1 × 1 za lokalna receptivna polja (kao i uprimjeru iz poglavlja 5.1), te da obrađujemo i rubne piksele tako da dodajemo ispunu od 0 gdjeje potrebno. Takva ispuna ne utječe na izlaz neurona.

Za definiranje slojeva udruživanja koristimo korisnički definiranu funkciju max_pool_2x2. Njomeće svaki takav sloj vršiti max-udruživanje blokovima dimenzija 2 × 2. Napredovanje je takođerdefinirano na 2 × 2.

Definirajmo prvi konvolucijski sloj. Konvolucije su definirane na lokalnom receptivnom poljudimenzija 5 × 5 i računaju 32 svojstvenih mapa. Taj broj nije fiksan i nije vezan uz dimenzijelokalnog receptivnog polja, pa je tako mogao biti veći ili manji. Koristim 32 pošto je i mreža izdokumentacije [20] koristila taj broj svojstava za prvi konvolucijski sloj.

Kako bi u programu mogli primijeniti konvolucije, potrebno je pretvoriti ulaze iz 1D tenzorau 4D tenzore. To je učinjeno naredbom tf.reshape(x, [-1, 28, 28, 1]). Drugi argumentreshape predstavlja listu sa novim dimenzijama budućih ulaza. Lista redom definira: veličinupodskupa za korak treniranja (engl. batch size) koji može biti bilo koje veličine (-1), visinuulaznog uzorka (28), njegovu širinu (28) i broj ulaznih kanala (1). Postoji samo jedan ulaznikanala pošto su ulazne slike crno-bijele.

18

Page 21: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Nakon prvog konvolucijskog sloja (u kodu h_conv1) slijedi max-udruživanje (u kodu h_pool1).Iz koda možemo vidjeti da h_conv1 koristi ReLU neurone. Prvi sloj udruživanja uzima izlaz tihReLU neurona.

Drugi konvolucijski sloj prvo računa konvolucije na izlaze prvog sloja udruživanja. I ovdje sekoristi lokalno receptivno polje dimenzija 5 × 5. Za razliku od prvog sloja ovdje računamo 64svojstvenih mapa. Zato i imamo težine za drugi konvolucijski sloj u tenzoru dimenzija 5 × 5× 32 × 64 (visina i širina receptivnog lokalnog polja, ulazni kanali, izlazni kanali) te sklonostiu 1D tenzoru duljine 64. Izlaz ovog konvolucijskog sloja se, kao u prvom sloju, provlači krozReLU funkciju. Max-udruživanja se opet vrše blokovima 2 × 2 sa napredovanjem od 2 × 2.

Nakon drugog sloja max-udruživanja slijedi standardni potpuno povezani sloj sa 1024 neurona(mogao se uzeti i neki drugi broj neurona). Tenzor sa težinama tog skrivenog sloja ima oblik3136 × 1024. Slijedi objašnjenje kako smo došli do broja 3136 (koji je u kodu izražen kao 7 *7 * 64).

a) Dodavanjem ispune (0), ulazne slike (originalno 28 × 28 × 1) dobivaju dimenzije 32 × 32× 1 (zadnja jedinica predstavlja broj ulaznih kanala);

b) konvolucijama 5 × 5 × 32 (visina, širina, broj izlaznih svojstvenih mapa) na prethodnoopisane slike dobije se izlaz dimenzija 28 × 28 × 32;

c) max-udruživanjem (sa blokovima 2 × 2 i napredovanjem 2 × 2) prepolovili smo prve dvijedimenzije ulaza tako da izlaz ovog sloja ima dimenzije 14 × 14 × 32;

d) kako bi i u drugom konvolucijskom sloju primijenili konvolucije na cijele izlaze, dodajemoispunu – ovako ulazi oblika 14 × 14 × 32 dobivaju oblik 18 × 18 × 32;

e) drugi konvolucijski sloj (opet sa poljem visine i širine 5 × 5 no sada sa 32 ulaznih kanalai 64 izlaznih) rezultira izlazima dimenzija 14 × 14 × 64;

f) zadnje udruživanje sažima prethodni konvolucijski sloj na dimenzije 7 × 7 × 64;

g) konačno, ako bi htjeli potpuno povezani sloj sa 1024 neurona koji uzima ulaze prethodnogmax-udruživanja, potreban nam je tenzor težina oblika 3136 × 1024 gdje smo 3136 dobilikao 7 · 7 · 64.

Kako bi se dimenzije izlaza drugog sloja max-udruživanja podudarale sa tenzorom težina pot-puno povezanog sloja, potrebo ih je preoblikovati. U kodu tako imamo tf.reshape(h_pool2,[-1, 7 * 7 * 64]). Drugi argument funkcije reshape je lista koja određuje novi oblik. Reklismo kako smo dobili 7 · 7 · 64; spomenimo i da −1 označava bilo koji broj (koji će se iz-računati tijekom pokretanja programa). Izlaz skrivenog sloja je time u kodu definiran kaotf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1). Primijetimo da opet koristimo Re-LU neurone.

Kako bi smanjio pretreniranost, koristim izbacivanje nakon potpuno povezanog sloja. Izbaciva-nje u TensorFlowu izvedeno je nešto drugačije nego tehnika opisana u poglavlju 5.3. Funkcijomtf.nn.dropout(h_fc1, keep_prob) definiramo sloj izbacivanja. Prvi argument je sloj na ko-jem se vrši izbacivanje a drugi je vjerojatnost izbacivanja (koja tijekom treniranja iznosi 0.5).Vjerojatnost keep_prob ne samo da odlučuje koji će neuroni ostati, nego ako ostanu takođerskalira njihov izlaz za 1/keep_prob puta. Ako je neuron "izbačen" njegov izlaz će biti 0. Skalira-nje "uključenih" neurona služi kako se ne bi promijenila očekivana suma sloja. Time istu mrežumožemo koristiti i kod testiranja (bez da mijenjamo težine veza nakon treniranja). Naravno,kod testiranja keep_prob želimo postaviti na 1.

Nakon sloja izbacivanja slijedi, posljednji, izlazni sloj. Ovaj izlazni sloj je standardni softmaxsloj sa 27 neurona. Slika 17 ilustrira arhitekturu cijele mreže.

19

Page 22: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Slika 17. Arhitektura implementirane konvolucijske mreže. Kod veličina dimenzija ulaza i ostalih slojeva uzete su u obzir iispune. Također, na slici nije označeno da konvolucijski slojevi i predzadnji (potpuno povezani) sloj koriste ReLU neurone.

Konvolucijska mreža koristi AdamOptimizer optimizator za treniranje sa stopom učenja od0.0008. Optimizator implementira Adam (engl. Adaptive Moment Estimation) algoritam opisanu [24]. U svakom koraku treniranja uzima se 50 uzoraka, po uzoru na primjer iz dokumentacije.Kao i u prošloj mreži, i ovdje se koristi unakrsna entropija te umjetno prošireni skup poda-taka za treniranje (koji se ispremiješa prije samog treniranja). Slijedi TensorBoard vizualizacijapreciznosti klasifikacije na testnom skupu podataka tijekom treniranja mreže.

Slika 18. Preciznost na testnom skupu podataka temeljenom na misalu tijekom treniranja konvolucijske mreže.

9 Rezultati klasifikacija

Uspješnosti klasificiranja na testnim skupovima podataka se u nastavku mjere kao preciznostiP (jednadžba 8 gdje |TP | predstavlja broj točnih a |FP | broj netočnih klasifikacija).

P = |TP ||TP |+ |FP | (8)

Tablice 1 i 3 sadrže rezultate testiranja u prvoj jednostavnijoj mreži. U tablicama 2 i 4 prikazanisu rezultati za konvolucijsku mrežu. Za obje mreže izvršio sam testiranje na a) skupu podatakaod tri skenirane stranice na kojem su primijenjeni pomak, rotacija i šum (tablice 1 i 2) i b)skupovi podataka nastali na temelju 200 ručno segmentiranih slova iz misala (tablice 3 i 4). Za

20

Page 23: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

svaku mrežu izvršio sam višestruka pokretanja19 (treniranje i zatim testiranje) za a) i b) skupovepodataka kako bi dobio bolji dojam o rezultatima. Zadnji redak tablica označava aritmetičkusredinu P po stupcima za dana pokretanja. U tablicama za skup b) stupci sadrže: osnovni crno-bijeli skup, osnovni skup na koji je primijenjeno binarno određivanje praga (BOP u tablicama),osnovni skup na koji je primijenjeno globalno ujednačavanje histograma (GUH u tablicama) iosnovni skup na koji je primijenjeno adaptivno ujednačavanja histograma (AUH u tablicama).

Prvo navodim rezultate za skup a).

Tablica 1. Preciznosti klasificiranja prve mreže za 10 pokretanja na skupu podataka od tri skenirane stranice na kojem suprimijenjeni pomak, rotacija i šum.

Rbr. pokretanja Skup podataka a)1 0.9973552 0.9993393 0.9993394 0.9984575 0.9964736 0.9984577 0.9973558 0.9869939 0.99911810 0.998236P 0.99711

Tablica 2. Preciznosti klasificiranja konvolucijske mreže za 10 pokretanja na skupu podataka od tri skenirane stranice nakojem su primijenjeni pomak, rotacija i šum.

Rbr. pokretanja Skup podataka a)1 0.999782 0.9988983 0.9993394 0.9973555 1.06 0.9995597 0.9988988 0.9984579 0.99955910 0.99978P 0.99916

Za obje mreže preciznosti su (unatoč dodanom pomaku, rotaciji i šumu) gotovo 100%. To se imoglo očekivati pošto su podaci za treniranje i testiranje iz istog izvora.

Slijede rezultati za skup b).

19Umjesto ručnog pokretanja istih skripti više puta, napisao sam skriptu caller.py (prilog 14.6).

21

Page 24: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

Tablica 3. Preciznosti klasificiranja prve mreže za 10 pokretanja na skupovima podataka nastalim na temelju 200 ručnosegmentiranih slova iz misala.

Rbr. pokretanja Osnovni skup BOP GUH AUH1 0.965 0.98 0.985 0.972 0.99 0.98 0.985 0.983 0.97 0.97 0.98 0.9754 0.97 0.975 0.98 0.975 0.965 0.965 0.98 0.986 0.94 0.965 0.955 0.957 0.97 0.975 0.985 0.9858 0.97 0.975 0.975 0.969 0.975 0.985 0.98 0.9810 0.96 0.975 0.98 0.97P 0.9675 0.9745 0.9785 0.972

Tablica 4. Preciznosti klasificiranja konvolucijske mreže za 10 pokretanja na skupovima podataka nastalim na temelju 200ručno segmentiranih slova iz misala.

Rbr. pokretanja Osnovni skup BOP GUH AUH1 0.945 0.975 0.98 0.742 0.99 0.99 0.995 0.933 0.965 0.975 0.985 0.844 0.985 0.975 0.99 0.785 0.98 0.965 0.985 0.866 0.97 0.985 0.98 0.8357 0.945 0.965 0.965 0.788 0.975 0.99 0.99 0.919 0.975 0.99 0.995 0.8310 0.945 0.995 0.99 0.7P 0.9675 0.9805 0.9855 0.8205

Iako se mreže dosta razlikuju po arhitekturi, dale su vrlo slične rezultate. Druga mreža je dalanešto bolje rezultate za drugi i treći testni skup, dok je prva mreža dala znatno bolje rezultateza četvrti skup. Preciznosti za prva tri stupaca gornjih dviju tablica su preko 95%, što je visoko,ali i dalje niže nego rezultati u prve dvije tablice. Kroz izradu, treniranje i testiranje mreža,kvaliteta i veličina skupa podataka za treniranje pokazala se bitnija nego arhitektura.

Što se vremena treniranja tiče, prva mreža brža je od konvolucijske mreže. Treniranje za prvumrežu izvrši za nešto manje od 10 s. Konvolucijska mreža treniranje na istom skupu poda-taka obavi za otprilike 93 s. Prva mreža je očito brža pošto ima samo ulazni i izlazni sloj.Konvolucijska mreža obavlja mnogo više izračuna pošto ima više skrivenih slojeva.

22

Page 25: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

10 Zaključak

U radu sam predstavio jedan sveobuhvatni primjer strojnog učenja. Na početku navodim kakosam odabrao i izradio svoje skupove podataka (skupove za treniranje i skupove za testiranje).Slijede primjeri strojnog učenja realizirani kroz dvije različite neuronske mreže implementiraneTensorFlowom. Uz opis tih mreža donosim rezultate njihovog predviđanja na više skupovatestnih podataka. Obje mreže su poslužile za klasifikaciju (tj. optičko raspoznavanje) slova uglateglagoljice. Obje su imale sličnu preciznost klasifikacije od preko 95% za prva tri testna skupatemeljenih na misalu. Bilo je potrebno dosta eksperimentiranja kod određivanja arhitekture iparametara za dobivanje željenih rezultata (čak i uz korištenje gotovih primjera arhitektura). Toukazuje kako su neuronske mreže složeni matematički aparat koji nije intuitivno lako razumjeti(potrebno je poznavanje više područja matematike) i implementirati.

Rezultate klasifikacije bi se naravno moglo dalje poboljšati. Ovdje se logično nameću dva pos-tupka: a) proširivanje skupa podataka (i kvantitativno i kvalitativno) i b) definiranje sofisticira-nijih mreža. Skup podataka za treniranje bi se mogao proširiti skeniranjem većeg broja stranica.Stranice bi uz nove fontove mogle sadržavati i ručno pisanu glagoljicu. Naravno, ako bi cilj bioklasificirati znakove iz misala, trebalo bi razmotriti izradu skupa za treniranje na temelju slovaiz njega. Skup bi se zatim opet mogao umjetno prošiti (šum, rotacija, razne distorzije itd.). Savećim skupom prirodno se javlja pitanje brzine treniranja modela. Kako TensorFlow podržavaizvođenje izračuna na grafičkim karticama, mogla bi se usporediti CPU i GPU vremena trenira-nja mreža. Što se neuronskih mreža tiče, postojeće bi se mogle izmijeniti sa drugačijim stopamaza učenje, aktivacijskim funkcijama, funkcijama pogreški itd. Mreže bi se mogle proširiti do-davanjem više različitih skrivenih slojeva sa različitim brojem (i vrstom) neurona. U radu nisupredstavljene cikličke neuronske mreže (engl. recurrent neural network, RNN).

Što se samog TensorFlowa tiče, smatram da je to kvalitetan alat za modeliranje neuronskihmreža koji daje veliku slobodu kod implementacije. Također, ima kvalitetnu dokumentaciju saobjašnjenim implementacijama jednostavnijih modela strojnog učenja. Prednost mu je i što imaprogramsko sučelje za Python čime se olakšava njegovo korištenje. Vjerujem da će popularnostTensorFlowa rasti, pogotovo ako ga Google bude i dalje aktivno razvijao kao biblioteku sanaglaskom na performanse.

Mislim da će popularnost neuronskih mreža i dalje rasti kako računalni hardver bude napredovao.Već danas imaju reputaciju jedne od najpopularnijih i najuspješnijih metoda za strojno učenje[25]. Pošto imaju široku upotrebu realno je očekivati da će područje rasti, vjerojatno u smjeruotkrivanja sofisticranijih modela hibridne prirode [26]. Očekujem da će se naglasak u budućnostipremjestiti sa klasificiranja na generiranje originalnog sadržaja po uzoru na ljudska djela [27].

23

Page 26: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

11 Literatura[1] ABOUT | OpenCV. adresa: http://opencv.org/about.html (pogledano 11. 2. 2016).[2] J. Dean, TensorFlow - Google’s latest machine learning system, open sourced for everyone,

studeni 2015. adresa: http://googleresearch.blogspot.com/2015/11/tensorflow-googles-latest-machine_9.html (pogledano 11. 2. 2016).

[3] NumPy — Numpy. adresa: http://www.numpy.org/ (pogledano 11. 2. 2016).[4] TensorFlow, en, Page Version ID: 710763504, ožujak 2016. adresa: https://en.wikipedia.

org/w/index.php?title=TensorFlow&oldid=710763504 (pogledano 19. 3. 2016).[5] J. Ward-Bailey, „Google chairman: We’re making ’real progress’ on artificial intelligence”,

Christian Science Monitor, rujan 2015, issn: 0882-7729. adresa: http://www.csmonitor.com/Technology/2015/0914/Google-chairman-We-re-making-real-progress-on-artificial-intelligence (pogledano 20. 3. 2016).

[6] TensorFlow – an Open Source Software Library for Machine Intelligence. adresa: https://www.tensorflow.org/ (pogledano 11. 2. 2016).

[7] RankBrain, en, Page Version ID: 710048505, ožujak 2016. adresa: https://en.wikipedia.org/w/index.php?title=RankBrain&oldid=710048505 (pogledano 20. 3. 2016).

[8] D. T. Larose i C. D. Larose, Discovering Knowledge in Data: An Introduction to DataMining, English, 2 edition. Hoboken: Wiley, srpanj 2014, isbn: 978-0-470-90874-7.

[9] Neuron, en, Page Version ID: 735402189, kolovoz 2016. adresa: https://en.wikipedia.org/w/index.php?title=Neuron&oldid=735402189 (pogledano 5. 9. 2016).

[10] Overfitting, en, Page Version ID: 732335668, srpanj 2016. adresa: https://en.wikipedia.org/w/index.php?title=Overfitting&oldid=732335668 (pogledano 4. 9. 2016).

[11] M. A. Nielsen, Neural Networks and Deep Learning. Determination Press, 2015. adresa:http://neuralnetworksanddeeplearning.com/ (pogledano 31. 8. 2016).

[12] Glagoljica, hr, Page Version ID: 4650149, siječanj 2016. adresa: https://hr.wikipedia.org/w/index.php?title=Glagoljica&oldid=4650149 (pogledano 11. 2. 2016).

[13] D. Zubrinic, Glagolitic fonts. adresa: http : / / www . croatianhistory . net / etf / gl -font.html (pogledano 11. 2. 2016).

[14] OpenCV: Contours : Getting Started. adresa: http://docs.opencv.org/master/d4/d73/tutorial_py_contours_begin.html#gsc.tab=0 (pogledano 10. 2. 2016).

[15] Y. LeCun, C. Cortes i C. Burges, MNIST handwritten digit database. adresa: http://yann.lecun.com/exdb/mnist/ (pogledano 11. 2. 2016).

[16] Uvod / Misal po zakonu rimskoga dvora 1483. adresa: http://db.nsk.hr/HeritageDetails.aspx?id=484 (pogledano 2. 9. 2016).

[17] Typographic ligature, en, Page Version ID: 730759110, srpanj 2016. adresa: https : / /en.wikipedia.org/w/index.php?title=Typographic_ligature&oldid=730759110(pogledano 2. 9. 2016).

[18] OpenCV: Image Thresholding. adresa: http://docs.opencv.org/master/d7/d4d/tutorial_py_thresholding.html#gsc.tab=0 (pogledano 10. 2. 2016).

[19] MNIST For ML Beginners. adresa: https://www.tensorflow.org/versions/v0.6.0/tutorials/mnist/beginners/index.html (pogledano 11. 2. 2016).

[20] Deep MNIST for Experts. adresa: https://www.tensorflow.org/versions/r0.10/tutorials/mnist/pros/index.html (pogledano 30. 8. 2016).

[21] Softmax function, en, Page Version ID: 702318561, siječanj 2016. adresa: https://en.wikipedia.org/w/index.php?title=Softmax_function&oldid=702318561 (pogledano11. 2. 2016).

[22] Gradient descent, en, Page Version ID: 703834692, veljača 2016. adresa: https://en.wikipedia.org/w/index.php?title=Gradient_descent&oldid=703834692 (pogledano11. 2. 2016).

24

Page 27: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

[23] Rectifier (neural networks), en, Page Version ID: 697474209, prosinac 2015. adresa: https://en.wikipedia.org/w/index.php?title=Rectifier_(neural_networks)&oldid=697474209 (pogledano 11. 2. 2016).

[24] D. Kingma i J. Ba, „Adam: A Method for Stochastic Optimization”, ArXiv:1412.6980 [cs],prosinac 2014, arXiv: 1412.6980. adresa: http://arxiv.org/abs/1412.6980 (pogledano16. 5. 2016).

[25] A. Karpathy, The Unreasonable Effectiveness of Recurrent Neural Networks. adresa: http://karpathy.github.io/2015/05/21/rnn-effectiveness/ (pogledano 10. 2. 2016).

[26] D. Maji, A. Santara, S. Ghosh, D. Sheet i P. Mitra, „Deep neural network and randomforest hybrid architecture for learning to detect retinal vessels in fundus images”, 201537th Annual International Conference of the IEEE Engineering in Medicine and BiologySociety (EMBC), kolovoz 2015, str. 3029–3032. doi: 10.1109/EMBC.2015.7319030.

[27] D. Johnson, Composing Music With Recurrent Neural Networks, kolovoz 2015. adresa:http://www.hexahedria.com/2015/08/03/composing- music- with- recurrent-neural-networks/ (pogledano 10. 2. 2016).

25

Page 28: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

12 Popis slika1 Struktura tipičnog biološkog neurona. Sa lijeva na desno: jezgra (engl. nucleus),

dendrit (engl. dendrite), soma (engl. cell body), akson (engl. axon), mijelinskaovojnica (engl. myelin sheath), Ranvierovo suženje (engl. node of Ranvier), telo-dendron (engl. axon terminal) i Schwannova stanica (engl. Schwann cell). Slikapreuzeta sa [9]. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2 Ilustracija jednog neurona neuronske mreže. Ulazi se množe pripadnim težinamate sumiraju zajedno sa sklonošću. Aktivacijska funkcija uzima tu sumu kako biproizvela izlaz neurona. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

3 Shema jednostavne neuronske mreže sa ulaznim slojem, jednim skrivenim slojemi izlaznim slojem sa jednim čvorom. . . . . . . . . . . . . . . . . . . . . . . . . . 6

4 Izračun prve konvolucije za receptivno polje veličine 5× 5. Ulazni sloj je dimenzija28 × 28, konvolucijski 24 × 24. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

5 Izračun druge konvolucije za primjer u slici 4. . . . . . . . . . . . . . . . . . . . . 76 Konvolucijski sloj u praksi računa više svojstvenih mapa. Ovdje je zbog pregled-

nosti prikazano samo njih tri. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 Max-udruživanje se primjenjuje za svaku svojstvenu mapu posebno. . . . . . . . 98 Prvih osam slova, od ukupno njih 27, korištenih u generiranju skupova podataka

za treniranje. Primijetimo različiti znak za "E" u trećem fontu. . . . . . . . . . . 119 Dio 115. stranice misala dostupnog na [16]. . . . . . . . . . . . . . . . . . . . . . 1210 Testirane tehnike određivanja praga. Sve imaju vrijednost praga 200. Slika je

generirana pomoću skripte data_samples.py (prilog 14.3). . . . . . . . . . . . . 1311 Pravokutnici opisani oko pronađenih kontura na dijelu slike sa podacima za tre-

niranje. Slika je generirana pomoću skripte data_samples.py. . . . . . . . . . . 1412 Primjer sortiranih segmenata na dijelu slike. Slika je generirana pomoću skripte

data_samples.py. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1413 Primjer uzoraka za font Glagoljica euglata. Uzorcima je postavljena fiksna širina

i visina nakon automatskog segmentiranja sa crno-bijele slike. . . . . . . . . . . . 1514 Primjer uzoraka (font Glagoljica euglata) kojima su primijenjeni pseudo-slučajni

pomak, rotacija i šum. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1515 Primjer slova iz skupova za testiranje temeljenih na misalu. Na vrhu su slova iz

osnovnog skupa po kojem su nastala tri donja skupa. . . . . . . . . . . . . . . . . 1616 Preciznost na testnom skupu podataka temeljenom na misalu tijekom treniranja

za prvu mrežu. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1817 Arhitektura implementirane konvolucijske mreže. Kod veličina dimenzija ulaza

i ostalih slojeva uzete su u obzir i ispune. Također, na slici nije označeno dakonvolucijski slojevi i predzadnji (potpuno povezani) sloj koriste ReLU neurone. . 20

18 Preciznost na testnom skupu podataka temeljenom na misalu tijekom treniranjakonvolucijske mreže. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

13 Popis tablica1 Preciznosti klasificiranja prve mreže za 10 pokretanja na skupu podataka od tri

skenirane stranice na kojem su primijenjeni pomak, rotacija i šum. . . . . . . . . 212 Preciznosti klasificiranja konvolucijske mreže za 10 pokretanja na skupu podataka

od tri skenirane stranice na kojem su primijenjeni pomak, rotacija i šum. . . . . 213 Preciznosti klasificiranja prve mreže za 10 pokretanja na skupovima podataka

nastalim na temelju 200 ručno segmentiranih slova iz misala. . . . . . . . . . . . 224 Preciznosti klasificiranja konvolucijske mreže za 10 pokretanja na skupovima po-

dataka nastalim na temelju 200 ručno segmentiranih slova iz misala. . . . . . . . 22

26

Page 29: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

14 Prilozi

Pripremu skupova podataka za neuronske mreže moguće je učiniti skriptama segment.py imisal_data.py. Prva skripta automatski obrađuje skenirane stranice sa glagoljicom dok drugaobrađuje već segmentirana slova. Obje skripte zahtijevaju pripremljene datoteke sa oznakamauzoraka. Skriptu data_samples.py nije potrebno iskoristiti u pripremi podataka; ona služijedino za vizualizaciju određenih dijelova obrade stranica u segment.py.

Prva neuronska mreža pokreće se sa basic_net.py. Skupovi podataka za treniranje i testiranjese definiraju unutar skripte. Konvolucijska neuronska mreža pokreće se sa conv_net.py. Kao iza prvu mrežu, i ovdje se skupovi podataka za treniranje i testiranje moraju definirati unutarskripte. Za praktičnija višestruka pokretanja skripti basic_net.py i conv_net.py napisana jeskripta caller.py.

Sve skripte u nastavku napisane su za Python 3.

14.1 Skripta segment.py

Skripti se kod pokretanja mora proslijediti barem jedna skenirana slika. Sa proslijeđenih stranicaće se automatski segmentirati i označiti slova. Za svaku stranicu mora postojati i tekstualnadatoteka sa oznakama slova sa stranica. Ime te datoteke jednako je imenu slike stranice sadodanim sufiksom _labels. numpy polje slova će se spremiti posebno za svaku stranicu (sapripadnim numpy poljima oznaka). Dodatno, sva slova biti će spremljena i u zajedničkom polju(sa pripadnim poljem oznaka). Dodavanje pseudo-slučajnog pomaka, rotacije i šuma definira seu skripti kroz varijable shift, rotate i noise. Valja spomenuti da su moguće oznake (tj. slova)za skup podataka definirane u varijabli ALPHABET. Varijable letter_w i letter_h sadrže noveuniformne širine i visine segmentiranih slova, dok thresh_value sadrži vrijednost za binarnoodređivanje praga.

1 import cv22 from sys import argv3 import numpy as np4 from matplotlib import pyplot as plt5 import matplotlib.gridspec as gridspec6 from operator import itemgetter7 from os.path import exists8 from os import makedirs9 import random

10 from math import sqrt11 from datetime import datetime12

13

14 ALPHABET = "ABCČĆDÐEFGHIJKLMNOPRSŠTUVZŽ"15

16 def get_rows_limits(imgray, image_color, thresh_value, row_min_width=0.1 , fig_num_1=1 , fig_num_2=2 , save=False):

17 '''18 Vrati y koordinate granica izmedju redaka.19 Funkcija u konzoli ispisuje dimenzije slike i broj nadjenih redaka.20 Opcionalno funkcija spremi retke i nadjene granice na dvije slike.21

22 Args:23 imgray: crno-bijela slika.24 image_color: ista slika u boji.25 thresh_value: threshold vrijednost (0 -255).26 row_min_width: minimalna sirina retka (postotak ukupne sirine stranice).27 fig_num_1: broj (id) prve matplotlib figure.28 fig_num_2: broj (id) druge matplotlib figure.

27

Page 30: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

29 save: spremi oznacene slike.30

31 Returns:32 limits_ys: y koordinate granica.33 '''34 # bluraj retke kako bi dobio crne horizontalne "mrlje"35 imgray = cv2.GaussianBlur(imgray, (95, 1), 0) # blur-matrica rucno postavlj

ena na 95x1 (bluraj horizontalno)36 ret, thresh = cv2.threshold(imgray, thresh_value, 255, cv2.THRESH_BINARY) #

rucno postavljen limit za threshold37

38 thresh_copy = cv2.cvtColor(thresh.copy() , cv2.COLOR_GRAY2RGB)39

40 im_height, im_width = imgray.shape[:2]41 print("Sirina slike:", im_width, "px")42 print("Visina slike:", im_height, "px")43

44 # nadji pravokutne konture koje opisuju retke45 image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHA

IN_APPROX_SIMPLE)46 rects = []47 for i in range(len(contours)):48

49 # provjeri ako je kontura prvo dijete konture koje opisuje papir50 # znaci, traze se vanjske konture redaka51 # [Next, Previous, First_Child, Parent]52 if hierarchy[0][ i][3] == 0:53

54 x, y, w, h = cv2.boundingRect(contours[ i])55 # uzmi retke koji su siri od odredjene granice56 if w > im_width * row_min_width:57 rects.append([x, y, w, h])58

59 rects_sorted = sorted(rects, key=itemgetter(1)) # sortiraj po y koordinati60 num_rows = len(rects)61 print("Br. pronadjenih redaka:", num_rows)62

63 image_color_copy = image_color.copy()64 limits_ys = []65

66 # nadji y koordinate granica izmedju redaka67 for i in range(num_rows - 1):68

69 current_row_y = rects_sorted[ i][1]70 current_row_h = rects_sorted[ i][3]71 next_row_y = rects_sorted[ i+1][1]72 limit_y = int(current_row_y + current_row_h + (next_row_y - (current_row

_y + current_row_h)) / 2)73 limits_ys.append(limit_y)74

75 # nacrtaj granice na dvije slike76 cv2.line(image_color_copy, (0, limit_y), (im_width, limit_y), (255 , 0,

0), 5)77 cv2.line(thresh_copy, (0, limit_y), (im_width, limit_y), (255 , 0, 0), 5)78

79 row_num = 180 for r in rects_sorted:81 # nacrtaj pravokutnike oko redaka82 cv2.rectangle(image_color_copy, # slika83 (r[0] , r[1]) , # gornji-lijevi kut84 (r[0] + r[2] , r[1] + r[3]) , # donji-desni kut85 (0, 255, 0), # boja86 2) # debljina linije

28

Page 31: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

87 # dodaj redni broj retka na sliku88 cv2.putText(image_color_copy, # slika89 str(row_num), # tekst90 (r[0] -1 , r[1] -1) , # x i y koordinate teksta (donji-

lijevi kut)91 cv2.FONT_HERSHEY_SIMPLEX, # font teksta92 1, # velicina (tj. scale) fonta93 (0, 0, 255) , # boja teksta94 2, # debljina slova95 cv2.LINE_AA) # vrsta linije96

97 row_num += 198

99 if save:100

101 # thresholding bluranih redaka i granice102 plt.figure(fig_num_1)103 plt.imshow(thresh_copy)104 plt.axis('off')105 plt.savefig('rows_blured.png', bbox_inches= 'tight', pad_inches=0.0 , dp

i=300)106

107 # oznaceni reci i granice108 plt.figure(fig_num_2)109 plt.imshow(image_color_copy)110 plt.axis('off')111 plt.savefig('rows_limits.png', bbox_inches= 'tight', pad_inches=0.0 , dp

i=300)112

113 return limits_ys114

115 def letters_contours(contours, hierarchy):116 '''117 Vrati listu opisanih pravokutnika za segmentirana slova.118

119 Args:120 contours: konture (svih nadjenih objekata, i unutaranje i vanjske).121 hierarchy: info o hijerarhiji kontura.122

123 Returns:124 rects: lista pravokutnika koji opisuju vanjske konture slova.125 '''126 rects = []127

128 for i in range(len(contours)):129

130 # provjeri ako je kontura prvo dijete konture koje opisuje papir131 # znaci traze se vanjske konture slova132 # [Next, Previous, First_Child, Parent]133 if hierarchy[0][ i][3] == 0:134

135 x, y, w, h = cv2.boundingRect(contours[ i])136 # izbaci male objekte (mrlje, noise itd.)137 # velicina rucno postavljena138 if h > 15 and w > 15:139 rects.append([x, y, w, h])140

141 print("Br. pronadjenih slova:", len(rects))142 return rects143

144 def order_rects(rects, limits_ys):145 '''146 Sortiraj pravokutnike koji opisuju slova.

29

Page 32: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

147 Novi redoslijed slova je redoslijed kojim bi se citala (lijevo-desno, gore-dolje).

148

149 Args:150 rects: lista pravokutnika koji opisuju slova.151 limits_ys: y koordinate granica izmedju redaka slova.152

153 Returns:154 ordered_rects: lista sortiranih pravokutnika koji opisuju slova.155 '''156 ordered_rects = []157 num = 0158

159 # prodji stranicu redak po redak160 for i in range(len(limits_ys) + 1):161

162 # pravokutnici koji opisuju vanjsku konturu slova u trenutnom retku163 rects_row = []164

165 # prvi redak166 if i == 0:167 for rect in rects:168 if rect[1] < limits_ys[ i]:169 rects_row.append(rect)170 # zadnji redak171 elif i == len(limits_ys):172 for rect in rects:173 if rect[1] > limits_ys[i - 1]:174 rects_row.append(rect)175 # ostali reci176 else:177 for rect in rects:178 if rect[1] < limits_ys[i] and rect[1] > limits_ys[i - 1]:179 rects_row.append(rect)180

181 # sortiraj po x osi182 rects_row = sorted(rects_row, key=itemgetter(0))183 ordered_rects.extend(rects_row)184

185 return ordered_rects186

187 def draw_letters_contours(rects, limits_ys, image, fig_num=3):188 '''189 Na skeniranu stranicu nacrtaj granice redaka, pravokutnike oko slova i redne

brojeve slova.190 Prikazi anotiranu figuru.191

192 Args:193 rects: lista pravokutnika opisanih oko slova.194 limits_ys: y koordinate granica izmedju redaka.195 image: skenirana stranica (u boji).196 fig_num: id nove matplotlib figure.197

198 Returns:199 Funkcija ne vraca vrijednost.200 '''201 plt.figure(fig_num)202 image_contours = image.copy()203 im_height, im_width = image.shape[:2]204 num = 1205

206 for i in range(len(limits_ys)):207 # nacrtaj granicu retka

30

Page 33: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

208 cv2.line(image_contours, # slika209 (0, limits_ys[ i]) , # pocetna tocka210 (im_width, limits_ys[ i]) , # krajnja tocka211 (255 , 0, 0), # boja linije212 5) # debljina linije213

214 for r in rects:215 # nacrtaj pravokutnik oko slova216 cv2.rectangle(image_contours, # slika217 (r[0] , r[1]) , # gornji-lijevi kut218 (r[0] + r[2] , r[1] + r[3]) , # donji-desni kut219 (0, 255, 0), # boja220 2) # debljina linije221 # izracunaj y koordinatu teksta na slici222 padding, font, font_scale, thick = 2, cv2.FONT_HERSHEY_SIMPLEX, 0.7, 1223 if num % 2 != 0:224 y = r[1] - padding225 else:226 text_w, text_h = cv2.getTextSize(str(num), font, font_scale, thick)

[0]227 y = r[1] + r[3] + padding + text_h228 # dodaj redni broj slova na sliku229 cv2.putText(image_contours, # slika230 str(num), # tekst231 (r[0] - 2, y), # x i y koordinate teksta (donji-lijevi ku

t)232 font, # font teksta233 font_scale, # velicina (tj. scale) fonta234 (0, 0, 255) , # boja teksta235 thick, # debljina slova236 cv2.LINE_AA) # vrsta linije237 num += 1238

239 plt.imshow(image_contours)240 plt.axis('off')241 plt.show()242

243 def save_letters(image, ordered_rects, data_dir, shift, rotate, noise, new_w, new_h, save=False):

244 '''245 Vrati listu segmentiranih slova. Slova imaju nove uniformne dimenzije.246 Eventualno spremi i PNG slike pojedinacnih slova.247

248 Args:249 image: skenirana stranica.250 ordered_rects: sortirana lista pravokutnika opisanih oko slova.251 data_dir: naziv direktorija za PNG slike.252 shift: pomakni sliku za slučajnu vrijednost.253 rotate: rotiraj sliku.254 noise: dodaj sum.255 new_w: nova sirina slova.256 new_h: nova visna slova.257 save: definira da li zelimo spremiti PNG slike slova.258

259 Returns:260 letters: lista segmentiranih slova.261 '''262 letters = []263

264 # ako treba napravi direktorij za segmentirana slova265 if save:266 if not exists(data_dir):267 makedirs(data_dir)

31

Page 34: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

268

269 # izdvoji slova, po potrebi primijeni dodatnu obradu i spremi slova kao slike

270 counter = 1271 for r in ordered_rects:272 x, y, w, h = r[0] , r[1] , r[2] , r[3]273 crop = image[y: y+h, x: x+w]274 letter = cv2.resize(crop, (new_w, new_h))275 if shift:276 letter = shift_xy(letter, -1, 1)277 if rotate:278 letter = random_rotation(letter, -8, 8)279 if noise:280 letter = add_noise(letter, -80, 80)281 if save:282 name = str(counter).rjust(4, '0')283 cv2.imwrite(data_dir + '/' + name + '.png', letter)284 letters.append(letter)285 counter += 1286

287 return letters288

289 def letters_tf_array(letters, letter_w, letter_h):290 '''291 Pretvori listu slova u numpy array prikladan za tensorflow.292

293 Args:294 letters: lista segmentiranih slova.295 letter_w: sirina slova.296 letter_h: visina slova.297

298 Returns:299 data: numpy array sa segmentiranim slovima.300 '''301 data = np.empty((0 , letter_w * letter_h), dtype=np.float32)302

303 for letter in letters:304 letter = letter.astype(np.float32)305 letter = letter / 255 # normaliziraj vrijednosti306 letter = letter.ravel()307 data = np.vstack((data, letter)) # dodaj slovo u polje slova308

309 return data310

311 def labels_tf_array(labels_dump, data, alphabet):312 '''313 Vrati numpy array oznaka za segmentirana slova.314 Za neregularne oznake izbaci uzorak i oznaku.315

316 Args:317 labels_dump: znakovni niz oznaka (redoslijed se podudra sa slovima u pol

ju slova).318 alphabet: abeceda (dopustena slova).319

320 Returns:321 labels: numpy array one-hot arrayeva.322 data_new: numpy array slova.323 '''324 data_new = np.copy(data)325 alphabet_size = len(alphabet)326 labels = np.empty((0 , alphabet_size), dtype=np.float32)327

328 for i in range(len(labels_dump)):

32

Page 35: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

329

330 if labels_dump[i] in alphabet:331 one_hot = np.zeros(alphabet_size, dtype=np.float32)332 idx = alphabet.find(labels_dump[ i])333 one_hot[idx] = 1334 labels = np.vstack((labels, one_hot))335 else:336 data_new = np.delete(data_new, (i), axis=0) # izbrisi redak337

338 return labels, data_new339

340 def shift_xy(img, min_val=-1, max_val=1):341 '''342 Pomakni sliku na x i y osi za slucajnu vrijednost iz [min_val, max_val].343

344 Args:345 img: slika.346 min_val: minimalni pomak u pikselima.347 max_val: maksimalni pomak u pikselima.348

349 Returns:350 shifted: pomaknuta slika.351 '''352 rows, cols = img.shape353

354 pos = np.random.randint(min_val, max_val + 1, 2)355 M = np.float32([[1 , 0, pos[0]] , [0, 1, po s[1]]])356 shifted = cv2.warpAffine(img, M, (cols, rows), borderMode=cv2.BORDER_CONSTAN

T, borderValue=(255 , 255, 255))357

358 return shifted359

360 def random_rotation(img, min_angle=-10, max_angle=10):361 '''362 Rotiraj sliku za slucajnu vrijednost.363

364 Args:365 img: slika.366 min_angle: minimalni kut.367 max_angle: maksimalni kut.368

369 Returns:370 rotated_img: rotirana slika.371 '''372 rows, cols = img.shape373

374 angle = random.uniform(min_angle, max_angle)375 M = cv2.getRotationMatrix2 D((cols / 2, rows / 2), angle, 1)376 rotated_img = cv2.warpAffine(img, M, (cols, rows), borderMode=cv2.BORDER_CON

STANT, borderValue=(255 , 255, 255))377

378 return rotated_img379

380 def add_noise(img, min_val=-80, max_val=80):381 '''382 Vrati novu sliku sa dodanim sumom.383

384 Args:385 img: originalna slika.386 min_val: minimalna vrijednost dodanog suma.387 max_val: maksimalna vrijednost dodanog suma.388

389 Returns:

33

Page 36: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

390 noisy: slika sa sumom.391 '''392 rows, cols = img.shape393 noise = np.random.randint(min_val, max_val + 1, (rows, cols))394 noisy = img.copy()395

396 for i in range(len(noisy)):397 for j in range(len(noisy[ i])):398 pixel = noisy[ i][ j] + noise[ i][ j]399 if pixel >= 0 and pixel <= 255:400 noisy[ i][ j] = pixel401

402 return noisy403

404 def draw_all_letters(letters):405 '''406 Spremi sliku svih slova u kvadratnoj matrici.407

408 Args:409 letters: polje slova/slika.410

411 Returns:412 Funkcija ne vraca vrijednost.413 '''414 num = len(letters)415 num_square = num416

417 while(True):418 current = sqrt(num_square)419 if current.is_integer():420 break421 else:422 num_square += 1423

424 plt.figure(figsize=(sqrt(num_square), sqrt(num_square)))425 gs = gridspec.GridSpec(int(sqrt(num_square)), int(sqrt(num_square)))426 gs.update(wspace=0.1 , hspace=0)427

428 for i in range(num):429 ax = plt.subplot(gs[ i])430 plt.imshow(letters[i], 'gray')431 ##plt.axis('off')432 plt.xticks([]) , plt.yticks([])433 ##ax.set_xticklabels([]) , ax.set_yticklabels([])434 ax.set_aspect('equal')435

436 plt.savefig('img.png', bbox_inches= 'tight', dp i=120)437

438

439 if __name__ == "__main__":440

441 try:442 argv[1]443 except IndexError:444 print("Nije dano ime skenirane slike.\nIzlaz iz skripte...")445 exit()446

447 pages = argv[1:]448

449 page_num = 0450 alphabet_size = len(ALPHABET)451 letter_w, letter_h = 28, 28452 thresh_value = 200

34

Page 37: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

453

454 all_pages_data = np.zeros((0 , letter_w * letter_h), dtype=np.float32)455 all_pages_labels = np.zeros((0 , alphabet_size), dtype=np.float32)456 all_pages_filename = ""457

458 shift, rotate, noise = True, True, True459

460 for page in pages:461

462 page_num += 1463 print(" ** Slika br.", page_num, "**")464

465 im = cv2.imread(page, 1) # ucitaj sliku u boji466 imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # crno-bijela slika467

468 ret, thresh = cv2.threshold(imgray, thresh_value, 255, cv2.THRESH_BINARY) # rucno postavljen limit za threshold

469

470 # nadji konture slova471 image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, c

v2.CHAIN_APPROX_SIMPLE)472 rects = letters_contours(contours, hierarchy)473

474 # sortiraj slova475 limits_ys = get_rows_limits(imgray, im, thresh_value)476 ordered_rects = order_rects(rects, limits_ys)477 ##draw_letters_contours(ordered_rects, limits_ys, im)478

479 # procitaj oznake480 data_no_ext = page[: -4] # bez ekstenzije481 labels_file = data_no_ext + '_labels.txt'482 with open(labels_file, encoding='utf-8') as f:483 labels_dump = f.readline()484 labels_dump = labels_dump.replace('\ufeff', '')485

486 # spremi slova i njihove oznake487 letters = save_letters(imgray, ordered_rects, data_no_ext, shift, rotat

e, noise, new_w=letter_w, new_h=letter_h, save=False)488 data = letters_tf_array(letters, letter_w, letter_h)489 labels, data = labels_tf_array(labels_dump, data, ALPHABET)490

491 ##draw_all_letters(letter s[:49])492

493 # pojedina stranica494 np.save(data_no_ext, data)495 np.save(data_no_ext + '_labels', labels)496

497 # sve stranice498 all_pages_filename += data_no_ext[data_no_ext.rfin d("/") + 1:] + "__"499 all_pages_data = np.vstack((all_pages_data, data))500 all_pages_labels = np.vstack((all_pages_labels, labels))501

502

503 dir_name = '.' ##page s[0][: pages[0].rfin d("/") ] # ime direktorija prve slike

504

505 if noise:506 all_pages_filename = 'noise_' + all_pages_filename507 if rotate:508 all_pages_filename = 'rotate_' + all_pages_filename509 if shift:510 all_pages_filename = 'shift_' + all_pages_filename511 timestamp = '{:% Y-%m-%d_%H-%M} '.format(datetime.now())

35

Page 38: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

512 all_pages_filename = timestamp + "_" + all_pages_filename[: -2] # dodaj vrijeme, makni zadnji "__"

513

514 np.save(dir_name + "/" + all_pages_filename, all_pages_data)515 np.save(dir_name + "/" + all_pages_filename + '_labels', all_pages_labels)516 print("\nPodaci spremljeni u:", dir_name + "/" + all_pages_filename + "(_lab

els)" + ".npy")517 print("Oblik polja slova:", all_pages_data.shape)518 print("Oblik polja oznaka:", all_pages_labels.shape)

14.2 Skripta misal_data.py

Kod pokretanje ove skripte potrebno je proslijediti barem jedno ime datoteke sa oznakamasegmentiranih slova. Svaki redak tih datoteka sadrži ime slike jednog slova i njegovu oznakuodvojenu razmakom. Slova i datoteka sa oznakama moraju biti u istom direktoriju. VarijablaALPHABET sa mogućim oznakama slova (uz još nekoliko funkcija) se uvozi iz skripte segment.py.Skripta lokalno sprema četiri numpy polja slova i četiri pripadnih polja oznaka. Svako od tihčetiri polja slova sadrži sva slova. Razlike su u obradi slova; prvo polje sadrži crno-bijela slova,drugo sadrži slova na koja je primijenjeno binarno određivanje praga, treće sadrži slova nakoja je primijenjeno globalno ujednačavanje histograma i četvrto polje sadrži slova na koja jeprimijenjeno adaptivno ujednačavanje histograma.

1 import cv22 from sys import argv3 import numpy as np4 from matplotlib import pyplot as plt5 import matplotlib.gridspec as gridspec6 from segment import ALPHABET, labels_tf_array, letters_tf_array, draw_all_letter

s7

8

9 def show_image(im, color=True):10 '''11 Prikazi sliku.12

13 Args:14 im: slika.15 color: da li je slika u boji.16

17 Returns:18 Funkcija ne vraca vrijednost.19 '''20 plt.figure()21 if color:22 plt.imshow(cv2.cvtColor(im.copy() , cv2.COLOR_BGR2RGB))23 else:24 plt.imshow(im.copy() , cmap='gray')25 plt.axis('off')26 plt.show()27

28

29 if __name__ == "__main__":30

31 try:32 argv[1]33 except IndexError:34 print("Nije dano ime 'labels' datoteke.\nIzlaz iz skripte...")35 exit()36

36

Page 39: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

37 labels_files = argv[1:]38

39 alphabet_size = len(ALPHABET)40 letter_w, letter_h = 28, 2841 thresh_value = 15042

43 all_data_gray = np.zeros((0 , letter_w * letter_h), dtype=np.float32)44 all_data_thresh = np.zeros((0 , letter_w * letter_h), dtype=np.float32)45 all_data_gray_equ = np.zeros((0 , letter_w * letter_h), dtype=np.float32)46 all_data_gray_clahe = np.zeros((0 , letter_w * letter_h), dtype=np.float32)47

48 all_labels_gray = np.zeros((0 , alphabet_size), dtype=np.float32)49 all_labels_thresh = np.zeros((0 , alphabet_size), dtype=np.float32)50 all_labels_gray_equ = np.zeros((0 , alphabet_size), dtype=np.float32)51 all_labels_gray_clahe = np.zeros((0 , alphabet_size), dtype=np.float32)52

53 all_dirs_filename = ""54

55 for labels_file in labels_files:56

57 letters_gray = []58 letters_thresh = []59 letters_gray_equ = []60 letters_gray_clahe = []61

62 with open(labels_file, encoding='utf-8') as infile:63 # svaki redak ima oblik "ime_slike.jpg oznaka"64 files_and_labels = infile.read()65

66 # u istom diru su slike slova67 labels_path = labels_file[:labels_file.rfind('/')] # put do datoteke be

z te datoteke68 labels_dir = labels_path[labels_path.rfind('/') + 1:] # ime direktorija69

70 labels_dump = ""71

72 print(" * Obrada", labels_file, "*")73

74 for line in files_and_labels.split('\n'):75

76 letter_file, letter_label = line.split()77

78 im_file = labels_path + '/' + letter_file79 ##print("Slika:", im_file, '(' + letter_label + ')')80

81 im = cv2.imread(labels_path + '/' + letter_file, 1) # ucitaj slikuu boji (BGR)

82 imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)83

84 ret, thresh = cv2.threshold(imgray, thresh_value, 255, cv2.THRESH_BINARY)

85

86 imgray_equ = cv2.equalizeHist(imgray)87

88 clahe = cv2.createCLAHE(clipLimit=1.0 , tileGridSize=(3 , 3))89 imgray_clahe = clahe.apply(imgray)90

91 letter_gray = cv2.resize(imgray, (letter_w, letter_h))92 letter_thresh = cv2.resize(thresh, (letter_w, letter_h))93 letter_gray_equ = cv2.resize(imgray_equ, (letter_w, letter_h))94 letter_gray_clahe = cv2.resize(imgray_clahe, (letter_w, letter_h))95

96 letters_gray.append(letter_gray)

37

Page 40: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

97 letters_thresh.append(letter_thresh)98 letters_gray_equ.append(letter_gray_equ)99 letters_gray_clahe.append(letter_gray_clahe)

100

101 labels_dump += letter_label102

103 ##draw_all_letters(letters_gray[:])104

105 # spremi slova i njihove oznake106 data_gray = letters_tf_array(letters_gray, letter_w, letter_h)107 data_thresh = letters_tf_array(letters_thresh, letter_w, letter_h)108 data_gray_equ = letters_tf_array(letters_gray_equ, letter_w, letter_h)109 data_gray_clahe = letters_tf_array(letters_gray_clahe, letter_w, letter_

h)110

111 labels_gray, data_gray = labels_tf_array(labels_dump, data_gray, ALPHABET)

112 labels_thresh, data_thresh = labels_tf_array(labels_dump, data_thresh, ALPHABET)

113 labels_gray_equ, data_gray_equ = labels_tf_array(labels_dump, data_gray_equ, ALPHABET)

114 labels_gray_clahe, data_gray_clahe = labels_tf_array(labels_dump, data_gray_clahe, ALPHABET)

115

116 # sve "labels" datoteke117 all_dirs_filename += labels_dir + "__"118

119 all_data_gray = np.vstack((all_data_gray, data_gray))120 all_data_thresh = np.vstack((all_data_thresh, data_thresh))121 all_data_gray_equ = np.vstack((all_data_gray_equ, data_gray_equ))122 all_data_gray_clahe = np.vstack((all_data_gray_clahe, data_gray_clahe))123

124 all_labels_gray = np.vstack((all_labels_gray, labels_gray))125 all_labels_thresh = np.vstack((all_labels_thresh, labels_thresh))126 all_labels_gray_equ = np.vstack((all_labels_gray_equ, labels_gray_equ))127 all_labels_gray_clahe = np.vstack((all_labels_gray_clahe, labels_gray_cl

ahe))128

129 np.save(all_dirs_filename + "gray", all_data_gray)130 np.save(all_dirs_filename + "thresh", all_data_thresh)131 np.save(all_dirs_filename + "gray_equ", all_data_gray_equ)132 np.save(all_dirs_filename + "gray_clahe", all_data_gray_clahe)133

134 np.save(all_dirs_filename + "gray_labels", all_labels_gray)135 np.save(all_dirs_filename + "thresh_labels", all_labels_thresh)136 np.save(all_dirs_filename + "gray_equ_labels", all_labels_gray_equ)137 np.save(all_dirs_filename + "gray_clahe_labels", all_labels_gray_clahe)138

139 print("Br. spremljenih slova:", len(all_data_gray))

14.3 Skripta data_samples.py

Ova skripta poslužila je za generiranje nekoliko slika u radu. Skripta uzima sliku definiranu uvarijabli filename i prikazuje nekoliko tehnika određivanja praga na dijelu slike. Rezultirajućavizualizacija spremi se lokalno. Vizualizacija sa nađenim konturama na dijelu slike se takođersprema lokalno. Zadnja vizualizacija koja se sprema sadrži dio slike sa sortiranim slovima igranicama između redaka.

1 import numpy as np2 import cv2

38

Page 41: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

3 from matplotlib import pyplot as plt4 from operator import itemgetter5 from segment import letters_contours, get_rows_limits, order_rects6

7

8 def thresh_samples(im, thresh_val):9 '''

10 Prikazi neke tehnike thresholdinga. Spremi rezultirajucu sliku.11

12 Args:13 im: slika u boji.14 thresh_val: thresh vrijednost.15

16 Returns:17 Funkcija ne vraca vrijednost.18 '''19 imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)20

21 ret, thresh1 = cv2.threshold(imgray.copy() , thresh_val, 255, cv2.THRESH_BINARY)

22 ret, thresh2 = cv2.threshold(imgray.copy() , thresh_val, 255, cv2.THRESH_TRUNC)

23 ret, thresh3 = cv2.threshold(imgray.copy() , thresh_val, 255, cv2.THRESH_TOZERO)

24 thresh4 = cv2.adaptiveThreshold(imgray.copy() , 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY, 11, 2)

25

26 titles = ['Crno-bijela slika', 'Binarno određivanje praga', 'Određivanje praga odsijecanjem', 'Do-nule određivanje praga']

27

28 y, h, x, w = 168, 210, 226, 30029 images = [imgray[y: y+h, x: x+w],30 thresh1[ y: y+h, x: x+w],31 thresh2[ y: y+h, x: x+w],32 thresh3[ y: y+h, x: x+ w]]33

34 plt.figur e(101)35 for i in range(4):36 plt.subplot(2, 2, i+1)37 plt.imshow(images[i], 'gray')38 plt.title(titles[ i])39 plt.xticks([])40 plt.yticks([])41

42 plt.savefig('thresh_types.png', bbox_inches= 'tight', dp i=200)43

44

45 def contours_sample(im, thresh_value):46 '''47 Prikazi konture oko dijela slike. Spremi rezultirajucu sliku.48

49 Args:50 im: slika u boji.51 thresh_val: thresh vrijednost.52

53 Returns:54 Funkcija ne vraca vrijednost.55 '''56 imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # crno-bijela slika57 ret, thresh = cv2.threshold(imgray, thresh_value, 255, cv2.THRESH_BINARY) #

rucno postavljen limit za threshold58

59 # nadji konture slova

39

Page 42: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

60 image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

61

62 rects = []63 for c in contours:64 x, y, w, h = cv2.boundingRect(c)65 rects.append([x, y, w, h])66

67 im_c = cv2.cvtColor(imgray.copy() , cv2.COLOR_GRAY2RGB)68 for r in rects:69 # nacrtaj pravokutnik oko kontura70 cv2.rectangle(im_c, (r[0] , r[1]) , (r[0]+ r[2] , r[1]+ r[3]) , (255 ,0 ,0) , 1)71

72 y, h, x, w = 170, 157, 226, 30073

74 plt.figur e(102)75 plt.imshow(im_c[y: y+h, x: x+ w])76 plt.xticks([])77 plt.yticks([])78 plt.savefig('conts.png', bbox_inches= 'tight', dp i=200)79

80 def draw_letters_contours_sample(rects, limits_ys, image, fig_nu m=103) :81 '''82 Na skeniranu stranicu nacrtaj granice redaka, pravokutnike oko slova i redne

brojeve slova.83 Prikazi anotiranu figuru.84 Za detaljnije komentare kod crtanja vidi draw_letters_contours() iz segment.

py.85

86 Args:87 rects: lista pravokutnika opisanih oko slova.88 limits_ys: y koordinate granica izmedju redaka.89 image: skenirana stranica (u boji).90 fig_num: id nove matplotlib figure.91

92 Returns:93 Funkcija ne vraca vrijednost.94 '''95 plt.figure(fig_num)96 image_contours = image.copy()97 im_height, im_width = image.shape[:2]98 num = 199

100 for i in range(len(limits_ys)):101 # nacrtaj granicu retka102 cv2.line(image_contours, (0, limits_ys[ i]) , (im_width, limits_ys[ i]) ,

(255 , 0, 0), 2)103

104 for r in rects:105 # nacrtaj pravokutnik oko slova106 cv2.rectangle(image_contours, (r[0] , r[1]) , (r[0] + r[2] , r[1] + r[3]) ,

(0, 255, 0), 1)107 # izracunaj y koordinatu teksta na slici108 padding, font, font_scale, thick = 2, cv2.FONT_HERSHEY_SIMPLEX, 0.4, 1109 if num % 2 != 0:110 y = r[1] - padding111 else:112 text_w, text_h = cv2.getTextSize(str(num), font, font_scale, thick)

[0]113 y = r[1] + r[3] + padding + text_h114 # dodaj redni broj slova na sliku115 cv2.putText(image_contours, str(num), (r[0] - 2, y), font, font_scale,

(0, 0, 255) , thick, cv2.LINE_AA)

40

Page 43: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

116 num += 1117

118 y, h, x, w = 165, 219, 226, 600119 plt.imshow(image_contours[y: y+h, x: x+ w])120 plt.xticks([])121 plt.yticks([])122 plt.savefig('ordered.png', bbox_inches= 'tight', dp i=200)123

124

125 if __name__ == "__main__":126

127 filename = "data/01 _200dpi.jpg"128 im = cv2.imread(filename, 1)129 thresh_value = 200130

131 thresh_samples(im, thresh_value)132 contours_sample(im, thresh_value)133

134 im = cv2.imread(filename, 1) # ucitaj sliku135 imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY) # crno-bijela slika136 ret, thresh = cv2.threshold(imgray, thresh_value, 255, cv2.THRESH_BINARY) #

rucno postavljen limit za threshold137 image, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHA

IN_APPROX_SIMPLE) # nadji konture slova138 rects = letters_contours(contours, hierarchy)139 limits_ys = get_rows_limits(imgray, im, thresh_value)140 ordered_rects = order_rects(rects, limits_ys) # sortiraj slova141 draw_letters_contours_sample(ordered_rects, limits_ys, im)

14.4 Skripta basic_net.py

Ovom skriptom pokreće se treniranje i testiranje neuronske mreže opisane u poglavlju 8.1. Podaciza treniranje definirani su u varijabli all_train_data (lista sa imenima numpy polja uzoraka).Varijabla test_data_files sadrži 2D listu imena numpy polja sa uzorcima za testiranje. Uzsvako ime polja dan je i kratak opis podataka. Skripta na kraju svog izvođenja ispisuje vrijemetreniranja i preciznost klasifikacija na podacima za testiranje.

1 import tensorflow as tf2 import numpy as np3 from time import time4

5

6 def load_labels(samples_filename):7 '''8 Ucitaj pripadnu npy datoteku sa oznakama.9 Uzorci: <ime_dat>.npy; oznake <ime_dat>_labels.npy.

10

11 Args:12 samples_filename: ime npy datoteke sa uzorcima.13

14 Returns:15 labels: numpy polje sa oznakama.16 '''17 labels_filename = samples_filename[: -4] + "_labels.npy"18 data_labels = np.load(labels_filename)19

20 return data_labels21

22 def load_train_data(all_train_data):23 '''

41

Page 44: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

24 Ucitaj podatke za treniranje iz dane liste (sadrzi datoteke sa uzorcima).25 Svaka lista je drugi skup podataka.26

27 Args:28 all_train_data: lista sa imenima datoteka uzoraka.29

30 Returns:31 data_train: polje sa svim uzorcima.32 data_train_labels: polje sa svim oznakama.33 '''34 data_train = np.load(all_train_data[0])35 data_train_labels = load_labels(all_train_data[0])36

37 for i in range(1, len(all_train_data)):38 samples, labels = np.load(all_train_data[ i]) , load_labels(all_train_dat

a[ i])39 data_train = np.vstack((data_train, samples))40 data_train_labels = np.vstack((data_train_labels, labels))41

42 return data_train, data_train_labels43

44 def shuffle(data, labels):45 '''46 Ispremijesaj uzorke i njihove oznake.47

48 Args:49 data: polje sa uzorcima.50 labels: polje sa pripadnim oznakama.51

52 Returns:53 data_shuffle: ispremijesano polje uzoraka.54 labels_shuffle: ispremijesano polje oznaka.55 '''56 idx = np.arange(0, len(data))57 np.random.shuffle(idx)58 data_shuffle = [data[i] for i in idx]59 labels_shuffle = [labels[i] for i in idx]60

61 return data_shuffle, labels_shuffle62

63 def run_net():64

65 # podaci za treniranje66 all_train_data = ['train_data/2016 -09 -01 _20 -51_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy',67 'train_data/2016 -09 -01 _20 -53_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy',68 'train_data/2016 -09 -01 _20 -57_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy',69 'train_data/2016 -09 -06 _22 -14_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy']70 data_train, data_train_labels = load_train_data(all_train_data)71 data_train, data_train_labels = shuffle(data_train, data_train_labels)72

73 # podaci za testiranje74 test_data_files = [['test_data/misal_31__misal_55__misal_115__misal_175__mis

al_199__misal_205__gray.npy', 'gray'],75 ['test_data/misal_31__misal_55__misal_115__misal_175__misal

_199__misal_205__thresh.npy', 'thresh'],76 ['test_data/misal_31__misal_55__misal_115__misal_175__misal

_199__misal_205__gray_equ.npy', 'equ'],77 ['test_data/misal_31__misal_55__misal_115__misal_175__misal

_199__misal_205__gray_clahe.npy', 'clahe']]

42

Page 45: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

78 ##test_data_files = [['test_data/2016 -09 -06 _22 -50_shift_rotate_noise_01 _200dpi__02 _200dpi__03 _200dpi.npy', 'my data']]

79

80 data_test = []81 for filename, data_type in test_data_files:82 data_test.append([np.load(filename), load_labels(filename), data_type])83

84 sample_size = np.shape(data_train) [1]85 label_size = np.shape(data_train_labels) [1]86

87 with tf.name_scope("inputs"):88 # ulazi u mrezu89 x = tf.placeholder(tf.float32, [None, sample_size], name="x_inputs")90 # tocne klase91 y_ = tf.placeholder(tf.float32, [None, label_size], name="y_inputs")92

93 with tf.name_scope("layer"):94 with tf.name_scope("weights"):95 # tezine izmedju ulaznog i izlaznog sloja96 W = tf.Variable(tf.zeros([sample_size, label_size]) , name="W")97 ##tf.histogram_summary("weights", W)98 with tf.name_scope("weights"):99 # sklonosti

100 b = tf.Variable(tf.zeros([label_size]) , name="b")101 ##tf.histogram_summary("biases", b)102 with tf.name_scope("inputs"):103 # izlaz mreze104 y = tf.nn.softmax(tf.matmul(x, W) + b)105 ##tf.histogram_summary("output", y)106

107 with tf.name_scope("loss"):108 # funkcija pogreske109 cross_entropy = -tf.reduce_sum(y_*tf.log(y), name="cross_entropy")110 tf.scalar_summary("cross_entropy", cross_entropy)111

112 with tf.name_scope("train"):113 # treniranje114 learn_rate = 0.02115 train_step = tf.train.GradientDescentOptimizer(learn_rate).minimize(cros

s_entropy)116

117 init = tf.initialize_all_variables()118

119 with tf.name_scope('Accuracy'):120 # preciznost121 correct_prediction = tf.equal(tf.argmax(y,1), tf.argmax(y_,1))122 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))123 acc_summ = tf.scalar_summary("accuracy", accuracy)124

125 sess = tf.Session()126 writer = tf.train.SummaryWriter("logs/", sess.graph)127 sess.run(init)128

129 print("Broj uzoraka za treniranje:", len(data_train))130

131 batch_size = 2132 print("Batch size:", batch_size)133 print("Stopa učenja:", learn_rate)134

135 t_start = time()136

137 # pokreni treniranje138 for i in range(len(data_train) // batch_size):

43

Page 46: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

139 batch_xs = data_train[batch_size * i : batch_size * (i+1)]140 batch_ys = data_train_labels[batch_size * i : batch_size * (i+1)]141 sess.run(train_step, feed_dict={ x: batch_xs, y_: batch_ys})142 '''143 if i % 50 == 0:144 a = sess.run(acc_summ, feed_dict={ x: data_test[0][0] , y_: data_tes

t[0][1]})145 writer.add_summary(a, i)146 '''147

148 t_end = time()149 print('Treniranje izvrseno u', t_end - t_start, 's')150

151 acc_all = []152 data_types = []153

154 for samples, labels, data_type in data_test:155 acc = sess.run(accuracy, feed_dict={ x: samples, y_: labels})156 print( 'Preciznost klasifikacije (' + data_type + '):', acc)157 acc_all.append(acc)158 data_types.append(data_type)159

160 return acc_all, data_types161

162

163 if __name__ == "__main__":164 run_net()

14.5 Skripta conv_net.py

Skripta pokreće treniranje i testiranje neuronske mreže opisane u poglavlju 8.2. Na samompočetku izvede se uvoz nekoliko pomoćnih funkcija iz basic_net.py. Skupovi podataka zatreniranje definirani su u kodu listom all_train_data (imena numpy polja sa uzorcima). Podaciza testiranje dani su 2D listom test_data_files, na isti način kao i za prvu mrežu. Skriptana kraju svog izvođenja ispisuje vrijeme treniranja i preciznost klasifikacija na podacima zatestiranje.

1 import tensorflow as tf2 import numpy as np3 from time import time4 from basic_net import load_labels, load_train_data, shuffle5

6

7 def weight_variable(shape):8 initial = tf.truncated_normal(shape, stdde v=0.1)9 return tf.Variable(initial)

10

11 def bias_variable(shape):12 initial = tf.constant(0.1 , shape=shape)13 return tf.Variable(initial)14

15 def conv2d(x, W):16 return tf.nn.conv2d(x, W, strides=[1 , 1, 1, 1], padding='SAME')17

18 def max_pool_2 x2( x):19 return tf.nn.max_pool(x, ksize=[1 , 2, 2, 1], strides=[1 , 2, 2, 1], padding='

SAME')20

21 def run_net():22

44

Page 47: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

23 # podaci za treniranje24 all_train_data = ['train_data/2016 -09 -01 _20 -51_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy',25 'train_data/2016 -09 -01 _20 -53_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy',26 'train_data/2016 -09 -01 _20 -57_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy',27 'train_data/2016 -09 -06 _22 -14_shift_rotate_noise_01 _200dpi_

_02 _200dpi__03 _200dpi.npy']28 data_train, data_train_labels = load_train_data(all_train_data)29 data_train, data_train_labels = shuffle(data_train, data_train_labels)30

31 print('Broj uzoraka za treniranje:', len(data_train))32

33 # podaci za testiranje34 test_data_files = [['test_data/misal_31__misal_55__misal_115__misal_175__mis

al_199__misal_205__gray.npy', 'gray'],35 ['test_data/misal_31__misal_55__misal_115__misal_175__misal

_199__misal_205__thresh.npy', 'thresh'],36 ['test_data/misal_31__misal_55__misal_115__misal_175__misal

_199__misal_205__gray_equ.npy', 'equ'],37 ['test_data/misal_31__misal_55__misal_115__misal_175__misal

_199__misal_205__gray_clahe.npy', 'clahe']]38 ##test_data_files = [['test_data/2016 -09 -06 _22 -50_shift_rotate_noise_01 _200d

pi__02 _200dpi__03 _200dpi.npy', 'my data']]39

40 data_test = []41 for filename, data_type in test_data_files:42 data_test.append([np.load(filename), load_labels(filename), data_type])43

44 sample_size = np.shape(data_train) [1]45 label_size = np.shape(data_train_labels) [1]46

47 x = tf.placeholder(tf.float32, shape=[None, sample_size])48 y_ = tf.placeholder(tf.float32, shape=[None, label_size])49

50 W = tf.Variable(tf.zeros([sample_size, label_size]))51 b = tf.Variable(tf.zeros([label_size]))52

53 W_conv1 = weight_variable([5 , 5, 1, 32])54 b_conv1 = bias_variabl e([32])55

56 x_image = tf.reshape(x, [-1, 28, 28, 1])57

58 h_conv1 = tf.nn.relu(conv2d(x_image, W_conv1) + b_conv1)59 h_pool1 = max_pool_2 x2(h_conv1)60

61 W_conv2 = weight_variable([5 , 5, 32, 64])62 b_conv2 = bias_variabl e([64])63

64 h_conv2 = tf.nn.relu(conv2d(h_pool1, W_conv2) + b_conv2)65 h_pool2 = max_pool_2 x2(h_conv2)66

67 W_fc1 = weight_variable([7 * 7 * 64, 1024])68 b_fc1 = bias_variabl e([1024])69

70 h_pool2_flat = tf.reshape(h_pool2, [-1, 7 * 7 * 64])71 h_fc1 = tf.nn.relu(tf.matmul(h_pool2_flat, W_fc1) + b_fc1)72

73 # dropout74 keep_prob = tf.placeholder(tf.float32)75 h_fc1_drop = tf.nn.dropout(h_fc1, keep_prob)76

45

Page 48: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

77 W_fc2 = weight_variable([1024 , label_size])78 b_fc2 = bias_variable([label_size])79

80 y_conv = tf.nn.softmax(tf.matmul(h_fc1_drop, W_fc2) + b_fc2)81

82 with tf.name_scope('Accuracy'):83 # preciznost84 correct_prediction = tf.equal(tf.argmax(y_conv,1), tf.argmax(y_,1))85 accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))86 acc_summ = tf.scalar_summary("accuracy", accuracy)87

88 cross_entropy = tf.reduce_mean(-tf.reduce_sum(y_ * tf.log(y_conv), reduction_indice s=[1]) )

89 learn_rate = 0.000890 train_step = tf.train.AdamOptimizer(learn_rate).minimize(cross_entropy)91

92 batch_size = 5093

94 print("Batch size:", batch_size)95 print("Stopa učenja:", learn_rate)96

97 sess = tf.Session()98 writer = tf.train.SummaryWriter("logs/", sess.graph)99 sess.run(tf.initialize_all_variables())

100

101 t_start = time()102

103 for i in range(len(data_train) // batch_size):104 batch_xs = data_train[batch_size * i : batch_size * (i + 1)]105 batch_ys = data_train_labels[batch_size * i : batch_size * (i + 1)]106 sess.run(train_step, feed_dict={ x: batch_xs, y_: batch_ys, keep_prob:

0.5})107 ##a = sess.run(acc_summ, feed_dict={ x: data_test[0][0] , y_: data_tes

t[0][1] , keep_prob: 1.0})108 ##writer.add_summary(a, i)109

110 t_end = time()111 print('Treniranje izvrseno u', t_end - t_start, 's')112

113 acc_all = []114 data_types = []115

116 for samples, labels, data_type in data_test:117 acc = sess.run(accuracy, feed_dict={ x: samples, y_: labels, keep_prob:

1.0})118 print( 'Preciznost klasifikacije (' + data_type + '):', acc)119 acc_all.append(acc)120 data_types.append(data_type)121

122 return acc_all, data_types123

124

125 if __name__ == "__main__":126 run_net()

14.6 Skripta caller.py

Cilj ove skripte je olakšati višestruka uzastopna pokretanja skripti basic_net.py i conv_net.py.Broj pokretanja za svaku mrežu dan je varijablom runs. Skripta će na kraju izvođenja pojedinemreže ispisati preciznosti za sva pokretanja te mreže. Također će se ispisati aritmetičke sredine

46

Page 49: Edvin Močibob Raspoznavanjeslovauglate glagoljice · 2019-05-05 · Nakon što sam odabrao vrstu glagoljice i fontove Glagoljica euglata, Glagolica Missal DPG i Epistula Croatica

preciznosti za sva izvršavanja pojedinih mreža.1 import numpy as np2 from basic_net import run_net as basic_net_main3 from conv_net import run_net as conv_net_main4

5

6 def call_net(net_main, runs):7

8 all_accs = []9

10 for i in range(1, runs + 1):11 print(" ** Pokretanje:", i, '/', runs, "**")12 accs, data_types = net_main()13 all_accs.append([ i] + accs)14

15 print("\nStupci:")16 print(data_types)17

18 for row in all_accs:19 latex_row = " & ".join(str(el).rjust(8, ' ') for el in row) + " \\\\"20 print(latex_row)21

22 means = np.mean(all_accs, axis=0)23 print( " & ".join(str(round(el, 5)).rjust(8, ' ') for el in means) + " \\\\

\hline")24

25 if __name__ == "__main__":26

27 runs = 1028

29 print(" ** PRVA MREŽA **\n")30 call_net(basic_net_main, runs)31

32 print("\n ** KONV MREŽA **\n")33 call_net(conv_net_main, runs)

47