Neironu tīkli


Saturs

Saturs.................................................................................................................................
Ievads................................................................................................................................
1. Neironu tīklu apmācības teorija.....................................................................................
1.1.Neironu tоklu struktыra...........................................................................................
1.1.1.Bioloмiskie un mвkslоgie neironu tоkli............................................................
1.1.2.Bioloмiskie neironu tоkli..................................................................................
1.1.3.Tehniskв neirona modelis...............................................................................
1.1.4.Neironu tоklu veidi.........................................................................................
1.2.Mвkslоgo neironu tоklu apmвcоbas algoritmi.......................................................
1.2.1.Neironu tоklu apmвcоbas uzdevuma formulзjums un iespзjamie risinвjumu ceпi  
1.2.2.Neironu tоkls apmвcоbas laikв.......................................................................
1.2.3.Apmвcоbas paradigmas..................................................................................
1.2.4.Atgriezeniskвs izplatорanas algoritms............................................................
1.3.Neironu tоklu pamatparadigmas............................................................................
1.3.1.Pretimnвkoрвs izplatорanas tоkls..................................................................
1.3.2.Maksimuma meklзрanas tоkls ar tieрiem sakariem.........................................
1.3.3.Gausa klasifikators.........................................................................................
1.3.4.Ieejas zvaigzne................................................................................................
1.3.5.Izejas zvaigzne................................................................................................
2.Neironu tīklu darba matemātiskā modelēšana..............................................................
2.1.Neironu tоkla darbоbas matemвtiskв modelзрanas uzdevuma izvirzорana..........
2.2.Modelзjoрвs programmas funkcijas......................................................................
2.2.1.Funkciju vispвrзjs apraksts.............................................................................
2.2.2.Lietotвja interfeiss..........................................................................................
2.2.3.Moduпa "nnet.c" programmзрanas interfeisa apraksts...................................
3.Neironu tīklu izmantošana............................................................................................
3.1.Aritmзtisko un loмisko operвciju izpildорana izmantojot neironu tоklu...............
3.1.1.Loмiskв VAI realizвcija neironu tоklв...........................................................
3.1.2.Loмiskв UN realizвcija neironu tоklв............................................................
3.1.3.Izslзdzoрв VAI izpilde neironu tоklв............................................................
3.1.4.Skaitпu saskaitорanas operвcijas realizвcija binвrajв skaitорanas sistзmв neironu tоklв   
3.1.5.Aritmзtiskвs saskaitорanas operвcijas realizвcija neironu tоklв.....................
3.2.Pasta indeksa ciparu atpazорana...........................................................................
3.3.Trigonometrisko funkciju vзrtоbu aprзнinврana izmantojot neironu tоklu...........
3.4.Neironu tоkla apmвcорana prognozзt trigonometrisko funkciju sekojoрвs vзrtоbas pзc uzdotajвm iepriekрзjвm vзrtоbвm..........................................................................................................
3.5.Trenda pagrieрanвs atpazорanas uzdevums..........................................................
Nobeigums.......................................................................................................................
Izmantotās literatūras saraksts.........................................................................................
1.Pielikums......................................................................................................................
2.Pielikums......................................................................................................................
3.Pielikums....................................................................................................................
4.Pielikums....................................................................................................................
5.Pielikums....................................................................................................................


Ievads

Neironu tīkli - tie ir skaitļošanas modeļi, kuri balstās principiem, līdzīgiem smadzeņu uzbūves principiem, un kuri paredzēti smadzeņu risināmo problēmu atrisināšanai. Zīdītājiem bioloģiskie neironu tīkli ir formēti no neironiem, kuri paši par sevi ir samērā sarežģīti bioloģiski objekti. Liels skaits apvienotu neironu pamato dzīvnieku sarežģīto uzvedību.  Šajā darbā apskatītie mākslīgie neironu tīkli ir daudz vienkāršāki un labāk izpētīti. Bet tomēr, tie ir spējīgi atrisināt dažus pietiekami sarežģītus uzdevumus - atpazīt audio un vizuālos tēlus, aproksimēt funkcijas, veikt dažu veidu prognozes un vadīt.
Pētījumi mākslīgo neironu tīklu sfērā pārdzīvojuši trīs aktivācijas periodus. Pirmo uzplaukumu 40.gados izraisīja MakKaloka un Pitsa pionieru darbs. Otrais bija 60.gados, balstoties uz Rozenblata perceptrona tuvinājuma teorēmu un Minska ‑ Peiperta darbu, kurš norādīja vienkāršākā percetrona ierobežotās iespējas. Minska ‑ Peiperta rezultāti noslāpēja tā pētnieku vairuma entuziasmu, kuri strādāja skaitļošanas zinātņu jomā. Radies klusums ilga gandrīz 20 gadus. No 80.gadu sākuma mākslīgie neironu tīkli no jauna piesaistīja pētnieku uzmanību. Verboss piedāvāja atgriezeniskās izplatības algoritmu daudzslāņu perceptrona apmācībai, kurš kļuva pazīstams 1986.gadā.
Uz šodienu eksistē divas pieejas realizējot mākslīgos neironu tīklus: aparāt­realizācija un programrealizācija. Daudzas pazīstamas firmas ražo elektroniskos kompo­nentus (mikroshēmas un veselas plates), kuras aparātlīmenī realizē mākslīgā neironu tīkla modeli. Pie otras pieejas, neironu tīklu modelē speciāla programma, kura darbojas uz parasta (iespējams, personālā) datora. Aparāt­nodrošinājuma un programnodrošinājuma tirgos eksistē pietiekami liels skaits neironu tīklu kā aparāt, tā arī programmemulatoru, bet tie visi izceļas ar savu augsto cenu, kas padara tos nepieejamus vairumam lietotāju.
Mūsdienās mākslīgie neironu tīkli tiek aktīvi izmantoti visās cilvēka darbības sfērās: militārajā, politikā, ekonomikā u.c.
Dotā darba mērķis ir apskatīt neironu tīklu funkcionēšanas principus, apskatīt to veidus, vairāku neironu tīklu modeļu izveidošana un apmācība, lai noskaidrotu to praktisko derīgumu atrisinot dažādus uzdevumus.
Galvenais dotā darba mērķis bija neironu tīkla izveidošana, kurš ir spējīgs funkcionēt uz spēcīga datora un tā apmācība atpazīt fjučersu tirgus trenda pagriešanos. Savlaicīga trenda pagriešanās atpazīšana ļauj izvēlēties visveiks­mīgāko biržas spēles stratēģiju un līdz ar to rast praktisku pielietojumu ekonomikas sfērā.

1.Neironu tīklu apmācības teorija

1.1.Neironu tīklu struktūra

1.1.1.Bioloģiskie un mākslīgie neironu tīkli


Ilgstošais evolūcijas periods cilvēka smadzenēm ir devis daudz īpašību, kuru nav nedz mašīnām ar fon Neimana arhitektūru, nedz arī mūsdienīgajiem paralēlajiem datoriem. Tās būtu:
·     masveida paralēlisms;
·     sadalīta informācijas un skaitļošanas attēlošana;
·     spēja mācīties un spēja vispārināt;
·     adaptivitāte;
·     spēja kontekstuāli apstrādāt informāciju;
·     tolerance pret kļūdām;
Var pieņemt, ka ierīcēm, kas uzbūvētas pēc tādiem pašiem principiem kā bioloģiskie neironi, piemitīs uzskaitītās īpašības.
Mūsdienu ciparu skaitļojamās mašīnas pārspēj cilvēka ciparu un simbolu skaitļošanas veiktspēju. Tomēr cilvēks bez piepūles var risināt ārējo datu uztveršanas uzdevumus (piemēram, pazīt pūlī tikko pazibējuša cilvēka seju) ar tādu ātrumu un precizitāti, ka pats jaudīgākais dators pasaulē salīdzinājuma ar viņu šķiet bezcerīgs cietpauris. Kāds ir tik būtiskas ražīguma atšķirības iemesls? Bioloģiskās neironu sistēmas arhitektūra pilnīgi atšķiras no fon Neimana mašīnas arhitektūras (tabula 1.1.), un tas būtiski iespaido funkciju tipus, kurus katrs modelis izpilda visefektīvāk.
1.1 Tabula
Fon Neimana mašīna salīdzinājumā ar bioloģisko neironu sistēmu.

Fon Neimana mašīna
Bioloģiskā neironu sistēma
Procesors
Sarežģīts
Vienkāršs

Ātrs
Lēns

Viens vai vairāki
Liels daudzums
Atmiņa
Atdalīta no procesora
Integrēta procesorā

Lokalizēta
Sadalīta

Adresācija ne pēc satura
Adresācija pēc satura
Skaitļošana
Centralizēta
Sadalīta

Pakāpeniska
Paralēla

Saglabājamas programmas
Pašmācība
Drošība
Viegli ievainojams
Izturīgs
Specializācija
Ciparu un simbolu specializācija
Uztveršanas problēmas
Funkcionēšanas vide
Stingri noteikta
Slikti noteikta

Stingri ierobežota
Bez ierobežojumiem

Līdzīgi bioloģiskajai neironu sistēmai mākslīgais neironu tīkls ir skaitļošanas sistēma ar milzīgu daudzumu paralēli funkcionējošu vienkāršu procesoru ar daudziem sakariem. Mākslīgo neironu tīklu modeļi kaut kādā ziņā atveido cilvēka smadzenēm raksturīgus “organizācijas” principus. Bioloģiskas neironu sistēmas modelēšana, izmantojot mākslīgo neironu tīklu, var veicināt bioloģisko funkciju labāku izpratni. Tādas ražošanas tehnoloģijas kā VLSI (superaugsts integrācijas līmenis) un optiskā aparatūra šādu modelēšanu padara iespējamu.
Dziļāka mākslīgo neironu tīklu izpēte prasa neirofizioloģijas zināšanu, zinātnes par izziņu, psiholoģijas, fizikas (statiskās mehānikas), vadīšanas teorijas, skaitļošanas teorijas, mākslīgā intelekta problēmu, statistikas un matemātikas, tēlu atpazīšanas, datoru redzes, paralēlās skaitļošanas un aparatūras (datu / analogās / VLSI / optiskās) izpēti. No otras puses, mākslīgie neironu tīkli sekmē šo disciplīnu attīstības, nodrošinot tās ar jauniem instrumentiem un priekšstatiem. Šī simbioze nepieciešama neironu tīklu pētījumiem.

1.1.2.Bioloģiskie neironu tīkli

Neirons (nervu šūna) ir īpaša bioloģiska šūna, kas apstrādā informāciju (1.1 zīm.). Tā sastāv no šūnas ķermeņa vai somas un diviem atzariem: aksona un dendrīta. Šūnas ķermenis sevī ietver kodolu, kurš satur informāciju par pārmantojamām īpašībām, un plazmu, kurai piemīt molekulāri līdzekļi neironam nepieciešamo materiālu ražošanai. Neirons saņem signālus (impulsus) no citiem neironiem ar dendrītu (uztvērēju) starpniecību un pārraida šūnas ķermenī ģenerētos signālus pa aksonu (pārraidītājs), kurš galā sadalās šķiedrās. Šo šķiedru galos ir sinapses.
1.1. zīm. Bioloģiskais neirons
Sinapse ir elementāra struktūra un funkcionāls mezgls starp diviem neironiem (viena neirona aksona šķiedra un otra dendrīts). Kad impulss sasniedz sinaptisko galu, atbrīvojas noteiktas ķīmiskās vielas, kuras sauc par neirotransmiteriem. Tie difundē caur sinaptisko spraugu, atkarībā no sinapses tipa uzbudinot vai bremzējot neirona-uztvērēja spēju ģenerēt elektriskos impulsus. Sinapses rezultativitāte var tikt regulēta ar caurejošo signālu palīdzību tā, ka sinapses var apmācīties atkarībā no to procesu aktivitātes, kuros tās piedalās. Šī atkarība no priekšvēstures darbojas kā atmiņa, kura, iespējams, ir atbildīga par cilvēka atmiņu.
Cilvēka galvas smadzeņu garoza ir garena, neironu veidota 2-3 mm bieza virsma ar laukumu ~ 2200 cm2, kas divas reizes pārsniedz datora tastatūras virsmas laukumu. Galvas smadzeņu garoza satur ap 1011 neironus, kas aptuveni līdzvērtīgs Piena ceļa [2] zvaigzņu skaitam. Katrs neirons saistīts ar 103 - 104 citiem neironiem. Kopumā cilvēka smadzenes satur aptuveni no 1014 līdz 1015 savstarpējo saišu.
Neironi iedarbojas ar īsu impulsu sērijas starpniecību, kas parasti ilgst dažas milisekundes. Paziņojums tiek pārraidīts ar frekvenču - impulsu modulācijas palīdzību. Frekvence var mainīties no dažām vienībām līdz simtiem hercu, kas ir miljons reižu lēnāk par pašām ātrdarbīgākajām elektroniskajām pārslēdzējshēmām. Tomēr sarežģītus informācijas uztveres uzdevumus, piemēram, sejas atpazīšanu, cilvēks veic dažu simtu ms laikā. Tas nozīme, ka skaitļošana prasa ne vairāk kā 100 pakāpeniskas stadijas. Citiem vārdiem sakot, lai risinātu tādus sarežģītus uzdevumus, smadzenes “iedarbina” paralēlas programmas, kuras satur ap 100 soļus. Tas ir pazīstams kā simts soļu likums [3]. Spriežot tādā pašā veidā ir jākonstatē, ka informācijas daudzums, kas tiek nosūtīts no viena neirona otram, ir ļoti neliels (daži biti). Var secināt, ka pamatinformācija tiek nodota bez starpniecības, bet tiek pārtverta un sadalīta sakaros starp neironiem.

1.1.3.Tehniskā neirona modelis

1.2. zīm. Mākslīgais neirons
Katra neironu tīkla pamatu veido nosacīti vienkārši, vairumā gadījumu - vienveidīgi elementi (šūnas), kas imitē smadzeņu neironu darbu. Turpmāk ar neironu tiks domāts mākslīgais neirons, t.i. neironu tīklu šūna. Katrs neirons tiek raksturots ar tā stāvokli analoģiski ar galvas smadzeņu nervu šūnām, kuras var tikt uzbudinātas vai bremzētas. Tam piemīt sinapšu grupa - vienvirziena ieejas sakari, kas savienoti ar citu neironu izeju, kā arī ir aksons - dotā neirona izejas sakars, no kura signāls (uzbudinājums vai bremzēšana) nonāk nākošo neironu sinapsēs.       
Kopējais neirona izskats dots 1.2. zīm. Katra sinapse tiek raksturota ar sinaptisko sakaru lielumu vai tās svaru wi, kas pēc fiziskās būtības ir ekvivalents elektriskai vadāmībai.
Tekošais neirona stāvoklis tiek noteikts kā ārējā ieeju summa:
.

(1.1)
Neirona izeja ir stāvokļa funkcija:
y = f(s).
(1.2)
Nelineārā funkcija f tiek saukta par aktivācijas funkciju un var būt dažāda, kā parādīts 1.3. zīm. Viena no izplatītākajām ir funkcija ar piesātinājumu, tā saucamā loģistiskā funkcija vai sigmoīds (t.i. S-veidīgā funkcija) [4]:
.
(1.3)

1.3. zīm.
a) vienreizējā lēciena funkcija;
b) slieksnis (histerēze);
c) sigmoīds - hiperboliskais tangenss
d) sigmoīds - formula (1.3)
No sigmoīda izteiksmes ir acīmredzams, ka neirona izejas vērtība atrodas diapa­zonā [0,1]. Viena no sigmoīda funkciju vērtīgajām īpašībām - tās līknes vienkārša izteiksme, kuras pielietošana tiks izska­tīta turpmāk.
(1.4)
Ir jāatzīmē, ka sigmoīda funkcija ir diferencējama visās tās abscesa ass garumā, kas tiek izmantots dažos apmā­cības algoritmos. Bez tam tai piemīt īpašība vājos signālus pastiprināt vairāk nekā stipros un novērst pārsātinājumu no stiprajiem signāliem, jo tie atbilst argumentu apgabaliem, kur sigmoīds ir slīps.

1.1.4.Neironu tīklu veidi

Atgriežoties pie visu neironu tīklu kopējām pazīmēm, ir jāatzīmē paralēlas signālu apstrādes princips, kas tiek sasniegts, apvienojot lielu neironu skaitu tā saucamajos slāņos un savienojot dažādu slāņu (dažās konfigurācijās arī viena slāņa) neironus noteiktā veidā, pie kam neironu mijiedarbību apstrāde tiek veikta pa slāņiem.
,   j=1...3.

(1.5)
Acīmredzams, ka visu viena neironu slāņa svaru koeficientus var aprakstīt matricē W, kurā Wij elements apzīmē j neirona sinaptisko sakaru i lielumu. Tādējādi neironu tīklos notiekošo procesu var pierakstīt matrices formā:
Y=F(XW),
(1.6)
kur X un Y - atbilstoši ieejas un izejas signālu vektori, F(V) - aktivācijas funkcija, kura pielietojama V-vektora komponentiem.
Teorētiski slāņu skaits un neironu skaits katrā slānī var būt neierobežots, tomēr faktiski tas ir ierobežots atkarībā no datora resursiem vai specializētās mikroshēmas, ar kuru palīdzību parasti tiek realizēts neironu tīkls. Jo sarežģītāks neironu tīkls, jo vairāk uzdevumu tas spēj veikt.
Neironu tīkla struktūras izvēle notiek atkarībā no uzdevuma īpatnībām un sarežģītības. Jautājums par tīkla nepieciešamajām un pietiekamajām īpašībām kāda uzdevuma atrisināšanai rada veselu neirodatoru zinātnes novirzienu. Neironu tīkla sintēzes problēma ir ļoti atkarīga no risināmā uzdevuma, un sniegt vispārīgas rekomendācijas ir grūti. Vairumā gadījumu optimāls variants rodas pēc intuitīvās atlases principa.
Attīstot tālāk jautājumu par iespējamo neironu tīklu klasifikāciju, ir svarīgi atzīmēt bināro un analogo tīklu pastāvēšanu. Pirmie operē ar bināriem signāliem, un katra neirona izejai var būt divas vērtības: loģiska nulle (“bremzētais” stāvoklis) un loģiskais vieninieks (“uzbudināts” stāvoklis). Šai tīklu klasei pieder arī perceptrons (tas ir tīkls, kur katram neironam ir vienota lēciena aktivācijas funkcija), jo tāda neirona, ko veido vienota lēciena funkcija, izejas vērtība ir vai nu 0, vai 1. Analogajos tīklos neironu izejas ir spējīgas uztvert nepārtrauktus signālus, kas kļūst iespējams, perceptrona neironu aktivācijas funkciju nomainot ar sigmoīdu.
1.4. zīm. Divslāņainais perceptrons
Vēl viena klasifikācija iedala neironu tīklus sinhronajos un asinhronajos [5]. Pirmajā gadījumā katrā laika sprīdī savu stāvokli maina viens neirons. Otrajā - stāvoklis mainās veselai neironu grupai uzreiz, parasti visā slānī. Turpmāk tiks aplūkoti tikai sinhronie neironu tīkli.
Tīklus var klasificēt pēc slāņu skaita. Zīm 1.4. parādīts divslāņu perceptrons. Te ir jāatzīmē aktivā­cijas funkcijas nelinearitātes no­zīme, jo, ja tai nebūtu minētās īpašības vai ja tā neiesaistītos katra neirona darba algoritmā, jebkura p-slāņu neironu tīkla ar svaru matricēm W(i) , kur i=1,2,…,p, darbības rezultāts katram slānim i tiktu reducēts līdz ieejas signālu vektora X reizināšanu ar matrici
W(S)=W(1)×W(2) ×...×W(p),
(1.7)
t.i., faktiski šāds p-slāņu neironu tīkls ir ekvivalents vienslāņa neironu tīklam ar vienīgā slāņa svaru matrici W(S):
Y=XW(S).
(1.8)
Pēc vienreizējā lēciena funkcijas zīmējuma var redzēt, ka robežlielums T vispārīgā gadījumā var būt patvaļīgs. Vēl vairāk, tam jāpieņem kādu brīvu agrāk nezināmu vērtību, kas tiek atlasīta apmācības stadijā kopā ar svaru koeficientu. Tas pats attiecas arī uz sigmoīda centrālo punktu, kurš var novirzīties uz X ass pa labi vai pa kreisi, kā arī uz visām citām aktivācijas funkcijām. Tomēr tas netiek atspoguļots formulā (1.1), kurai būtu jāizskatās sekojoši:
.

(1.9)
Lieta tāda, ka tamlīdzīgas nobīdes tiek veiktas, pievienojot neironu slānim vēl vienu ieeju, kas vienmēr vienāda ar 1 un papildus uzbudina katra neirona sinapsi. Piešķirsim šai ieejai numuru 0. Tad
,

(1.10)
kur W0 =-T, x0=1.
Acīmredzams, ka formulu (1.1) un (1.10) atšķirība ir tikai ieeju numurācijas veidā.
Kādus uzdevumus var risināt neironu tīkls? Vienkāršoti runājot, visu tīklu darbs tiek reducēts uz ieejas signālu, kuri pieder n-dimensiju hipertelpai, klasifikāciju. No matemātiska viedokļa tas notiek hiperplaknēm sadalot hipertelpu
,  k=1...m.

(1.11)
1.2 Tabula
x1    x2
0
1
0
A
B
1
B
A

Katrs iegūtais apgabals ir atsevišķas klases definīcijas apgabals. Tādu klašu skaits vienam perceptrona tipa neironu tīklam nepārsniedz 2m, kur m - tīkla izeju skaits. Tomēr ne visi no tiem var būt atdalīti ar doto neironu tīklu.
Piemēram, vienslāņa perceptrons, kurš sastāv no viena neirona ar divām ieejām, nav spējīgs sadalīt plakni (divdimensiju hipertelpu) divās pusplaknēs tā, lai veiktu ieejas signālu klasifikāciju A un B klasēs (1.2. tab.).
Tīkla vienādojums šim gadījumam
,
(1.12)
ir taisnes vienādojums (viendimensijas hipertelpa), kas ne pie kādiem apstākļiem nevar plakni sadalīt tā, lai dažādām klasēm piederošie daudzi ieejas signālu punkti nonāktu dažādās taisnes pusēs (1.5. zīm.).
1.5. zīm. Vizuāls neironu tīkla darba attēlojums
pēc 1.4. zīm.
Ja ieskatās 1.2. tabulā, var ievērot, ka dotā sašķelšana klasēs realizē loģiski izslēdzošo VAI funkciju ieejas signāliem. Vienslāņa perceptrona nespēja realizēt šo funkciju ieguva nosaukumu - izslēdzošā VAI problēma.
Funkcijas, ko vienslāņa tīkls nerealizē, tiek sauktas par lineāri nesadalāmām [4]. Šajos ierobežojumos nonākošo uzdevumu atrisinājums ietver sevī 2 un daudzslāņu tīklu vai nelineāro sinapšu tīklu pielietošanu, tomēr arī tad pastāv varbūtība, ka dažu ieejas signālu korekta sadalīšana klasēs nav iespējama.


1.2.Mākslīgo neironu tīklu apmācības algoritmi

1.2.1.Neironu tīklu apmācības uzdevuma formulējums un iespējamie risinājumu ceļi

Neironu tīkls darbības procesā rada izejas signālu Y atbilstoši ieejas signālam X, realizējot noteiktu funkciju g: Y=g(X). Ja dota tīkla arhitektūra, tad funkcijas g veidu nosaka sinapšu svaras un tīkla nobīde. Apzīmēsim ar burtu G visu iespējamo funkciju g kopu, kuras atbilst tīkla uzdotajai arhitektūrai.
Noteikta uzdevuma atrisinājums ir funkcija r: Y=r(X), kuru uzdod ieejas-izejas pāris (X1,Y1), (X2,Y2),... (XM,YM), kur Ym=r(Xm) (m=1,2,...,M). D ‑ kļūdas funkcija, kura parāda katras funkcijas g tuvības pakāpi r. Atrisināt uzdevumu ar dotās arhitektūras neironu tīkla palīdzību nozīmē izveidot (sintezēt) funkciju, izvēloties neironu parametrus (sinaptiskos svarus un nobīdes) tādā veidā, lai kvalitātes funkcionālis pārvērstos optimumā visiem pāriem (Xm,Ym).
Apmācības uzdevumu nosaka piecu elementu kopums:
, kur X un Y - atbilstoši ieeja un izeja; r - funkcija  r:X®Y, kas nosaka apmācības vēlamo rezultātu; apmācības uzdevumā pēc piemēriem funkciju r apraksta ieejas-izejas datu pāri: (X1,Y1), (X2,Y2),...(XM,YM), kuriem Ym=r(Xm) (m=1,2,...,M); G - funkciju g:X®Y kopa visiem ; neironu tīklu sakaru arhitektūra tiek uzskaitīta par dotu līdz apmācības sākumam, tā nosaka funkciju kopu G; D ‑ kļūdas funkcija, kas parāda katras funkcijas tuvību r, apmācības būtība ir tādas funkcijas g meklēšana, kura ir optimāla pēc D.
Apmācība ir iterācijas procedūra. Katrā iterācijā notiek kļūdas funkcijas samazināšana. Apmācība prasa ilgstošus aprēķinus. Ja ir izvēlēti daudzi apmācošie piemēri - pāri (Xm,Ym) (m=1,2,...,M) - un kļūdas funkcijas izskaitļošanas veids, neironu tīkla apmācība pārvēršas daudzdimensiju optimizācijas uzdevumā. Uzdevuma dimensiju skaits - no dažiem tūkstošiem līdz 108. Funkcija D ir patvaļīga, tādēļ vispārīgā gadījumā apmācība ir daudzekstrēmu neizliekts optimizācijas uzdevums.
Lai atrisinātu šo uzdevumu, var izmantot sekojošus algoritmus:
1.  Lokālās optimizācijas algoritms ar dažu pirmās kārtas līkņu aprēķinu.
2.  Lokālās optimizācijas algoritms ar atsevišķu pirmās un otrās kārtas līkņu aprēķinu.
3.  Stohastiskie optimizācijas algoritmi.
4.  Globālās optimizācijas algoritmi.
Pirmajai grupai pieder:
·        gradācijas algoritms (ātrākas nolaišanās metode),
·        mērķa funkcijas vien- un divdimensiju optimizācijas metodes antigradienta virzienā,
·        sajūgto gradientu metode,
·        metodes, kas ievēro vērā antigradienta virzienu dažu algoritma soļu attālumā.
Otrajai grupai pieder Ņūtona metode, optimizācijas metodes ar izretinātām Gesses matricēm, kvaziņūtoniskās metodes, Gausa-Ņūtona metode, Levenberga-Markarda metode.
Stohastiskie algoritmi ir meklēšana gadījuma virzienā, Monte-Karlo metode (statistisko mēģinājumu skaitļu metode).
Globālās optimizācijas uzdevumi tiek risināti, šķirojot mainīgos, no kuriem atkarīga mērķa funkcija.
Neironu tīklu apmācības metožu salīdzināšanai ir nepieciešams izmantot divus kritērijus:
1.     Algoritma soļu skaits, kas nepieciešami atrisinājuma iegūšanai
2.     Papildus mainīgo skaits, kuri nepieciešami aprēķinu procesa organizēšanai.
Lai ilustrētu terminu “papildus mainīgie”, parādīsim sekojošu piemēru. p1 un p2 - daži neironu tīkla parametri ar dotajiem lielumiem. Apmācības procesā pēc kāda algoritma katrā solī vismaz divas reizes nepieciešams izpildīt reizinājumu p1×p2. Lai minēto reizinājumu izpildītu tikai vienu reizi un netērētu laiku papildus reizināšanai, tiek izmantots papildus mainīgais, kurš saglabā lielumu pēc pirmā reizinājuma.
Priekšroka jādod tiem algoritmiem, kuri ļauj apmācīt neironu tīklu ar nelielu soļu skaitu un kuriem nepieciešams mazs papildus mainīgo skaits. Tas saistīts ar to, ka tīklu apmācība tiek veikta uz datoriem ar ierobežotu operatīvās atmiņas apjomu un nelielu veiktspēju. Kā likums, apmācībai tiek izmantoti personālie datori.
Pieņemsim, ka neironu tīkls satur P mainīgos parametrus (sinaptiskie svari un nobīdes). Pastāv tikai divas algoritmu apmācības grupas, kurām nepieciešami mazāk kā 2×P papildus parametri un kas sniedz iespēju apmācīt neironu tīklu ar pieņemamu soļu skaitu. Šie algoritmi ir ar atsevišķu pirmās kārtas līkņu skaitļošanu ar (iespējams) viendimensijas  optimizāciju.
Kaut arī minētie algoritmi dod iespēju atrast tikai lokālos ekstrēmus, tie var tikt izmantoti praksē neironu tīklu apmācībai ar daudzekstrēmu mērķa funkcijām (kļūdas funkcijām). Lieta tāda, ka mērķa funkciju ekstrēmu parasti nav daudz. Pietiek tikai divas reizes “izsist” tīklu no lokālā minimuma ar mērķa funkcijas lielāku vērtību, lai iterācijas rezultātā saskaņā ar lokālās optimizācijas algoritmu tīkls nonāktu lokālā mērķa funkcijas vērtības minimumā, kas tuvs nullei. Ja pēc dažiem mēģinājumiem “izsist” tīklu no lokālā minimuma vēlamais rezultāts netiek sasniegts, nepieciešams papildināt neironu skaitu visos slāņos no pirmā līdz priekšpēdējam. (Lai “izsistu” tīklu no lokālā minimuma, sinaptiskiem svariem un nobīdēm piešķir uzdotā diapazona gadījuma rakstura lielumu.)
Vairākkārtēji eksperimenti neironu tīklu apmācībā parādīja, ka lokālās optimizācijas izmantošana, tīkla “izsišanas” procedūras no lokālā minimuma un neironu skaita palielināšanas procedūras apvienošana noved pie veiksmīgas neironu tīklu apmācības.

1.2.2.Neironu tīkls apmācības laikā

Apskatīsim lineāru telpu ar dimensiju skaitu n, kas vienāds ar neironu tīkla iestādāmo parametru skaitu (sinaptiskie svari un nobīdes). Neironu tīkla stāvokli jebkurā laika momentā var noteikt ar punktu A (x1, x2,…, xn) šajā telpā. Apmācības laikā, katrā tā solī, tīkla stāvokli aprakstošais punkts par noteiktu attālumu pārbīdās virzienā, kurš samazina tīkla kļūdu atpazīstot doto tēlu. Tā kā katrā tīkla apmācības solī tīklam tiek uzrādīti dažādi tēli, tad arī tīkla stāvokli n‑dimensiju telpā aprakstošais punkts nobīdās dažādos virzienos, bet vispārējā nobīdes tendence ir vienā virzienā, uz punktu, kurš apraksta dotās tēlu kopas atpazīšanai apmācītu tīklu. Zīm.1.6. dots punkta vienas koordinātes izmaiņas atkarības grafiks, kurš apraksta tīkla stāvokli atkarībā no iterācijas numura, neironu tīklu ar konstantu soli apmācot binārai saskaitīšanai.
Zīm. 1.6.
Līkne citām punkta A koordinātēm xk ir līdzīga. Līkne rāda, ka apmācība ir visefektīvākā pirmajās 30 iterācijās.

1.2.3.Apmācības paradigmas

Spēja mācīties ir fundamentāla smadzeņu īpašība. Mākslīgo neironu tīkla kontekstā apmācības process var tikt izskatīts kā tīkla arhitektūras un svaru sakaru noskaņošana efektīvai speciāla uzdevuma izpildei. Tīklu funkcionēšana uzlabojas atkarībā no svaru koeficientu iteratīvās noskaņošanas. Tīkla spēja apmācīties ar piemēriem padara tos pievilcīgākus salīdzinājumā ar sistēmām, kuras seko noteiktai ekspertu noformulētai funkcionēšanas sistēmai.
Apmācības procesa koordinēšanai vispirms ir nepieciešams ārējas vides modelis, kurā funkcionē neironu tīkls, jāzina tīklam pieejamā informācija. Apmācības algoritms ir procedūra, kurā tiek izmantoti apmācības noteikumi svaru noregulēšanai.
Pastāv trīs apmācības paradigmas: “ar skolotāju”, “bez skolotāja” (pašmācība) un jauktā. Pirmajā gadījumā neironu tīklam ir pareizas atbildes (izejas tīkli) katram ieejas piemēram. Svarus noregulē tā, lai tīkls sniegtu atbildes pēc iespējas tuvāk zināmajām atbildēm. Pastiprināts apmācības variants ar skolotāju paredz, ka ir zināms tikai kritiskais neironu tīkla pareizības vērtējums, bet ne pašas pareizās izejas vērtības. Apmācība bez skolotāja neprasa pareizas atbildes zināšanu  katram apmācošajam piemēram. Šajā gadījumā tiek atklāta datu iekšējā struktūra vai korelācija starp piemēriem datu sistēmā, kas ļauj sadalīt paraugus kategorijās. Jauktas apmācības gadījumā daļa svaru tiek noteikta, izmantojot apmācību ar skolotāju, bet pārējie svari tiek noteikti ar pašmācības palīdzību.
Apmācības teorija izskata trīs fundamentālās īpašības, kuras saistītas ar apmācību pēc piemēriem: apjoms, paraugu sarežģītība un skaitļošanas sarežģītība. Ar apjomu tiek saprasts, cik paraugus var iegaumēt tīkls un kādas lēmuma pieņemšanas funkcijas un robežas tas spēj izveidot. Paraugu sarežģītību nosaka apmācošo piemēru skaits, kas nepieciešams, lai sasniegtu tīkla spēju vispārināt. Pārāk mazs piemēru skaits var radīt tīkla “pārapmācību”, kad tas labi funkcionē ar apmācošajiem piemēriem, bet slikti - ar testu piemēriem, kas pakļauti tai pašai statistiskai sadalei. Zināmi 4 apmācības noteikumu pamattipi: korekcija pēc kļudas, Bolcmana mašīna, Hebba noteikumi un apmācība pēc sacensību metodes.
Kļūdas korekcijas noteikumi. Apmācības gadījumā ar skolotāju katram ieejas piemēram noteikta vēlamā izeja d. Tīkla reālā izeja y var nesakrist ar vēlamo. Kļūdas korekcijas princips apmācoties ir signāla (d-y) izmantošana svaru modifikācijai, kas nodrošina pakāpenisku kļūdas samazināšanos. Apmācība ir nepieciešama tikai gadījumā, kad tīkls kļūdās. Ir zināmas dažādas šī algoritma apmācības modifikācijas [6].
Bolcmana apmācība. Bolcmana apmācības mērķis ir tāda svaru koeficientu noregulēšana, pie kuras redzamo neironu stāvoklis apmierina vēlamo varbūtību sadali. Bolcmana apmācība var tikt izskatīta kā kļūdas korekcijas īpašs gadījums, kur ar kļūdu tiek saprasta korelācijas stāvokļa nevienprātība divos režīmos.
Hebba noteikumi. Paši vecākie apmācības noteikumi ir Hebba apmācības postulāts [7]. Hebbs balstījās uz sekojošiem neirofizioloģijas novērojumiem: ja neironi sinapses abās pusēs aktivizējas vienlaicīgi un regulāri, tad sinaptiskā sakara spēks pieaug. Svarīga šī noteikuma īpatnība - sinaptiskā svara izmaiņas atkarīgas tikai no neironu, kuri saistīti ar doto sinapsi, aktivitātes. Tas būtiski vienkāršo apmācības mērķi VLSI realizācijā.
Apmācība pēc sacensību metodes. Atšķirībā no Hebba apmācības, kur vairums izejas neironu var uzbudināties vienlaicīgi, sacensību apmācībā neironu izejas sacenšas savā starpā par aktivizāciju. Šī parādība pazīstama kā “uzvarētājs paņem visu” noteikums. Tamlīdzīga apmācība pastāv bioloģiskajos neironu tīklos. Apmācība ar sacensību starpniecību ļauj klasterizēt ieejas datus: līdzīgus piemērus tīkls sagrupē atbilstoši korelācijai un parāda kā vienu elementu.
Apmācības gaitā tiek modificēti tikai “uzvarējušā” neirona svari. Šī likuma efekts tiek sasniegts uz tāda tīkla saglabātā piemēra (“uzvarējušā” neirona svaru sakaru vektora) izmaiņu rēķina, kur tas kļūst nedaudz tuvāks ieejas piemēram. 1.7. zīm. dota sacensību metodes apmācības ģeometriska ilustrācija. Ieejas vektori ir normalizēti un parādīti ar punktiem uz sfēras virsmas. Triju neironu svaru vektori inicializēti ar gadījuma vērtībām. To sākuma un beigu vērtības atzīmētas atbilstoši 1.7.a.zīm. un 1.7.b.zīm. Katra no piemēru grupām norādīta ar vienu no izejas neironiem, kura svaru vektors noregulēts uz konkrētās grupas smaguma centru.
1.7. zīm. Sacensību metodes apmācības piemērs:
a) pirms apmācības; b) pēc apmācības
Var atzīmēt, ka tīkls nekad nepārstāj apmācīties, ja apmācības ātruma parametrs nelīdzinās 0. Kāds ieejas piemērs var aktivizēt citu ieejas neironu sekojošās iterācijās apmācības procesa laikā.
Tas rada jautājumu par apmācības sistēmas stabilitāti. Sistēma tiek uzskatīta par stabilu, ja neviens no apmācošajiem piemēriem neizmaina savu piederību kategorijai pēc apmācības procesa iterāciju galīgā skaita. Viens no stabilitātes sasniegšanas veidiem ir apmācības ātruma parametra pakāpeniska samazināšana līdz 0. Tomēr šī mākslīgā apmācības bremzēšana rada citu problēmu, ko sauc par plastiskumu, un kas ir saistīta ar spēju adaptēties jauniem datiem. Šī sacensību metodes apmācības īpatnība pazīstama ar nosaukumu - Grosberga stabilitātes-plastiskuma dilemma.
1.3.tab. parādīti dažādi apmācības algoritmi un ar tiem saistītā tīklu arhitektūra. Pēdējā ailē uzskaitīti uzdevumi, kuriem varētu tikt pielietots katrs algoritms. Katrs apmācības algoritms orientēts uz noteiktas arhitektūras tīklu un paredzēts ierobežota līmeņa uzdevumu veikšanai.

Tabula 1.3
Zināmie apmācības algoritmi
Para­digma
Apmācības
likums
Arhitektūra
Apmācības algoritms
Uzdevems
Ar skolotāju
Kļūdas korekcija
Vienslāņainais un daudzslāņainais perceptrons
Perceptrona apmācības algoritmi
Atgriezeniska izplatīšanās
Adaline un Madaline
Tēlu klasificēšana,
funkcijas aproksimēšana,
vadīšana, paredzēšana

Bolcmans
Rekurentā
Bolcmana apmācības algoritms
Tēlu klasificēšana

Hebbs
Tiešas izplatīšanas daudzslāņainā
Lineāra diskriminatīvā analīze
Datu analīze,
tēlu klasificēšana

Sacensības
Sacensības
Vektora kvantēšana
Kategorizā­cija,
klases iekšpusē


Tīkls ART
ARTMap
Tēlu klasificēšana
Bez skolotāja
Kļūdas korekcija
Tiešas izplatīšanas daudzslāņaina
Samono projekcija
Kategorizā­cija, klases iekšpusē,
datu analīze

Hebbs
Tieša izplatīšanās vai sacensība
Galveno komponentu analīze
datu analīze,
datu sakļaušana


Hopfīlda tīkls
Asociatīvas atmiņas apmācība
Asociatīvā atmiņa

Sacensības
Sacensības
Vektora kvantēšana
Kategorizā­cija,
datu sakļaušana


Kohonena SOM
Kohonena SOM
Kategorizā­cija
Datu analīze


ART tīkli
ART1, ART2
Kategorizā­cija
Jaukta
Kļūdas korekcija un sacensība
RBF tīkls
RBF apmācības algoritms
Tēlu klasificēšana
funkcijas aproksimē­šana
Paredzēšana, vadīšana

1.2.4.Atgriezeniskās izplatīšanas algoritms

Neironu tīklu dažādo struktūru vidū viena no visizplatītajām ir daudzslāņu struktūra, kur katrs patvaļīgā slāņa neirons saistīts ar visiem iepriekšējā slāņa neironu aksoniem vai, pirmā slāņa gadījumā, ar visām neironu tīkla ieejām. Tādus neironu tīklus sauc par pilnīgi savienotiem. Ja tīklā ir tikai viens slānis, tā apmācības ar skolotāju algoritms ar acīmredzams, jo pareizie vienīgā slāņa neironu izejas stāvokļi ir iepriekš zināmi un sinaptisko sakaru pieregulēšana notiek virzienā, kas minimizē kļūdu tīkla izejā. Pēc šāda principa tiek veidots, piemēram, vienslāņa tīkla apmācības algoritms. Daudzslāņu tīklos optimālie visu slāņu izejas lielumi (izņemot pēdējo) parasti nav zināmi, un divu vai vairāku slāņu tīklu nevar vairs apmācīt, vadoties tikai pēc kļūdu lielumiem neironu tīkla izejās. Šīs problēmas risināšanas viens no variantiem - izejas signālu uzskaitījuma izstrāde, kuri atbilstu ieejas signālam, katram neironu tīkla slānim, kas, protams, ir ļoti darbietilpīgs process un ne vienmēr paveicams.
Otrs variants - sinapšu svaru koeficientu dinamiska noregulēšana, kuras laikā tiek atrasti visvājākie sakari, kas tiek izmainīti par vienu vienību uz vienu vai otru pusi, bet saglabātas tiek tikai tās izmaiņas, kuras radīja kļūdas samazināšanos visa tīkla izejā. Acīmredzams, ka dotā metode, neraugoties uz savu vienkāršību, prasa rutīnu skaitļošanu. Un, beidzot,  trešais, vispieņemamākais variants - kļūdas signālu izplatīšana no neironu tīkla izejām līdz ieejām, pretēji signālu tiešas izplatīšanas virzienam parastā darba režīmā. Šis neironu tīklu apmācības algoritms ir ieguvis atgriezeniskas izplatīšanas procedūras nosaukumu.
Saskaņā ar vismazāko kvadrantu metodi neironu tīkla kļūdas minimizējamā mērķa funkcija ir:
,

(1.13)
kur  - neirona tīkla izejas slāņa N neirona j reālais izejas stāvoklis, nosūtot tā ieejai p-to paraugu; djp ideāls (vēlamais) šī neirona izejas stāvoklis.
Summēšana tiek veikta visos izejas slāņa neironos visiem tīkla apstrādājamajiem paraugiem. Minimizācija veicama ar gradiētās nolaišanas metodi, kas nozīmē visu svaru koeficientu pieregulēšanu sekojošā veidā:
,

(1.14)
wij –sinaptisko sakaru svaru koeficients, kurš savieno n-1 slāņa i-to neironu ar n slāņa j-to neironu, h – apmācības ātruma koeficients, 0<h<1.
Kā parādīts [8],
.

(1.15)
Šeit ar yj  tāpat kā agrāk apzīmēta neirona j izeja, bet ar sj - tā ieejas signālu summa, t.i., aktivācijas funkcijas arguments. Tā kā reizinātājs dyj/dsj ir šīs funkcijas atvasinājums pēc tās argumenta, no tā izriet, ka aktivācijas funkcijas līkne ir definēta visai abscisu asij. Sakarā ar to vienreizējā lēciena funkcija un citas aktivācijas funkcijas ar neviendabībām neder izskatāmajiem neironu tīkliem. Tajos tiek lietotas tādas līdzenas funkcijas, kā hiperboliskais tangenss vai klasiskais sigmoīds ar eksponentu. Hiperboliskā tangensa gadījumā
.

(1.16)
Trešais reizinātājs sj/wij , acīmredzot, vienāds ar iepriekšējā slāņa yi(n‑1) neirona izeju.
Runājot par pirmo reizinātāju (1.15), tas viegli atainojams sekojošā veidā:
.

(1.17)
Šeit summēšana pēc k tiek veikta slāņa n+1 neironiem.
Ieviešot jaunu mainīgo
,

(1.18)
mēs iegūsim rekursīvo formulu slāņa n vērtību dj(n) aprēķināšanai no vecākā slāņa n+1 vērtībām dk(n+1) .
.

(1.19)
Izejas slānim
,

(1.20)
Tagad mēs varam pierakstīt (1.14) izvērstā veidā:
.
(1.21)
Dažreiz, lai piešķirtu svaru korekcijas procesam inerci, kas nolīdzina asos lēcienus pārvietojoties pa mērķa funkcijas virsmu, (1.21) tiek papildināta ar iepriekšējās iterācija svaru izmaiņu vērtību
,
(1.22)
kur m – inerces koeficients; t - tekošais iterācijas numurs.
Tādējādi, pilns neironu tīklu apmācības algoritms ar atgriezeniskas izplatīšanas procedūras palīdzību tiek veidots sekojoši:
1.     Sniegt tīkla ieejām vienu no iespējamajiem tēliem neironu tīkla parastas funkcionēšanas režīmā, kad signāli izplatās no ieejām uz izejām, izskaitļot izeju vērtības. Atgādināsim, ka
,

(1.23)
kur M - neironu skaits n-1 slānī, ievērojot neironu ar pastāvīgu izejas stāvokli +1, kas uzdod novirzi: yi(n-1)=xij(n) – i-tā n slāņa j neirona ieeja.
yj(n) = f(sj(n)), kur f() – sigmoīds
(1.24)

yq(0)=Iq,
(1.25)
kur Iq – ieejas tēla vektora q komponents.
2.     Izskaitļot d(N) izejas slānim pēc formulas (1.20)
Aprēķināt pēc formulas (1.21) vai (1.22) N slāņa svaru Dw(N) izmaiņas.
3.     Izskaitļot pēc formulām (1.19) un (1.21) (vai (1.19) un (1.22)) atbilstoši d(n) un Dw(n) visiem pārējiem slāņiem , n=N-1, … 1.
4.     Veikt visu neironu tīkla svaru korekciju
.

(1.26)
5.     Ja tīkla kļūda ir būtiska, pāriet uz 1 soli. Pretējā gadījumā - beigas.
Tīklam solim 1 pēc kārtas nejaušā veidā tiek padoti visi trenējošie tēli, lai tīkls, tēlaini runājot, neaizmirstu vienus, kamēr tiek iegaumēti citi.
No izteiksmes (1.21) izriet, ka, kad izejas lielums yi(n-1) teicas uz nulli, apmācības efektivitāte manāmi pazeminās. Izmantojot binārus ieejas vektorus, vidēji puse svaru koeficientu netiks koriģēta [4], tāpēc neironu izeju [0,1] iespējamo lielumu apvidu vēlams novirzīt [-0.5, +0.5] robežās, kas tiek panākts, izmantojot loģistisko funkciju vienkāršās modifikācijas. Piemēram, sigmoīda ar eksponenti tiek pārveidota šādā formā
.

(1.27)
Tagad aplūkosim neironu tīkla apjoma jautājumu, t.i. tīkla ieejām piedāvāto tēlu skaitu, kurus tas ir spējīgs iemācīties pazīt. Tīklos, kuros ir vairāk nekā divi slāņi, tas paliek atvērts. Kā parādīts [9], neironu tīklam ar diviem slāņiem, t.i. izejas slāni un vienu slēptu slāni, tīkla Cd determiniskais apjoms tiek novērtēts tā:
Nw/Nydw/Ny×log(Nw/Ny)
(1.28)
kur Nw - pielāgojamo svaru skaits, Ny - neironu skaits izejas slānī.
Jāatzīmē, ka dotā izteiksme iegūta, ņemot vērā dažus ierobežojumus. Pirmkārt, ieeju Nx skaitam un neironu skaitam slēptajā slānī Nh jāapmierina nevienādību Nx+Nh>Ny. Otrkārt, Nw/Ny>1000. Tomēr augstāk minētais vērtējums izpildās tīklos ar neironu aktivācijas funkcijām robežu veidā, bet tīkla ar līdzenām aktivācijas funkcijām apjoms parasti ir lielāks [9]. Bez tam apjoma nosaukumā iekļautais apzīmētājs “determiniskais” nozīmē, ka iegūtais apjoma vērtējums der absolūti visiem iespējamajiem ieejas tēliem, kuri var būt piedāvāti Nx ieejām. Patiesībā ieejas tēlu sadalīšanai parasti piemīt kāda regularitāte, kas neironu tīkliem ļauj vispārināt un tādā veidā palielināt reālo apjomu. Tā kā tēlu sadalījums vispārējā gadījumā iepriekš nav zināms, par šādu sadalījumu mēs varam runāt tikai nosacīti, bet parasti tas divas reizes pārsniedz determinisko apjomu.
Turpinot aplūkot neironu tīkla apjomu, loģiski būtu pieskarties jautājumam par nepieciešamo tīkla izejas slāņa jaudu, kurš izpilda galīgo tēla klasifikāciju. Lieta tāda, ka, lai sadalītu ieejas tēlu kopu, piemēram, divās klasēs, pietiek tikai ar vienu izeju. Pie kam katrs loģiskais līmenis - “1” un “0” - būs apzīmēts kā atsevišķa klase. Divās izejās var iekodēt jau 4 klases, un tā tālāk. Tomēr tādā veidā organizēta tīkla darba rezultāti nav īpaši droši. Lai paaugstinātu klasifikācijas ticamību, vēlams ieviest pārpilnību, iedalot katrai klasei vienu neironu izejas slānī vai, vēl labāk, vairākus, no kuriem katrs apmācīts noteikt piederību klasei ar savu ticamības pakāpi, piemēram, augstu, vidēju un zemu. Tādi neironu tīkli ļauj veikt ieejas tēlu, kuri apvienoti neskaidrā (izplūdušā) kopā, klasifikāciju. Šī īpašība tamlīdzīgus neironu tīklus pietuvina reālās dzīves apstākļiem.
Izskatāmajam neironu tīklam ir dažas “šauras vietas”. Pirmkārt, apmācības procesā var rasties situācija, kad svaru koeficienta lielas pozitīvas vai negatīvas vērtības nobīdīs daudzu neironu sigmoīdu darba punktu uz piesātinājuma apvidu. Loģistiskās funkcijas atvasinājuma mazās vērtības saskaņā ar (1.19) un (1.20) novedīs pie apmācības apstāšanās, kas paralizēs neironu tīklu. Otrkārt, gradientās nolaišanās metode negarantē, ka tiks atrasts globāls, bet ne lokāls mērķa funkcijas minimums. Šī problēma saistīta vēl ar vienu, un tieši - apmācības ātruma lieluma izvēli. Apmācības savienojamības pierādījums atgriezeniskās izplatīšanas procesā balstās uz atvasinājumiem, t.i. svaru pieaugšanai un tātad, apmācības ātrumam jābūt bezgalīgi maziem, tomēr šajā gadījumā apmācībai jānotiek nepieņemami lēni. No otras puses, ļoti liela svaru korekcija var novest pie nepārtrauktas apmācības procesa nestabilitātes. Tāpēc h parasti izvēlas mazāku par 1, bet ne ļoti mazu, piemēram, 0.1 un tas apmācības gaitā var pakāpeniski samazināties. Bet tam, lai izslēgtu gadījuma trāpījumus lokālajos minimumos dažreiz (pēc tam, kad svaru koeficientu lielumu nostabilizējas) h īslaicīgi ļoti palielina, lai sāktu gradienta nolaišanos no jaunā punkta. Ja vairākkārt atkārtojot šo procedūru, algoritms novedīs vienā un tajā pašā neironu tīkla stāvoklī, var vairāk vai mazāk pārliecināti teikt, ka atrasts globālais minimums un ne kas cits.


1.3.Neironu tīklu pamatparadigmas

1.3.1.Pretimnākošās izplatīšanas tīkls

Autori un rašanās vēsture

Pretimnākošās izplatīšanas tīklus radījis Roberts Heht-Nilsons.

Modelis

Pretimnākošas izplatīšanas tīklā apvienoti divi algoritmi: pašorganizācijas Kohonena karte un Grossberga zvaigzne. To apvienošanās noved pie pretimnākošas izplatīšanās modeļa tādu īpašību parādīšanās, kuru nav katram no šiem algoritmiem atsevišķi.
Neironu tīkliem, kuri apvieno dažādas neiroparadigmas kā būvēšanas blokus, pēc arhitektūras ir tuvāki smadzenēm nekā viendabīgas struktūras. Tiek uzskatīts, ka dažādas specializācijas kaskādes savienošanas moduļi smadzenēs ļauj izpildīt nepieciešamo skaitļošanu.
Tīkla pretimnākošas izplatīšanas apmācības procesā ieejas vektori var būt divēji vai nepārtraukti. Pēc apmācības tīkls formē izejas signālus, atbilstošus ieejas signāliem. Apkopojot tīkla iespējas tiek sniegta iespēja saņemt pareizu izeju, kad ieejas vektors ir nepilnīgs vai sagrozīts.
Pretimnākošas izplatīšanas tīklam ir divi slāņi ar pakāpeniskiem sakariem. Pirmais slānis - Kohonena slānis, otrs - Grosberga slānis. Katrs ieejas signāla elements tiek padots visiem Kohonena slāņa neironiem. Sakaru svari (Wmn) veido matrici W. Katrs slāņa neirons savienots ar visiem Grosberga slāņa neironiem. Svaru sakari (Vnp) veido matrici V. Pretimnākošās izplatīšanas tīkla atšķirība no citiem daudzslāņu tīkliem ar pakāpeniskiem sakariem ir operācijas, kuras izpilda Kohonena un Grasberga neironi.
Tīkla funkcionēšanas režīmā parādās ieejas signāls X un tiek formēts izejas signāls Y. Apmācības režīmā tīkla ieejai tiek nosūtīts ieejas signāls un svari tiek koriģēti, lai tīkls dotu nepieciešamo izejas signālu.
TĪKLA FUNKCIONĒŠANA
Kohonena slānis. Visvienkāršākajā formā Kohonena slānis funkcionē pēc likuma “uzvarētājs saņem visu”. Dotajam ieejas vektoram viens un tikai viens Kohonena neirons dod loģisku 1, visi pārējie dod 0. Katra Kohonena neirona izeja ir vienkārši ieejas signālu svērto elementu summa:
(1.29)
kur NETj - Kohonena j-tā neirona izeja, Wj=(w1j,w2j,...,wmj) - Kohonena j-tā neirona svaru vektors, X=(x1,x2,...,xm) - ieejas signālu vektors, vai vektoru matrices formā:
N=XW (2),
(1.30)
kur N - Kohonena slāņa izeju NET vektors.
Kohonena neirons ar maksimālu lielumu NET ir “uzvarētājs”. Tā izeja līdzinās 1, pārējiem tā līdzinās  0. Grosberga slānis funkcionē līdzīgi. Tā izeja NET ir Kohonena slāņa izeju svērtā summa.
Ja Kohonena slānis funkcionē tādā veidā, ka tikai viena izeja līdzinās 1, bet pārējās - 0, tad katrs Grosberga neironu slānis uzrāda svara lielumu, kurš saista šo neironu ar vienīgo Kohonena neironu, kura izeja nav nulle.
Iepriekšēja signālu apstrāde.
Ieejas vektoru normalizācija (iepriekšējā apstrāde) tiek veikta dalot katru ieejas vektora komponenti ar vektora garumu (kvadrātsakni no vektora komonenšu kvadrātu summas). Tas ieejas vektoru pārveido par tā paša virziena vienības vektoru, t.i., par vienības vektoru n-dimensiju telpā.
Kohonena slāņa apmācība.
Kohonena slānis klasificē ieejas vektorus līdzīgu vectoru grupās. Tas tiek panākts ar tādu Kohonena slāņa svaru koriģēšanu, ka tuvi ieejas vektori aktivizē vienu un to pašu dotā slāņa neironu. Pēc tam Grosberga slāņa uzdevums ir nepieciešamo izeju iegūšana.
Kohonena slānis apmācās bez skolotāja (pašmācība). Apmācības rezultātā slānis iegūst spēju atšķirt dažādu ieejas vektorus. Iepriekš grūti paredzēt, tieši kāds neirons aktivēsies, uzrādot konkrētu ieejas signālu.
Kohonena slāņa apmācībā ieejā tiek padots ieejas vektors un tiek aprēķināta tā skalārā līkne ar visu neironu svaru vektoriem. Skalārā līkne ir salīdzināšanas mērs starp ieejas vektoru un svaru vektoru. Neirons ar maksimālo skalārās līknes lielumu tiek paziņots par “uzvarētāju” un tā svari tiek noregulēti (svaru vektors tiek pietuvināts ieejas vektoram).
Apmācības procesu raksturojošs vienādojums:
,
(1.31)
kur wx - jaunais svara lielums, kurš savieno ieejas komponentu x ar uzvarējušo neironu, w0 - iepriekšējais šī svara lielums, a - apmācības ātruma koeficients.
Katrs ar uzvarējušo Kohonena neironu saistītai svarai izmainās proporcionāli tā lieluma un ieejas lieluma, kuram tas pievienots, starpībai. Izmaiņu virziens minimizē starpību starp svariem un atbilstošu ieejas signāla elementu. Mainīgais a ir apmācības ātruma koeficients, kurš sākumā parasti līdzinās 0.7 un apmācības procesā var pakāpeniski samazināties. Tas ļauj veikt lielākus sākuma soļus ātrai, rupjai apmācībai un mazākus soļus, nonākot pie galīgā soļa.
Ja ar katru Kohonena neironu asociētos viens ieejas vektors, tad Kohonena slānis varētu tikt apmācīts ar viena svaru (a=1) aprēķina palīdzību. Kā likums, apmācošais vairums ietver sevī daudzus savā starpā līdzīgus ieejas vektorus, un tīklam jābūt apmācītam aktivēt katram no tiem vienu un to pašu Kohonena neironu. Šī neirona svariem jāiznāk to ieejas vektoru vispārinājumam, kuriem tas jāaktivizē.
Grosberga slāņa apmāčība.
Kohonena slāņa izejas nonāk Grosberga slāņa neironu izejās. Neironu izejas tiek aprēķinātas kā parasti funkcionējot. Turpmāk katrs svars tiek koriģēts tikai tādā gadījumā, ja tas savienots ar Kohonena neironu, kam ir nenulles izeja. Korekcijas svara lielums proporcionāls starpībai starp svariem un nepieciešamo Grosbarga neirona izeju.
Grosberga slāņa apmācība - tā ir apmācība ar skolotāju, algoritms izmanto uzdotās vēlamās izejas. Pilnas atgriezeniskās izplatīšanās tīkla modelim ir iespēja saņemt izejas signālus caur ieejas un otrādi. Šīm divām darbībām atbilst tiešā un atgriezeniskā signālu izplatīšana.

Pielietošana

Tēlu atpazīšana, tēlu atjaunošana (asociatīvā atmiņa), datu saspiešana (ar zudumiem).

Trūkumi

Tīkls nedod iespēju veidot precīza aproksimācijas (precīzus atveidojumus). Te tīkls būtiski atpaliek no tīkliem ar atgriezenisku kļūdas izplatīšanos. Pie modeļa trūkumiem ir attiecināma arī pretimnākošās izplatīšanas tīkla modifikāciju vāja teorētiskā izstrāde.

Priekšrocības

Pretimnākošās izplatīšanās tīkls ir vienkāršs. Tas dod iespēju iegūt statistiskās  īpašības no daudziem ieejas signālu kopām. Kohonens ir parādījis, ka pilnīgi apmācīta tīklā iespējamība, ka nejauši izvēlēt ieejas vektors (atbilstoši ieejas vairākuma varbūtības blīvuma funkcijai) būs tuvākais jebkuram no uzdotajiem svaru vektoriem, līdzinās 1/k, kur k - Kohonena neironu skaits.
Tīkls apmācās ātri. Apmācības laiks, salīdzinājumā ar atgriezenisko izplatīšanos, var būt 100 reizes mazāks. Pēc iespējām veidot atveidojumus, pretimnākošās izplatīšanas tīkls būtiski pārspēj vienslāņainos perceptronus. Tīkls lietderīgs letojumos, kuriem nepieciešama ātra sākuma aproksimācija. Tīkls dod iespēju veidot funkciju un tai atgriezenisku, kas pielietojams praktisku uzdevumu atrisināšanā.

Modifikācijas

Pretimnākošās izplatīšanās tīkli var atšķirties ar sinaptisko svaru sākuma lielumu noteikšanas veidiem. Tā, bez tradicionālajiem gadījuma dotā diapazona gadījuma lielumiem, var tikt izmantoti lielumi atbilstoši izliektās kombinācijas metodei [4].
Lai paaugstinātu apmācības efektivitāti, tiek izmantota trokšņa pievienošana ieejas vektoram. Vēl viena apmācības efektivitātes paaugstināšanas metode - piešķirot “taisnības sajūtu” katram neironam. Ja neirons kļūst par uzvarētāju biežāk kā 1/k (k - Kohonena neironu skaits), tad tam uz laiku palielina slieksni, ar to pašu ļaujot apmācīties ar citiem neironiem.
Bez “akreditācijas metodes”, kur katram ieejas vektoram aktivējas tikai viens Kohonena neirons, var tikt izmantota “interpolācijas metode”, kuru izmantojot, vesela Kohonena neirona grupa, kuriem ir vislielākās izejas var nodot savus izejas signālus Grosberga slānim. Šī metode paaugstina tīkla realizēto atveidojumu precizitāti.

1.3.2.Maksimuma meklēšanas tīkls ar tiešiem sakariem

Nosaukumi

Pamatnosaukums - Feed-Forward MAXNET - tīkls maksimuma meklēšanai ar tiešiem sakariem. Cits nosaukums - maksimuma meklēšanas tīkls, kurš balstās uz bināro koku un neirotīklu komparatoriem.

Autori un rašanās vēsture

Tīkls ieteikts [13] kā papildinājums Heminga tīklam.

Modelis

1.8. zīm. Neirotīklu komparators
Daudzslāņu tīkls ar tiešiem sakariem. Ieejas signāli pa pāriem tiek salīdzināti viens ar otru. Vislielākais signāls katrā pārī tiek pārraidīts uz nākamo slāni tālākai salīdzināšanai. Tīkla izejā tikai vienam signālam ir nenulles lielums. Tas atbilst maksimālajam signālam tīkla ieejā.
Par pamatu ņemts neirotīklu komparators (1.8. zīm.), kurš izpilda divu analogu signālu (x1 un x2) salīdzināšanu. Izejā 2 - maksimālā signāla (x1 vai x2) lielums. Izejas y1 un y2 parāda, kuram tieši ieejas signālam ir maksimāls lielums. Visu tīkla neironu nobīde - nulle. Melnā krāsā atzīmētajiem neironiem ir stingras robežfunkcijas, pārējo neironu pārraidošās funkcijas - lineāras ar piesātinājumu.
1.9. zīm. Tīkls maksimuma meklēšanai ar tiešiem sakariem
1.9. zīm. parādīts tīkls maksimuma meklēšanai ar tiešiem sakariem, kurš dod iespēju noteikt maksimālo signālu no astoņiem ieejas signāliem. Tīkls sastāv no vairākiem komparatoriem un papildus neironiem un sakariem. Komparatoru sinaptiskie svari tādi paši kā zīm. 1.9. Citu sakaru svari - vienīgie. Melnajiem neironiem ir stingras robežfunkcijas (zīm. 1.10.), balto neironu pārraidošās funkcijas - lineāras ar piesātinājumu (zīm. 1.11.). Pēdējā slāņa neironiem ir 1.12. zīm. attēlotās pārraidošās funkcijas.
IEEJAS SIGNĀLU TIPS: analogie (veselie vai reālie)
IZEJAS SIGNĀLU TIPS: veselie.
IEEJAS UN IZEJAS VIENMĒRĪGUMS programmrealizācijā ierobežots tikai ar neironu tīklu modelējošās skaitļošanas sistēmas iespējām, aparātrealizācijā - ar tehnoloģiskajām iespējām. Ieejas un izejas signālu dimensijas sakrīt.
TĪKLA SLĀŅU SKAITS: aptuveni log2(M), kur M - ieejas signāla dimensija.
1.10. zīm. Stingrā robežfunkcija
1.11. zīm. Pārraidošā “lineārā ar piesātinājumu” tipa funkcija


1.12. zīm. Pēdēja neirona slāņa pārraidošā funkcija

Pielietošana

Kopīgi ar Heminga tīklu, tēlu atpazīšanas neironu tīklu sistēmu sastāvā.

Trūkumi

Tīkla slāņu skaits pieaug palielinoties ieejas signāla dimensiju skaitam.

Priekšrocības

Atšķirībā no MAXNET tīkla cikliskās funkcionēšanas, izskatāmajā modelī iepriekš ir zināms aprēķinu apjoms, kurš nepieciešams atrisinājuma iegūšanai.

Modifikacijas

Lai atrisinātu uzdevumu izdalīt signālu ar maksimālo lielumu no kādas signālu kopas, visbiežāk tiek izmantots cikliskas funkcionēšanas MAXNET tīkls.

1.3.3.Gausa klasifikators

Autori un rašanās vēsture

Modeli ieteica Lipmans 1987. gadā.

Modelis

Perceptrons var tikt izmantots realizējot Gausa klasifikatoru pēc varbūtības maksimuma. Klasiskajā perceptrona apmācības algoritmā netiek izmantoti pieņēmumi, attiecībā uz apmācībā izmantotās izlases iztvērumu piemēru sadalījumu, bet tiek izskatīta kļūdas funkcija. Šis algoritms strādā daudz stabilāk, ja ieejas signāli formējas nelineāro procesu rezultātā, un ir sadalīti nesimetriski, un ne pēc Gausa likuma. Gausa klasifikatora pamatā ir pieņemumi par ieejas signālu sadalījumu. Tiek uzskatīts, ka šie sadalījumi ir zināmi un atbilst Gausa likumam.
Neirotīkla Gausa klasifikatora parametru aprēķinu formulas tie noteiktas sekojoši. Lai mAi un sAi2 - vidējais lielums un nobīde (mat. gaidīšana un dispersija) ieejas signālam xi , kad ieejas signāls pieder klasei A, mBi un sBi2 -  ieejas signāla xi vidējais lielums un nobīde, kad ieejas signāls pieder klasei B, un sAi2=sBi2=si2 . Tad varbūtības lielumi, kurus izmanto klasifikators pēc varbūtības maksimuma ir proporcionāli sekojošiem lielumiem:
,
(1.32)

.
(1.33)
Klasifikatoram pēc varbūtības maksimuma jāaprēķina LA, LB un jāizvēlas klasi ar vislielāko varbūtību. Pirmie saskaitāmie formulās ir identiski. Tāpēc tos var izslēgt. Otrie saskaitāmie var tikt aprēķināti, reizinot ieejas signālus ar sinaptiskajiem svariem. Trešie saskaitāmie - konstantes, kuru lielums var piešķirt neirona nobīdei. Sinaptisko svaru lielumi:
.
(1.34.)
Nobīdu lielumi:
.
(1.35)
IEEJAS SIGNĀLU TIPS: binārie vai analogie (reālie).
IEEJAS UN IZEJAS VIENMĒRĪGUMS programmrealizācija ir ierobežots tikai ar neironu tīklu modelējošas skaitļojamās sistēmas iespējām, aparātrealizācijā - ar tehnoloģiskajām iespējām.

Pielietošana

Tēlu atpazīšana, klasifikācija.

Trūkumi

Primitīvas atdalošās virsmas (hiperplaknes) dod iespēju risināt tikai pašus vienkāršākos atpazīšanas uzdevumus. Par apriori zināmu tiek uzskatīta dažādām klasēm atbilstošu ieejas signālu sadalījums.

Priekšrocības

Programmas vai aparātrealizācijas modeļi ir ļoti vienkārši. Sinaptisko svaru formēšanas un nobīdes algoritms ir vienkāršs un ātrs.

Modifikācijas

Var izveidot adaptīvo Gausa klasifikatoru.

1.3.4.Ieejas zvaigzne

Autori un rašanās vēsture

Konfigurācija “instar” - neironu tīkla fragments, kuru piedāvāja un pielietoja daudzos neirotīklu modeļos izmantoja Grosbergs.

Modelis

Ieejas zvaigzne, kā parādīts 1.13. zīm., sastāv no neirona, kuram tiek padota ieeju grupa caur sinaptiskajiem svariem. Ieejas un izejas zvaigznes var būt savstarpēji savienotas jebkuras sarežģītības tīklā. Grosbergs izskatīja ieejas zvaigznes kā bioloģisko smadzeņu atsevišķu dalu modeļus.
1.13. zīm. Grosberga "Instar"
Ieejas zvaigznes apmācība
Ieejas zvaigzne tiek apmācīta reaģēt uz noteiktu ieejas vektoru X un ne uz kādu citu. Šī apmācība tiek realizēta, noregulējot svarus tādā veidā, lai tie atbilstu ieejas vektoram. Zvaigznes izeja tiek noteikta kā tās ieeju summa līdzsvarotā. No cita redzesviedokļa, izeju var uzskatīt par ieejas vektora un svaru vektora apvienojumu. Tātad, neironam ir jāreaģē daudz stiprāk uz ieejas tēlu, kuram tas ir apmācīts.
Apmācības procesu izsaka sekojoša formula:
wi(t+1) = wi(t) + a[xi - wi(t)] ,
(1.36)

kur wi - ieejas xi svars, xi - i-tā ieeja, a - normējošais apmācības koeficients, kura sākuma lielums 0.1 un kurš apmācības procesā pakāpeniski samazinās.
Pēc apmācības, ieejas vektora X uzrādīšana aktivizēs apmācīto ieejas neironu. Labi apmācīta ieejas zvaigzne reaģēs ne tikai uz noteiktu vektoru, bet arī uz nenozīmīgām šī vektora izmaiņām. Tādā veidā zvaigzne izrādī spēju vispārināt. Tas tiek sasniegts, pakāpeniski noregulējot neironu svaru, apmācības procesā uzrādot vektorus, kuri sākotnējā ieejas vektora variācijas. Svari tiek noregulēti tādā veidā, lai pielīdzinātu apmācošo vektoru lielumus, un neironi iegūst spēju reaģēt un jebkuru šīs klases vektoru.

Pielietošana

Izskatīto konfigurāciju var pielietot tēlu atpazīšanas tīklos.

Trūkumi

Katra zvaigzne atsevišķi realizē pārāk vienkāršu funkciju. No tādām zvaigznēm nav iespējams uzbūvēt neironu tīklu, kurš realizētu jebkuru uzdoto atveidojumu. Tas ierobežo praktisku ieejas zvaigžņu pielietošanu.

Piekšrocības

Ieejas zvaigzne labi modelē dažu dzīvo (bioloģisko) neironu tīklu komponentu funkcijas. Ieejas zvaigžņu tīkls var būt pietiekami labs atsevišķu smadzeņu apgabalu modelis. Risinot praktiskus uzdevumus, ieejas zvaigznes var tikt izmantotas vienkāršu ātri apmācāmu tīklu uzbūvei.

Modifikācijas

Ieejas zvaigžņu modeļi var izmantot dažādus apmācību normējošo koeficientu izmaiņas atkarībā no laika algoritmus.

1.3.5.Izejas zvaigzne

Autori un rašanās vēsture

Konfigurācija “OutStar” - neironu tīkla fragments, kuru piedāvāja un pielietoja daudzos neirotīklu modeļos izmantoja Grosbergs.

Modelis

1.14. zīm. Grosberga "Outstar"
Izejas zvaigzne, kā parādīts 1.14. zīm., sastāv no neirona, kurš vada svaru grupu. Ieejas  un izejas zvaigznes var būt savstarpēji savienotas tīklā jebkurā sarežģības pakāpes tīklā.
 Grosbergs izskatīja izejas zvaigznes kā atsevišķu bioloģisko smadzeņu atsevišķu daļu modeļus.
Izejas zvaigznes apmācība:
Ieejas zvaigzne tiek uzbudināta uzrādot noteiktu ieejas vektoru, bet izejas zvaigznei ir papildus funkcija, tā izstrādā nepieciešamo uzbudinošo signāli citiem neironiem katru reizi, kad uzbudinās.
Izejas zvaigznes neirona apmācības procesā, tā svari tiek noregulēti atbilstoši nepieciešamajam mērķa vektoram.
Apmācības procesu izsaka sekojoša formula:
wi(t+1) = wi(t) + b[yi - wi(t)] ,
(1.37)
kur b - apmācību normējošs koeficients, kurš sākumā aptuveni līdzinās 1 un pakāpeniski apmācības procesā samazinās līdz 0.
Kā arī ieejas zvaigznes gadījumā, izejas zvaigznes svari pakāpeniski tiek noregulēti uz vektoru kopu, kuri ir uzrāda ideālā (galīgā) vektora variācijas. Šajā gadījumā neironu izejas ir apmācošās kopas statistiskais raksturlielums.

Pielietošana

Izskatītā konfigurācija var tikt izmantota tēlu atpazīšanas tīklos.

Trūkumi

Katra zvaigzne atsevišķi realizē pārāk vienkāršu funkciju. No tādām zvaigznēm sastāvošā neironu tīkla skaitļošanas spējas ir ierobežotas.

Priekšrocības

Izejas zvaigzne labi modelē dzīvo (bioloģisko) neirontīklu dažu komponentu funkcijas. Tīkls, kurš satur izejas zvaigznes, var būt pietiekami atsevišķu smadzeņu daļu labs modelis.
Risinot praktiskus uzdevumus, izejas zvaigznes var būt izmantotas vienkāršu ātri apmācāmu tīklu izveidošanā.

Modifikācijas

Izejas zvaigžņu modeļi var izmantot dažādus apmācību normējošo koeficientu izmaiņas atkarībā no laika algoritmus


2.Neironu tīklu darba matemātiskā modelēšana

2.1.Neironu tīkla darbības matemātiskā modelēšanas uzdevuma izvirzīšana.


Neironu tīkla sintēze, kas paredzēta noteiktu uzdevumu risināšanai, ir ļoti sarežģīta daudzpakāpju procedūra. Mūsdienu neironu tīkli pamatā paredzēti tādu uzdevumu risināšanai, kā tēlu atpazīšana, tāpēc par pirmo soli neirona tīkla veidošanā kļūst tēlu apraksts, ar kuru atpazīšanu vajadzēs nodarboties. Pie pirmās apskates tēla sarežģītību var raksturot ar tā binārā apraksta garumu - tēla attēlošanu nuļļu un vieninieku kodā. Kā likums, interesējošiem atpazīšanai paredzētiem tēliem apraksts satur simtus, tūkstošus un desmitus tūkstošus bitu. Tāpēc neironu tīkliem, kuri ir spējīgi tēlu atpazīt, jāsatur simtiem, tūkstošiem elementu ieejas slānī. Tādu tīklu realizācija aparatūras līmenī ir iespējama, bet to modelēšana programmu līmenī patērē lielus skaitļojamos resursus un ir realizējama vienīgi uz superdatoriem. Tāpēc praksē notiek tēla "pievilkšana" tādam izskatam, kurš var tikt uztverts ar saprātīgas sarežģītības pakāpes neironu tīklu. Tāda objekta “pievilkšana” ir neirona tīkla sintēzes otrais etaps. Trešais sintēzes etaps ir saistīts ar tīkla struktūras izvēli - slāņu skaits, ieejas un izejas slāņu elementu skaits, noslēpto slāņu un to elementu skaits, aktivācijas funkcijas veids. No šo parametru izvēles būs atkarīgi tādi tīkla parametri, kā apmācības ātrums, stabilu tēlu formēšanas spēja, jūtīgums uz minimālām ieejas datu izmaiņām. Jāievēro, ka daudzi neironu tīkla parametri ir savstarpēji viens otru izslēdzoši: jo lielāka tīkla apmācāmība, jo mazāka ir tā stabilitāte; jo vairāk sarežģītu tēlu spēj tīkls uztvert, jo lielāks ir elementu skaits un, attiecīgi, apmācāmības laiks. Nākošais - ceturtais sintēzes solis ir paradigmas un apmācības algoritma izvēle. Tagad literatūrā ir aprakstīti desmitiem neironu tīklu apmācības algoritmu, kas tika izveidoti dažādām struktūrām un vajadzībām. Bez salīdzinoši vienkāršiem algoritmiem, tādiem kā atgriezeniskās izplatības algoritma, eksistē daudz sarežģītāki algoritmi. Atkarībā no algoritma izvēles, apmācāmības laiks var atšķirties simtiem reižu. Tāpēc apmācāmības uzdevums, kas nav atrisināms ar vienas klases algoritmu palīdzību, izrādāms atrisināms, izvēloties apmācības algoritmu no citas klases.
Šim darbam ir divi pamatuzdevumi: izveidot tīkla sintēzes metodiku, un balstoties uz izstrādāto metodiku, izveidot reālu tīklu fjučeru tirgus trenda pagriešanas noteikšanai (tehniskās analīzes pamatuzdevums). Šie uzdevumi tika risināti ar pakāpeniska tuvinājuma metodēm. No sākuma tika formulēts sintēzes uzdevums vienkāršam tēla atpazīšanas tīklam. Pēc tīkla izveides tika analizēti tīkla sintēzes pamatetapi un novērtēti tīkla sintēzes dažādu etapu raksturojums - laika patēriņš struktūras izveidei, atgriezeniskās izplatības algoritma uzrakstīšana, programmēšana, tīkla apmācības un testēšanas laiks. Pēc pilna vienkārša tīkla izveides tika uzstādīts uzdevums par daudz sarežģītāka tīkla izveidi, ievērojot pirmā uzdevuma rezultātus.
Pēc tam, līdzīgi kā iepriekš, tika veikta analīze, līdzīgi kā iepriekš, pēc kā procedūra atkārtojās daudz sarežģītākam uzdevumam.
Par pirmo, kur tika izmēģināta iepriekš aprakstītā sintēzes metode, kļuva uzdevums, kur vajadzēja apmācīt neironu tīklu vienkāršām loģiskām operācijām. Otrs uzdevums bija par pasta indeksu ciparu simbolu atpazīšana. Trešais - apmācīt neironu tīklu trigonometrisko funkciju skaitļošanai. Ceturtais uzdevums bija neironu tīkla apmācīšana trigonometrisko funkciju vērtību prognozēšanai, izejot no iepriekšējiem trigonometrisko funkciju rezultātiem. Piektais uzdevums - reāla trenda atpazīšana.
Visi šie, pieaugošas sarežģītības pakāpes uzdevumi tika risināti ar augstākminēto neironu tīkla sintēzes metodoloģiju. Praktiskai šīs metodoloģijas realizācijai bija izveidota universāla modelējoša programma, kas ļauj veidot tiešas izplatības tīklus ar mainīgu struktūru, ar atšķirīgu ieejas un izejas slāņu elementu skaitu, starpslāņu un to elementu skaitu. Dotā modelējošā shēma tika veidota, lai izmantotu to augstākas klases mašīnās nekā personālie datori, un tā tika uzrakstīta tā lai būtu neatkarīga no konkrētas platformas.
Dotās modelējošās programmas uzrakstīšana ļāva ātri izveidot lielu daudzumu visdažādāko neironu tīklu, kas savukārt ļāva ātri pārveidot neironu tīklu konkrētam uzdevumam un pētīt tīkla struktūras ietekmi uz tās apmācības ātrumu, darba stabilitāti, tēla atpazīšanas precizitāti.
Galvenā modelējošās programmas daļa ir modulis, kas satur funkcijas manipulācijām ar mākslīgā neironu tīkla modeli.
Modulis paredzēts mākslīgā, tiešās izplatības homogēnā neironu tīkla darba modelēšanai, un satur funkcijas, kas ļauj izveidot tīklu atmiņā, saglabāt uz diska, nolasīt no diska, veikt neirona tīkla modeļa apmācību pēc autonoma gradienta atgriezeniskās izplatības algoritma, veikt informācijas apstrādi ar tīkla palīdzību.
Modulis uzrakstīts standarta ANSI C valodā, tāpēc to var kompilēt jebkurā operētājsistēmā ar jebkuru kompilatoru, kurš atbalsta šo standartu. Tā, piemēram, moduli var nokompilēt Win32 platformā bibliotēkā .dll un izmantot tā mākslīgā neironu tīkla manipulēšanas funkcijas no Visual Basic vai Delphi for Windows.
Moduļa teksta uzrakstīšanai izmantots teksta redaktors "Edit", kas ietilpst MS-DOS 6.22 standarta komplektā, un kompilators Watcom C32 Optimizing Compiler Version 10.0. Kompilācija tika veikta aizsargātajam procesora darba režīmam (DPMI) operāciju sistēmā MS-DOS.

2.2.Modelējošās programmas funkcijas

2.2.1.Funkciju vispārējs apraksts

Kā jau iepriekš minēts, neirona tīklu modelējošais programmas kodols, kas uzrakstīts valodā ANSI C, ir izveidots kā atsevišķs modulis "nnet.c". Modulis "nnet.c" satur divu tipu funkciju realizācijas aprakstu: funkcijas, kas ļauj manipulēt ar neironu tīkliem programmētāja līmenī, un funkcijas kuras izmanto pats "nnet.c" modulis. Tālāk tiek dots īss pirmā tipa funkciju apraksts:
nnet_init - inicializē doto tipa tneuronet mainīgo, aprakstītu failā "nnet.h", un operatīvajā atmiņā izveido neirona tīkla modeli ar uzdotiem parametriem (aktivējošās funkcijas veids, slāņu skaits un neironu skaits katrā slānī). tneuronet tipa mainīgais - struktūra, saistīta ar neironu tīklu (analogiska FILE struktūrai, kas saistīta ar failiem C valodā), unikāli identificē neironu tīklu un satur pamatdatus par tīkla arhitektūru, kas pieejami programmētājam caur struktūras laukiem. Tāpēc datora atmiņā vienlaicīgi var eksistēt vairāki cits no cita neatkarīgi neironu tīkli, iespējams, ar dažādu arhitektūru. To daudzums ir atkarīgs no datora brīvās operatīvās atmiņas apjoma.
nnet_free - izpilda procedūru, pretēju nnet_init dotajam neironu tīklam.
nnet_save - saglabā visu informāciju par dotā neironu tīkla arhitektūru (slāņu skaits, neironu skaits katrā slānī, aktivējošais funkcijas veids) un uzstādāmās tīkla vērtības (saikņu svaru un pārvietojumu) failā ar doto nosaukumu. Faila nosukumam jāievēro ierobežojumi, kas ir saistīti ar dažādu operētājsistēmu īpatnībām. Tā, piemēram, MS-DOS faila nosukuma garums nedrīkst pārsniegt 8 simbolus. Tā kā funkcija nnet_save tiek izmantota ierakstam pie tīkla apmācības ar automātisku soļa garuma izvēli, lai iegūtu maksimālu ātrdarbību, tika izvēlēts binārais ieraksta veids. Sakarā ar to, faili, izveidotie ar funkciju nnet_save, kas nokompilēta ar dažādiem kompilatoriem, var atšķirties, t.i ne vienmēr ir iespējams pilnīgi korekti pārnest saglabāto failu no vienām operētājsistēmām uz citām
nnet_load - inicializē tneuronet tipa mainīgo un operatīvajā atmiņā izveido neironu tīkla modeli, kas ierakstīts iepriekš ar funkciju nnet_save failā ar norādīto nosukumu.
nnet_setinputs - inicializē ieeja neironus dotajā neironu tīklā ar dotā masīva elementu vērtībām. Elementu skaitam masīvā jābūt ne mazākam, kā ieejas neironu skaitam tīkla ieejas slānī.
nnet-getoutputs - dotā neironu tīkla izejas slāņa neironu stāvokļa vērtības ievieto dotajā masīvā. Masīva elementu skaitam jābūt ne mazāk par izejas slāņa neironu skaitu. Iespējamais izejas slāņa neironu stāvokļa vērtību diapazons ir atkarīgs no aktivējošās funkcijas un ir (0;1) klasiskajam sigmoidam un (-1;1) hiperboliskajam tangensam. Praktisko uzdevumu risināšanā, bieži ir vajadzība iegūt rezultātus citā diapazonā. Šādos gadījumos vajag izpildīt dotā masīvā mērogošanu, pēc funkcijas nnet_getoutputs izpildes.
nnet_forward - veic neirona stāvokļa vērtību aprēķinu dotajā neironu tīklā taisnā virzienā.
nnet_error - veic izejas slāņa neironu stāvokļa vērtību kvadrātiskās novirzes vērtības aprēķinu dotajam neironu tīklam, no vērtībām dotajā masīvā. Masīva elementu skaitam jābūt ne mazākam, kā neironu skaitam izejošajā tīkla slānī.
nnet_bp - moduļa "sirds" - funkcija, kas veic svaru vērtību un noviržu korekciju dotajā neironu tīklā, lai samazinātu novirzes neironu tīkla izejas slānī no elementu vērtībām dotajā masīvā. Masīva elementu skaitam jābūt ne mazākam, kā neironu skaitam izejošajā tīkla slānī.
nnet_train - dotā neironu tīkla apmācība pēc paraugiem, dotiem norādītajā failā. Fails ar paraugiem ir teksta fails, kurā katra rinda ir atsevišķs paraugs. Paraugs sastāv no secīgi pierakstītiem neironu ieejas slāņa stāvokļa vērtībām, atdalītām ar viena tipa atdalītājiem (piemēram atstaipe), aiz tā secīgi pierakstās vēlamās izejas slāņa neironu stāvokļa vērtības, kas arī tiek atdalītas ar viena tipa atdalītāju.
nnet_setparams - parametru uzdošana neironu tīkla apmācībai. Uzdoti tiek sekojoši parametri: maksimālais iterāciju skaits - kritērijs, pēc kura sasniegšanas tiek pārtraukta apmācība; kļūdas slieksnis - minimālā neironu tīkla kļūdas vērtība, kuru sasniedzot tiek pārtraukta apmācība; periods - iterāciju skaits, pēc kuriem tiek iegaumēts neirona tīkla svaru un noviržu stāvoklis automātiskai soļa garuma noteikšanai; minimālā un maksimālā soļa garuma vērtība (jābūt vienādiem, apmācot ar fiksētu soļa garumu). Automātiskā režīma soļa vadība notiek ar parametra "periods" palīdzību. Uzstādot šo parametru vienādu ar 0, tiek atslēgts automātiskais soļa garuma izvēles režīms. Uzstādītie parametri tiek saglabāti līdz moduļa "nnet" darba beigām. Startējot moduli no jauna ir spēkā “pēc noklusēšanai” uzstadītie parametri.
nnet_export - funkcija, kas veic pilnu informācijas saglabāšanu par doto neironu tīklu failā ar doto nosaukumu (līdzīgs nnet_save). Atšķirībā no nnet_save tiek izmantots teksta formāts. Strādā lēnāk nekā nnet_save, bet nodrošina saglabāto failu pārnešanu uz dažādām platformām un to konvertācijas iespējas citos formātos (pateicoties vienkāršai faila struktūrai).
nnet_import - nodrošina failu lasīšanu, kas ierakstīti agrāk ar funkciju nnet_export. Strādā līdzīgi funkcijai nnet_load.
Bez tam, modulis izmanto vairākas iekšējās funkcijas:
activ - uzdotās aktivējošās funkcijas vērtības izskaitļošana;
deriv - uzdotās aktivējošās funkcijas atvasinājuma izskaitļošana;
rnd - pseidogadījumskaitļa iegūšana. Tiek izmantots sākumā inicializējot svaru un nobīdes vērtības.
Apraksta faila “nnet.h” izejas teksts dots Pielikumā Nr.1, moduļa “nnet.c” pilns izejas teksts - Pielikumā Nr.2.

2.2.2.Lietotāja interfeiss


Kā jau tika minēts iepriekš, modulis "nnet.c" satur tikai funkciju komplektu manipulācijai ar neironu tīkliem ar programmētāja interfeisu. Moduļa pamatfunkciju demonstrēšanai tika uzrakstīta programma "nnetemu", kas satur lietotājam draudzīgu interfeisu, lai varētu darboties ar moduļa funkcijām.
Programma "nnetemu" ir uzrakstīta C valodā un satur kompilācijas noteikumu direktīvas, lai strādātu ar kompilatoriem Watcom C un Borland C/C++. Sakarā ar to, pārnesot programmu no vienas platformas uz citu, ir jāveic nebūtiskas izmaiņas programmas pamatkodā. Moduļa "nnet.c" pieslēgšana notiek ar direktīvas #include palīdzību.
Startējot programmu, uz ekrāna parādās pamatizvēlne. Vēlamā punkta izvēle notiek nospiežot atbilstošo ciparu taustiņu.
Pamatizvēlnē ir sekojošas opcijas:
New - operatīvajā atmiņā izveidot jaunu neirona tīkla modeli, vai aizvietot jau eksistējošu. Izvēloties šo punktu, programma no lietotāja secīgi pieprasīs neirona tīkla slāņu skaitu (ieskaitot ieejas un izejas), neironu skaitu katrā slāni (ieejas slānim ir numurs 0) un aktivējošās funkcijas veidu visiem tīkla neironiem (klasiskais sigmoīds vai hiperboliskais tangenss). Korektas operācijas izpildes rezultātā uz ekrāna parādīsies uzraksts "OK", bet kļūdas gadījumā (piemēram, nepietiekošs operatīvās atmiņas daudzums operācijas veikšanai), parādīsies paziņojums par kļūdu. Pēc jebkura taustiņa nospiešanas tiks izsaukta pamatizvēlne.
Save - saglabā informāciju par tīklu binārā failā. Izvēloties šo punktu, programma pieprasīs lietotājam ievadīt faila nosaukumu ierakstam. Veiksmīgas operācijas rezultātā parādīsies uzraksts "OK", bet kļūdas gadījumā tiks izvadīts paziņojums par kļūdu. Ierakstot jau eksistējošā failā, ieraksta operācija tiks izpildīta bez brīdinājuma par veco datu pazaudēšanu failā. Jebkura taustiņa nospiešana atgriež lietotāju pamatizvēlnē.
Load - operatīvajā atmiņā izveido jaunu (vai aizvieto veco) neirona tīkla modeli, ar parametriem, kas iepriekš tika saglabāti failā ar "Save" palīdzību. Izvēloties punktu "Load", lietotājam tiks piedāvāts ievadīt faila nosaukumu lasīšanai no diska. Veiksmīgas operācijas izpildes rezultātā parādīsies uzraksts "OK", bet kļūdas gadījumā tiks izvadīts paziņojums par kļūdu. Jebkura taustiņa nospiešana atgriež lietotāju pamatizvēlnē.
Learn - operatīvajā atmiņā esošā neirona tīkla modeļa apmācība paraugu atpazīšanai, kas ierakstīti paraugu failā. Izvēloties doto punktu, lietotājam jāievada faila vārds, kas satur paraugus. Paraugu faila pimērs dots pielikumā Nr.4. Kad apmācības process tiks pabeigts, uz ekrāna tiks izvadīts paziņojums par neironu tīkla apmācības apstāšanas iemesliem (piemēram, pārsniegts maksimālais iterāciju skaits vai ir sasniegts dotais kļūdas slieksnis). Jebkura taustiņa nospiešana atgriež lietotāju pamatizvēlnē.
Process data - šis punkts paredzēts tīkla testēšanai. Izvēloties šo punktu, lietotājam tiks secīgi pieprasīti visas neironu ieejas slāņa stāvokļa vērtības neironu tīklā, secīgi tiks izvadītas visu izejas slāņa neironu stāvokļu vērtības. Jebkura taustiņa nospiešana atgriež lietotāju pamatizvēlnē.
Set Learn Parameters - tīklas apmācības parametru uzdošana. Tiek izmantots pēc nepieciešamības, jo parametri, kas uzdoti "pēc noklusēšanas", ir diezgan universāli. Apmācības parametru saraksts un to nozīme ir aprakstīti iepriekšējā nodaļā. Jebkura taustiņa nospiešana pēc operācijas pabeigšanas atgriež lietotāju pamatizvēlnē.
Export - eksportē informāciju par tīklu teksta failā, kas nodrošina pārnešanu uz citām platformām. Izvēloties šo punktu, programma pieprasīs lietotājam faila nosukumu eksportam. Veiksmīgas operācijas izpildes rezultātā parādīsies uzraksts "OK", bet kļūdas gadījumā tiks izvadīts paziņojums par kļūdu. Eksportējot datus jau eksistējošā failā operācija tiks veikta bez brīdinājuma par veco datu pazaudēšanu. Jebkura taustiņa nospiešana atgriež lietotāju pamatizvēlnē.
Import - izveido operatīvajā atmiņā jaunu (vai aizvieto veco) neirona tīkla modeli, ar parametriem, kas iepriekš tika saglabāti failā ar "Export" palīdzību. Izvēloties punktu "Import", lietotājam tiks piedāvāts ievadīt faila nosaukumu. Veiksmīgas operācijas izpildes rezultātā parādīsies uzraksts "OK", bet kļūdas gadījumā tiks izvadīts paziņojums par kļūdu. Jebkura taustiņa nospiešana atgriež lietotāju pamatizvēlnē.
Exit - vadības atgriežšana operētājsistēmai.

2.2.3.Moduļa "nnet.c" programmēšanas interfeisa apraksts

Vairākumam modulī aprakstīto funkciju, viens no parametriem ir norāde uz neirona tīkla modeli, kurā notiek darbība, ar struktūras rādītāja "tneuronet" tipa palīdzību, kas ir aprakstīts failā "nnet.h". Programmētājam no "tneuronet" tipa struktūras ir pieejami daži lauki, kas satur vērtīgu informāciju par tīkla struktūru:
unsigned     (tneuronet).layers
- neironu tīkla slāņu daudzums (ieskaitot ieejas un izejas). Neinicializētam tīklam šī lauka vērtība ir vienāda ar 0.    
int               (tneuronet).type
- aktivējošās funkcijas tips. Var būt SIGMOID (klasiskajam sigmoidam) vai TANH (hiperboliskajam tangensam) vērtības, noteiktas "nnet.h"
unsigned          (tneuronet).neurons[]
- MAXLAYERS (maksimālais slāņu skaits tīklā, noteikts "nnet.h") garuma masīvs, kura katrs elements satur atbilstošā slāņa neironu daudzumu. Elementi, kuru numuri ir lielāki vai vienādi par (tneuronet).layers netiek izmantoti.  
Pārējie "tneuronet" tipa struktūras lauki ir:
·atmiņas apgabalu rādītāju masīvs, kur slānis pēc slāņa glabā tīkla neironu stāvokli;
·rādītāju rādītāju masīvs, kas norāda uz atmiņas apgabaliem, kas satur sakaru un nobīžu svarus;
·atmiņas apgabalu rādītāju masīvs, kas satur pagaidus mainīgos, kas paredzēti starprezultātu glabāšanai tīkla apmācības gadījumā.
Šo lauku vērtības formējas dažādu moduļa "nnet.c" funkciju darba gaitā un nav interesantas programētājam.
Parametru apraksts, kas tiek nodoti moduļa funkcijām un to atgriežamās vērtības dotas tabulā 2.1.
2.1. Tabula
Funkcija
Nododamais parametrs
Atgrieztā vērtība

tips
apraksts
tips
apraksts
nnet_free
tneuronet*
norāde uz tīkla modeli atmiņā
int
OK
nnet_init
tneuronet*
norāde uz tīkla modeli atmiņā
int
pie kļūdaini ievadītiem parametriem vai pie nepietiekoša operatīvās atmiņas daudzuma - ERROR

int
aktivējošās funkcijas veids: SIGMOID vai TANH

pie veiksmīgi pabeigtas operācijas - OK

unsigned int
slāņu skaits tīklā (ieskaitot ieejas un izejas)



unsigned int
tālāk secīgi neironu daudzumu katrā slānī


nnet_save
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja nav tīkla ierakstam vai ja nevar ierakstīt failā - ERROR

char*
faila nosaukums ierakstam

pie veiksmīgi pabeigtas operācijas - OK
nnet_load
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja nav faila, neatbilst struktūra, lasīšanas kļūda, atmiņas nepietiekamība - ERROR

char*
faila nosukums lasīšanai

pie veiksmīgi pabeigtas operācijas - OK
nnet_setinputs
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja tīkla nav atmiņā - ERROR

float*
ieejošā slāņa neirona stāvokļu masīvs

pie veiksmīgi pabeigtas operācijas - OK
nnet_getoutputs
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja tīkla nav atmiņā - ERROR

float*
masīvs, kurā ievietos izejas slāņa neironu stāvokļi

pie veiksmīgi pabeigtas operācijas - OK
nnet_forward
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja tīkla nav atmiņā - ERROR




pie veiksmīgi pabeigtas operācijas - OK
nnet_error
tneuronet*
norāde uz tīkla modeli atmiņā
float
kļūdas vērtība

float*
masīvs ar izejas vērtību paraugiem


nnet_bp
tneuronet*
norāde uz tīkla modeli atmiņā
int
OK

float*
masīvs ar izejas vērtību paraugiem



float
apmācības solis


nnet_setparams
unsigned long
periods
int
OK

unsigned long
maksimālais iterāciju skaits



float
kļūdas slieksnis



float
apmācības soļa minimālais lielums



float
apmācības soļa maksimālais lielums


nnet_train
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja nav tīkla, kļūdas operācijās ar failiem, paraugu faila neatbilstība tīkla struktūrai - ERROR

char*
faila nosaukums ar paraugiem

pēc apmācības pabeigšanas, ja pārsniegts maksimālais iterāciju skaits - MAXIT,




pēc apmācības pabeigšanas, ja sasniegts minimālais kļūdas slieksnis - THRESH,




pēc apmācības pabeigšanas ar automātisku soļa garuma izvēli, ja sasniegts mērķa funkcijas minimums - OK
nnet_export
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja nav tīkla ierakstam vai ja nevar ierakstīt failā - ERROR,

char*
faila nosaukums ierakstam

pie veiksmīgi pabeigtas operācijas - OK
nnet_import
tneuronet*
norāde uz tīkla modeli atmiņā
int
ja nav faila, neatbilst struktūra, lasīšanas kļūda, atmiņas nepietiekamība - ERROR

char*
faila nosaukums ierakstam

pie veiksmīgi pabeigtas operācijas - OK

3.Neironu tīklu izmantošana

3.1.Aritmētisko un loģisko operāciju izpildīšana izmantojot neironu tīklu

3.1.1.Loģiskā VAI realizācija neironu tīklā

3.1. Tabula
x1    x2
0
1
0
A
B
1
B
B

Loģiskais VAI (loģiskā saskaitīšana) ir binārā operācija, kuru var definēt ar tabulu 3.1.
No tabulas redzams, ka loģiskās saskaitīšanas operācijas ar diviem operan­diem rezultāts var pieņemt vienu no diviem iespējamajiem stāvokļiem (A vai B).
Izsakot A kā nulli, bet B - kā vieninieku, visu tēlu kopu, kuru atpazīst tīkls dotās loģiskās operācijas izpildei, var attēlot sekojošā veidā:
3.2.Tabula

Tēla Nr.
1.arguments
2.arguments
Vērtība


1
0
0
0


2
0
1
1


3
1
0
1


4
1
1
1


Acīmredzams, ka loģiskā VAI operāciju izpildošajam neironu tīklam ir jābūt diviem neironiem ieejas slānī un vienam neironam izejas slānī. Tā kā ieeju un izeju skaits pieņem vērtības diapazonā (0;1), tad "visērtākā" pārraides funkcija ir klasiskais sigmoīds.
1. Eksperiments
Šajā un turpmākajos eksperimentos tīkla darba modelēšanai tika izmantots personālais dators ar procesoru Intel 486 ar takts frekvenci 120 MHz un ar operacionālo sistēmu Windows 95 (DOS mode) izmantojot diska kešu "SMARTdrive" (ver.5.0).
Pirmā eksperimenta uzdevums ‑ izveidot un apmācīt divlīmeņu neironu tīklu ar diviem neironiem ieejas slānī un klasisko sigmoīdu kā aktivācijas funkciju. Apmācība tika veikta ar tēliem saskaņā ar 3.2.tab. Tīkla apmācības process aizņēma 20 sec pie dotā kļūdas sliekšņa 0,000001. Tika sasniegti sekojoši rezultāti:
3.3.Tabula

1.ieeja
2.ieeja
izeja


0.000000
0.000000
0.001534


0.000000
1.000000
0.999032


1.000000
0.000000
0.999031


1.000000
1.000000
1.000000


Kā redzams no tabulām 3.2. un 3.3., tīkla kļūda atpazīstot tēlus, ar kuriem tas tika apmācīts, nepārsniedz 0,001534 pēc absolūtā lieluma, kas sastāda ne vairāk kā 0,16% no vērtību diapazona. Tāds rezultāts ir derīgs vairākuma praktisko uzdevumu atrisināšanā izpildot operāciju loģiskais VAI.

3.1.2.Loģiskā UN realizācija neironu tīklā

3.4. Tabula
x1    x2
0
1
0
A
A
1
A
B

Loģiskais UN (loģiskā reizināšana) ir bināra operācija, kuru var definēt ar tabulu 3.4.
Kā iepriekšējā gadījumā, loģiskās reizināšanas operācijas ar diviem argu­mentiem rezultāts var pieņemt vienu no divām iespējamām vērtībām (A vai B).
Izsakot A kā nulli, bet B - kā vieninieku, visu tēlu kopu, kuru atpazīst tīkls dotās loģiskās operācijas izpildei, var attēlot sekojošā veidā:

3.5.Tabula

Tēla Nr.
1.arguments
2.arguments
Vērtība


1
0
0
0


2
0
1
0


3
1
0
0


4
1
1
1


Acīmredzams, ka operāciju loģiskais UN izpildošajam neironu tīklam ir jābūt diviem neironiem ieejas slānī un vienam neironam izejas slānī. Tā kā ieeju un izeju stāvokļi pieņem vērtības no diapazona (0;1), tad kā pārraides funkcija tika izvēlēts klasiskais sigmoīds.
1.Eksperiments
Eksperimenta uzdevums - izveidot un apmācīt divslāņu neironu tīklu ar diviem neironiem ieejas slānī, vienu neironu izejas slānī un klasisko sigmoīdu kā aktivācijas funkciju, veikt loģiskās reizināšanas operāciju. Apmācība tika veikta pēc 3.5.tab. dotajiem tēliem, ar doto kļūdas slieksni 0,000001.
Tīkla apmācība tika veikta 17 sec laikā un tika iegūti sekojoši rezultāti:
3.6.Tabula

1.ieeja
2.ieeja
izeja


0.000000
0.000000
0.000000


0.000000
1.000000
0.001116


1.000000
0.000000
0.001118


1.000000
1.000000
0.998686


Tīkla maksimālā kļūda, apstrādājot datus, pēc absolūtā lieluma sastādīja 0,001314, jeb ne vairāk kā 0,14% no ieejas vērtību diapazona. Tāds rezultāts ir derīgs praktisku uzdevuma atrisināšanai izpildot loģiskās reizināšanas operāciju.

3.1.3.Izslēdzošā VAI izpilde neironu tīklā

Izslēdzošā VAI operācijas definīcija, kā arī daži jautājumi, kas saistīti ar šīs operācijas izpildi neironu tīklā, tika apskatīti 1.daļā.
Tēlu kopu, kurus atpazīst tīkls izpildot šo loģisko operāciju, var izteikt sekojoši:
3.7.Tabula

Tēla Nr.
1.arguments
2.arguments
Vērtība


1
0
0
0


2
0
1
1


3
1
0
1


4
1
1
0


Acīmredzams, ka izslēdzošo VAI izpildošajam neironu tīklam, ir jābūt diviem neironiem ieejas slānī un vienam neironam izejas slānī. Kā iepriekšējos eksperimentos, par pārraidošo funkciju tika izvēlēts klasiskais sigmoīds. Sakarā ar to, ka divslāņu neironu tīkls nevar atrisināt izslēdzošā VAI operācijas izpildes problēmu, tika izmantoti trīsslāņu neironu tīkli ar dažādu neironu skaitu slēptajā slānī. Kā apmācības tēli tika izmantoti dati no 3.7.tab. Eksperimentu rezultāti apmācot neironu tīklu, pie uzdotā kļūdas sliekšņa 0,000001, doti 3.8.tab.
3.8.Tabula
Eksperimenta Nr.
Neironu skaits slēptajā slānī
Apmācības laiks, sec
Maksimālā kļūda, % no izejas vērtības diapazona
1
2
17
0,1208
2
3
18
0,1329
3
4
18
0,1273
4
5
18
0,1079

Kā redzams no tabulas datiem, vislabākie rezultāti tika sasniegti 4. un  1.eksperimentā. Ievērojot apmācības laiku un datora operatīvās atmiņas apjomu, kurš nepieciešams tīkla parametru glabāšanai (vienkārši aprēķini rāda, ka pirmajā eksperimentā tīkls izmanto 9 iestādāmos parametrus, bet tīkls 4.eksperimentā ‑ 21), uzvarētājs ir 1.eksperimentā izmantotais tīkls, t.i., trīsslāņu tīkls ar diviem neironiem starpslānī.

3.1.4.Skaitļu saskaitīšanas operācijas realizācija binārajā skaitīšanas sistēmā neironu tīklā

Divu bināro divciparu skaitļu saskaitīšanas operāciju var uzdot sekojošas tabulas veidā:
3.9.Tabula

Tēla Nr.
1.saskaitāmais
2.saskaitāmais
Rezultāts


1
00
00
000


2
00
01
001


3
00
10
010


4
00
11
011


5
01
00
001


6
01
01
010


7
01
10
011


8
01
11
100


9
10
00
010


10
10
01
011


11
10
10
100


12
10
11
101


13
11
00
011


14
11
01
100


15
11
10
101


16
11
11
110


No tabulas redzams, ka tādu operāciju izpildošam neironu tīklam ir jābūt četriem neironiem ieejas slānī un trijiem neironiem izejas slānī. Tā kā ieejas un izejas stāvokļi pieņem vērtības no diapazona (0;1), tad kā pārraides funkciju var izmantot klasisko sigmoīdu.
1.Eksperiments. Eksperimenta uzdevums - izveidot un apmācīt divslāņu neironu tīklu ar četriem neironiem ieejas slānī, trijiem neironiem izejas slānī un klasisko sigmoīdu kā aktivācijas funkciju, veikt divu bināro skaitļu saskaitīšanu. Apmācība tika veikta ar 3.9.tab. dotajiem tēliem, ar kļūdas slieksni 0,000001. Apmācība tika pabeigta pēc 100 000 iterācijām. Maksimālā kļūda tēliem, ar kuriem tika veikta apmācība, sastādīja 0,724490, t.i., tāda tīkla struktūra nav derīga bināro skaitļu saskaitīšanai.
Pēc tam tika veikta eksperimentu sērija, izveidojot un apmācot trīsslāņu neironu tīklus ar četriem neironiem ieejas slānī, trijiem neironiem izejas slānī un klasisko sigmoīdu kā aktivācijas funkciju, ar dažādu neironu skaitu starpslānī. Eksperimentu sērijas rezultāti doti 3.10.tab.
3.10.Tabula
Eksperimenta Nr.
Neironu skaits slēptajā slānī
Apmācības laiks, sec
Maksimālā kļūda
2
4
1 240
0,002690
3
5
103
0,001700
4
6
143
0,001937

Kā redzams, vislabākie rezultāti tika sasniegti izmantojot tīkla struktūru, kurā bija 5 neironi starpslānī.
5.Eksperiments. Šajā eksperimentā tika apmācīts neironu tīkls ar četriem neironiem ieejas slānī, pieciem neironiem slēptajā slānī, trijiem neironiem izejas slānī un klasisko sigmoīdu kā aktivācijas funkciju, ar tēliem no nepilnīgas 3.10.tab.: apmācot tīklu ieejā tika padoti visi tēli, izņemot 10.  Testēšanas rezultāti doti 3.11.tab.
3.11.Tabula
1.ieeja
2.ieeja
3.ieeja
4.ieeja
1.izeja
2.izeja
3.izeja
0
0
0
0
0.000034
0.000288
0.000436
0
0
0
1
0.000014
0.000061
0.999550
0
0
1
0
0.000418
0.999593
0.000388
0
0
1
1
0.000532
0.999222
0.999964
0
1
0
0
0.000014
0.000059
0.999596
0
1
0
1
0.000290
0.999617
0.000387
0
1
1
0
0.000219
0.999733
0.999973
0
1
1
1
0.999381
0.000588
0.000133
1
0
0
0
0.000420
0.999561
0.000430
1
0
0
1
0.003412
0.998183
0.998685
1
0
1
0
0.999405
0.000526
0.000024
1
0
1
1
0.999323
0.001019
0.999203
1
1
0
0
0.000757
0.999573
0.999492
1
1
0
1
0.999761
0.000988
0.000007
1
1
1
0
0.999307
0.000947
0.999287
1
1
1
1
0.999848
0.998337
0.001280

No tabulas redzams, ka tīkls apmācījās ne tikai pareizi atpazīt apmācībā izmantotos tēlus, bet arī tēlu, kurš ir izveidots pēc tiem pašiem noteikumiem, bet kurš netika uzrādīts apmācības procesā.

3.1.5.Aritmētiskās saskaitīšanas operācijas realizācija neironu tīklā

Šajā un turpmākajās sadaļās kā tēli, apmācot neironu tīklu izpildīt matemātiskās operācijas un aprēķināt trigonometriskās funkcijas, izmantoti piemēri, kuros atbilstošās darbības rezultāts atrodas diapazonā (-1;1). Tas nepieciešams izejas datu pārveidošanas procesa izslēgšanai, kas savukārt samazina eksperimentu veikšanai nepieciešamo laiku.
Apmācot tīklu divu skaitļu aritmētiskai saskaitīšanai tika izmantota tēlu kopa, kura sastāv no 331 elementa (divu skaitļu no ‑1 līdz 1 ar soli 0,1 visu iespējamo kombināciju summa).
1.Eksperiments, izveidojot un apmācot divslāņu neironu tīklu ar diviem neironiem ieejas slānī, vienu neironu izejas slānī un hiperbolisko tangensu kā aktivācijas funkciju, tika pabeigts pēc 105 iterāciju izpildes pēc 5 285 sec, tā arī nesasniedzot uzdoto kļūdas slieksni 0,0001. Maksimālā tīkla kļūda, ar tēliem, kurus tīkls apguva, pēc apmācības pārsniedza 0,12 pēc absolūtās vērtības, kas tīklu dara nederīgu praktiskai izmantošanai.
Tālāk tika veikta eksperimentu sērija apmācot trīsslāņu tīklus. Eksperimentu sērijas rezultāti doti 3.12.tab.
3.12.Tabula
Eksperimenta Nr.
Neironu skaits slēptajā slānī
Apmācības laiks, sec
Maksimālā kļūda
2
2
635
0,12
3
3
235
0,04
4
4
159
0,03
5
5
95
0,03
6
6
142
0,03
7
7
222
0,03

Kā redzams no tabulas datiem, sākot ar 3.eksperimentu tīkls apmācās sekmīgi (tiek sasniegts uzdotais kļūdas līmenis). Rezultējošā maksimālā kļūda piemēriem, ar kuriem tika veikta apmācība, sastāda ne vairāk kā 0,03 pēc absolūtā lieluma, t.i., noapaļojot rezultātu līdz 0,1, iegūstam simtprocentīgu tēlu. Vismazākais laiks bija vajadzīgs tīklam ar 5 neironiem slēptajā slānī, tāpēc eksperimentu turpināšanai, apmācot tīklu aritmētiskajai saskaitīšanai, tika izvēlēta tiešī šī arhitektūra.
Sekojošā eksperimentu sērija bija veltīta tīkla aprēķinu precizitātes palielināšanai. Šim nolūkam eksperimentu virknē pakāpeniski tika samazināts kļūdas slieksnis. Vislabākais rezultāts tika sasniegts pie kļūdas sliekšņa 0,000012 laikā 8 338 sec. Šeit maksimālā kļūda tēliem, ar kuriem tika veikta apmācība, sastādīja 0,012105.
Eksperimentu sērijas noslēgumā tika veikta apmācītā neironu tīkla testēšana ar desmit tēliem, brīvi vienmērīgi izvēlētiem no diapazona (‑1;1), bet tādiem, kuru nebija tēlu sarakstā apmācot tīklu. Maksimālā neironu tīkla kļūda dotajiem tēliem nepārsniedza 0,0035, t.i., neironu tīkls bija apmācīts divu skaitļu saskaitīšanai ar precizitāti, pietiekamu daudzu praktisko uzdevumu risināšanai.

3.2.Pasta indeksa ciparu atpazīšana

Kā zināms, uz bijušā PSRS pasta aploksnēm bija lauks ar masku no sešām zīmesvietām pasta indeksa pierakstam. Katra zīmesvieta sastāvēja no deviņiem tukšiem segmentiem, kurus aizkrāsojot pēc noteiktiem noteikumiem (3.1.zīm.), tika sastādīti indeksa cipari.
3.1.zīm.
Tēlu kopa atpazīšanai sastāv no desmit elementiem (cipari no 0 līdz 9).  Tēlu atpazīšanai kā ieejas ērti izmantot zīmesvietas segmentu stāvokļu bināro vektoru: neaizkrāsots segments atbilst 0, aizkrāsots - 1. Tīkla izeja formē bināro vektoru, kurš sastāv no 10 elementiem. Tīkls aktivizē vienu vektora elementu, kurš atbilst atpazītajam ciparam (stāvoklis 1). Visiem pārējiem elementiem jābūt nobremzētā stāvoklī (0). Kā pārraides funkcija tika izvēlēts klasiskais sigmoīds.
1.Eksperiments. Divslāņu neironu tīkla apmācība ar deviņiem neironiem ieejas slānī un desmit neironiem izejas slānī. Apmācība tika veikta 87 sec laikā pie uzdotā kļūdas sliekšņa 0,000001.
Kā iepriekšējos piemēros, neironu tīkla modelēšanai, kurš paredzēts indeksa ciparu atpazīšanai, tika izmantots modulis "nnet.c". Tieši šim uzdevumam tika uzrakstīta programma "cover", kura satur lietotāja interfeisu mijiedarbībai ar indeksa ciparu atpazīšanai apmācītu tīklu. Programmā "cover" cipars skaitās atpazīts tad, kad tam atbilstošā tīkla izeja ir aktivizēta (1 ‑0,01), bet visi pārējie nobremzēti (0 +0,01).
Dotā eksperimenta rezultātā, visi cipari, kuri tika izmantoti kā tēli apmācībai, tika atpazīti pilnīgi pareizi.
2.Eksperiments. Šī eksperimenta mērķis bija tēlu skaita palielināšana un tādas pat struktūras tīkla apmācība, kā pirmajā eksperimentā. Tēlu skaita paplašināšana ir nepieciešama, ja cipars tiek ierakstīts zīmesvietā, nepilnīgi ievērojot tā uzrakstīšanas noteikumiem.
Saraksts tika papildināts ar 17 jauniem tēliem, kuriem, pēc autora domām, jāaptver visi iespējamie ciparu uzrakstīšanas varianti deviņu segmentu tīklā. Teksts datnei ar tēliem dots 4.Pielikumā.
Tīkls tika apmācīts 233 sec laikā, testa laikā ar programmu "cover" tīkls nepielaida nevienu kļūdu ar tēliem, ar kādiem tas tika apmācīts.

3.3.Trigonometrisko funkciju vērtību aprēķināšana izmantojot neironu tīklu

Ir pierādīts [12], ka kāda lai arī nebūtu aktivācijas funkcija, jebkurai nepārtrauktai funkcijai var izveidot tādu neironu tīklu, kurš aprēķinās šo funkciju ar jebkuru uzdoto precizitāti. Balstoties uz šo apgalvojumu, tika pārbaudīts, cik vienkāršam ir jābūt tīklam, lai iemācītos aproksimēt trigonometriskās funkcijas ar pietiekamu precizitāti (piemēram, koordināšu aprēķinam trīsdimensiju grafikā).
Tika veikta eksperimentu sērija apmācot dažādas arhitektūras trīsslāņu tīklus sinusa viena perioda vērtību aprēķiniem. Apmācāmie tēli bija argumenta vērtību kopa diapazonā (‑p;p) ar soli apmēram 0,018 rad (kas atbilst 1o), un tām atbilstošās sinusa vērtības. Tā kā sinusa vērtības atrodas diapazonā (‑1;1), tad kā pārraides funkcija tika izvēlēts hiperboliskais tangenss. Eksperimentu rezultāti doti 3.13.tab.
3.13.Tabula
Eksperimenta Nr.
Neironu skaits slēptajā slānī
Apmācības laiks, sec
Maksimālā kļūda
1
2
396
0.862235
2
3
489
0.566377
3
4
458
0.194122
4
5
452
0.191337
5
6
531
0.184956
6
7
842
0.176141
7
8
630
0.137462
8
9
961
0.038715
9
10
642
0.143277
10
11
656
0.224276
11
12
706
0.205744
12
13
760
0.140954
13
14
821
0.215831

Kā redzams, vismazākā kļūda bija 8.eksperimentā. Maksimālā tīkla kļūda tēlu kopā, ar kuru tika veikta apmācība šajā eksperimentā, sastādīja 0,038715. Sinusa funkcijas grafiks salīdzinot ar tā aproksimāciju, ko veica trīsslāņu neironu tīkls ar deviņiem neironiem slēptā tīklā, dots 3.1.zīm. Grafiks ir uzzīmēts izmantojot 3 612 punktus, no kuriem mazāk par 1% sakrita ar tiem, kuri tika izmantoti tīkla apmācībai, t.i., neironu tīkls tikai ar 9 neironiem slēptajā slānī, apmācījās pietiekami vienmērīgi un precīzi aproksimēt sinusa vienu periodu.
3.2.zīm.

3.4.Neironu tīkla apmācīšana prognozēt trigonometrisko funkciju sekojošās vērtības pēc uzdotajām iepriekšējām vērtībām

Dotā uzdevuma jēga - apmācīt neironu tīklu ar piemēriem, kuri sastāv no trigonometriskās funkcijas vērtību secības (tā saucamā "loga"), prognozēt dotās funkcijas nākošo vērtību.
Risinot doto uzdevumu, tika veikta eksperimentu sērija apmācot trīsslāņu neironu tīklu, ar deviņiem neironiem starpslānī un hiperbolisko tangensu kā pārraides funkciju, prognozēt nākošo sinusa vērtību pie dotā iepriekšējo vērtību loga. Eksperimenti tika veikti dažādam loga platumam (elementu skaitam). Loga elementi tika izvēlēti sinusa vienā pusperiodā, tā raksturīgo punktu tuvumā () ar soli apmēram 0,087 rad (5o). Acīmredzams, ka ieejas slāņa neironu skaits atbilst loga platumam.
Pavisam tika veikti 25 eksperimenti ar loga platumu 5, 10, 15, 9 un 18. Vislabākie rezultāti tika sasniegti pie loga platuma 9. Pie tādas neironu tīkla struktūras, maksimālā tīkla kļūda ar tēliem, ar kādiem tīkls tika apmācīts, bija datora kļūdas robežās, bet maksimālā kļūda prognozējot nākošo vērtību, sekojošu aiz loga, sastādīja 9,5% no sinusa vērtības dotajā punktā (). Pārējos testētajos punktos prognozes precizitāte bija ne mazāka par 95,4% no sinusa vērtības testējamā punktā.

3.5.Trenda pagriešanās atpazīšanas uzdevums

Par trendu sauc sauc preces cenas virziena izmaiņu fjučersu tirgū. Ja preces cena aug, tad tādu trendu sauc par augošu, bet ja cena krītas, tad par dilstošu. Trenda pagriešanas atpazīšana (augoša nomaiņu ar dilstošu vai otrādi) agrā stadijā ļauj izvēlēties "spēles" pareizu turpmāko stratēģiju.
Izejas dati, apmācot neironu tīklu atpazīt trenda pagriešanos, bija vācu markas kursa vērtības izmaiņas attiecībā pret ASV dolāru tirdzniecības sesijas katrās 5 minūtēs laikā no 1999.gada 26.februāra līdz 9.aprīlim. Vērtību tabula bija sadalīta vairākos vienādos apgabalos, laikā atbilstošiem divām-trijām tirdzniecības sesijām. No katra iegūtā apgabala tika izvēlēti 18 visraksturīgākie trenda pagriešanās punkti, balstoties uz kuriem, tika izveidoti tēli neironu tīkla apmācībai. Saskaņā ar rekomendācijām (izklāstītām darbā [11]), katra ieejas datu kopa bija vēsturisko datu logs par vācu markas kursa relatīvajām izmaiņām attiecībā pret ASV dolāru, kas bija izteiktas procentos no kursa vērtības iepriekšējās 5 minūtēs. Kursa relatīvā izmaiņa tika noteikta pēc formulas:
,
(3.1)
Kur,
K(t) - kursa vērtība laika momentā t,
K(t+1) - kursa vērtība laika momentā t+1.
Izejas datu pārveidošanai nepieciešamajā formā tika izmantots Microsoft Excel.
Tīkla izejas datiem jābūt trenda izmaiņas virzienam, tāpēc tīkla izejas slānī ir jābūt diviem neironiem: pirmais aktivizējas tad, kad trends no dilstoša mainās uz augošu, otrais kļūst aktīvs tad, kad trends mainās no augoša uz dilstošu. Gadījumā, kad trends nepagriežas, izejas neironu stāvoklis ir nenoteikts.
Balstoties uz dotajiem rezultātiem [11], eksperimentiem, apmācot tīklu atpazīt trenda pagriešanos, tika izvēlēts trīsslāņu tīkls ar deviņiem neironiem starpslānī un diviem neironiem izejas slānī. Ieejas slāņa neironu skaitam jāatbilst loga platumam. Kā aktivācijas funkcija tika izvēlēts klasiskais sigmoīds.
Vislabākais rezultāts tika sasniegts pie loga platuma 16. Ar paraugiem, kuriem tīkls tika apmācīts, maksimālā tīkla kļūda sastādīja 0,000167, bet testējot ar paraugiem, kuri netika ievadīti tīklā apmācības procesā, trenda pagriešanās atpazīšanas precizitāte sastādīja 96,7% pie nosacījuma, ka trenda pagriešanās punkts aizņēma apmēram 75% loga platuma.

Nobeigums

Dotв darba izpildes procesв tika izveidota universвla programma, kura пauj вtri izveidot daювdu konfigurвciju neironu tоklus un apmвcоt tos pзc kпыdas atgriezeniskвs izplatорanвs algoritma.
Izveidotв programma uzrakstоta valodas C standartв ANSI, tвpзc tв ir pвrnesama starp daювdвm datoru platformвm izejas kodu veidв, kas пauj to izmantot uz daювdu klasu datoriem.
Ar dotвs programmas palоdzоbu tika izveidoti neironu tоkli un apmвcоti sekojoрu uzdevumu risinврanai:
·     Izpildоt loмiskвs operвcijas VAI, UN, izslзdzoрais VAI;
·     Saskaitоt skaitпus binвrajв skaitорanas sistзmв;
·     Veikt divu skaitпu aritmзtisko saskaitорanu;
·     Atpazоt pasta indeksa ciparus;
·     Aprзнinвt sinusa viena perioda vзrtоbas;
·     Prognozзt trigonometriskвs funkcijas vзrtоbu pie dotajвm iepriekрзjвm vзrtоbвm;
·     Atpazоt fjuиersu tirgus trenda pagrieрanos.
Pavisam darbв aprakstоta 34 eksperimentu izpiklde apmвcot neironu tоklus. Daюu eksperimentu rezultвti pвrspзja visu gaidоto, tв, piemзram, apmвcot neironu tоklu saskaitоt divus skaitпus binвrajв skaitорanas sistзmв, apmвcоts neironu tоkls deva pareizu rezultвtu ieejas skaitпu pвrim, kura nebija paraugu sarakstв, apmвcot tоklu.
Apmвcot prognozзt trigonometriskвs funkcijas vзrtоbu pзc dotajвm iepriekрзjвm vзrtоbвm (apmвcоbв tika izmantots sinuss), sliktвkais rezultвts bija ar kпыdu 9,5 %.
Trenda pagrieрanвs atpazорanas uzdevums tika atrisinвts: atpazорanas precizitвte sastвdоja 96,7 %, neironu tоkla ieejвs padodot datus par pзdзjo stundu pirms trenda pagrieрanвs.
Tвds rezultвts ir derоgs trenda uzvedоbas kontrolei praksз un var bыt par pamatu turpmвko pзtоjumu veikрanai, pielietojot neironu tоklus finansu darbоbas sfзrв.

Izmantotās literatūras saraksts

1.  W.S. McCulloch and W. Pitts, "A logical Calculus of Ideas Immanent in Nervous Activity", Bull. Mathematical Biophysics, Vol. 5, 1943, pp. 115-133.
2.  S. Brunak and B. Lautrup, Neural Networks, Computers with Intuition, World Scientific, Singapore, 1990
3.  J. Feldman, M.A. Fanty, and N.H. Goddard, "Computing with Structured Neural Networks", Computer, Vol. 21, No. 3, Mar.1988, pp. 91-103.
4.  Ф. Уоссермен, Нейрокомпьютерная техника, М., Мир, 1992.
5.  Итоги науки и техники: физические и математические модели НС, том 1, М., изд. ВИНИТИ, 1990.
6.  J. Hertz, A. Krogh, and R.G. Palmer, Introduction to the Theory of Neural Computation, Addison-Wesley, Reading, Mass., 1991.
7.  D.O. Hebb, The Organization of Behavior, John Wiley & Sons, New York, 1949.
8.  Sankar K. Pal, Sushmita Mitra, Multilayer Perceptron, Fuzzy Sets, and Classification //IEEE Transactions on Neural Networks, Vol.3, N5,1992, pp.683-696.
9.  Bernard Widrow, Michael A. Lehr, 30 Years of Adaptive NeuralNetworks: Perceptron, Madaline, and Backpropagation //Artificial Neural Networks: Concepts and Theory, IEEE Computer Society Press, 1992, pp.327-354.
10. Горбань А.Н. Обучение нейронных сетей. М.": изд. СССР-США СП "ParaGraph", 1990. 160 с.
11. Сидоркин К.В., Костюхин М.Н. Прогнозирование на основе аппарата нейронных сетей, Отчет о проделанной работе. ОГПУ, 1995.
12. Горбань А.Н. Обобщенная аппроксимационная теорема, Сибирский журнал вычислительной математики, №1, 1998.
13. Lippman R.P. An introduction to computing with neural nets // IEEE ASSP Magazine. Apr. 1987. P.4-22.
14. Копосов А.И., Щербаков И.Б., Кисленко Н.А., Кисленко О.П., Варивода Ю.В. и др., Создание аналитического обзора информационных источников по применению нейронных сетей для задач газовой технологии, Отчет по научно-исследовательской работе, ВНИИГАЗ, 1995.
15. Анил К. Джейн, Жианчанг Мао, Моиуддин К.М. Введение в искусственные нейронные сети, Открытые системы №4, 1997.

1.Pielikums

faila “nnet.h” izejas teksts



/*********************************/
/*   nnet.h by Victor Shooxt   */
/*********************************/
#define             MAXLAYERS                       3
#define             NNETID                     0x74656E4EL

#define             OK                              0
#define             MAXIT                                    1
#define             THRESH                   2
#define             ERROR                     -1

#define             SIGMOID                   1
#define             TANH                         2

#define             MAXSTRING                        256



typedef struct {
    unsigned                 layers;
    int                              type;
    unsigned                 neurons[MAXLAYERS];
    float                           *state[MAXLAYERS];
    float                           **weight[MAXLAYERS];
    float                           *sigma[MAXLAYERS];
} tneuronet;



extern int nnet_free(tneuronet*);
extern int nnet_init(tneuronet*, int, unsigned int, ...);
extern int nnet_save(tneuronet*, char*);
extern int nnet_load(tneuronet*, char*);
extern int nnet_setinputs(tneuronet*, float*);
extern int nnet_getoutputs(tneuronet*, float*);
extern int nnet_forward(tneuronet*);
extern float nnet_error(tneuronet*, float*);
extern int nnet_setparams(unsigned long, unsigned long, float, float, float);
extern int nnet_train(tneuronet*, char*);
extern int nnet_export(tneuronet*, char*);
extern int nnet_import(tneuronet*, char*);

2.Pielikums

Moduпa “nnet.c” izejas teksts


/*********************************/
/*   nnet.c by Victor Shooxt   */
/*********************************/
#include
#include
#include
#include
#include "nnet.h"



long randseed = 568731L;
unsigned long period = 150;
unsigned long maxiterations = 1E+5L;
float threshold = 0.0;
float minrate = 1E-7;
float maxrate = 1E+3;



/* activ */
float activ(tneuronet *nnet, float x)
{
    switch (nnet->type)
    {
        case SIGMOID: return 1.0 / (1.0 + exp(-x));
        case TANH:    return tanh(x);
        default:      return 0.0;
    }
}/* activ */



/* deriv */
float deriv(tneuronet *nnet, float s)
{
    switch (nnet->type)
    {
        case SIGMOID: return s * (1.0 - s);
        case TANH:    return 1.0 - s * s;
        default:      return 0.0;       
    }
}/* deriv */



/* rnd */
float rnd(void)
{
     randseed = 15625L * randseed + 22221L;
     return (float)((randseed >> 16) & 0x7FFF) / (float)(0x6FFF) - 1.0;
}/* rnd */



/* nnet_free */
int nnet_free(tneuronet *nnet)
{
    unsigned int                        i, l;

    for (l = 0; l < nnet->layers; l++)
    {
        if (l < (nnet->layers)-1)
        {
            for (i = 0; i < (nnet->neurons[l])+1; i++)
            {
                if (nnet->weight[l][i] != 0)
                {
                    free(nnet->weight[l][i]);
                    nnet->weight[l][i] = 0;
                }
            }
            if (nnet->weight[l] != 0)
            {
                free(nnet->weight[l]);
                nnet->weight[l] = 0;
            }
        }
        if (nnet->state[l] != 0)
        {
            free(nnet->state[l]);
            nnet->state[l] = 0;
        }
        if (nnet->sigma[l] != 0)
        {
            free(nnet->sigma[l]);
            nnet->sigma[l] = 0;
        }
    }

    nnet->layers = 0;

    return OK;
}/* nnet_free */



/* nnet_init */
int nnet_init(tneuronet *nnet, int type, unsigned int layers, ...)
{
    va_list                                   param;
    unsigned int                        i, j, l;
    unsigned int                        neurons[MAXLAYERS];

    if ((layers == 0) || (layers > MAXLAYERS)) return ERROR;

    va_start(param, layers);
    for (l = 0; l < layers; l++)
    {
        neurons[l] = va_arg(param, unsigned int);
        if (neurons[l] == 0) return ERROR;
    }
    va_end(param);

    nnet_free(&(*nnet));

    for (l = 0; l < layers; l++)
    {
        nnet->state[l] = (float *) calloc(neurons[l], sizeof(float));
        if (nnet->state[l] == 0) return ERROR;

        nnet->sigma[l] = (float *) calloc(neurons[l]+1, sizeof(float));
        if (nnet->sigma[l] == 0) return ERROR;

        if (l < (layers-1))
        {
            nnet->weight[l] = (float **) calloc(neurons[l]+1, sizeof(float*));
            if (nnet->weight[l] == 0) return ERROR;

            for (i = 0; i < neurons[l]+1; i++)
            {
                nnet->weight[l][i] = (float *) calloc(neurons[l+1], sizeof(float));
                if (nnet->weight[l][i] == 0) return ERROR;

                for (j = 0; j < neurons[l+1]; j++) nnet->weight[l][i][j] = rnd();
            }
        }
        nnet->neurons[l] = neurons[l];
    }

    nnet->type = type;
    nnet->layers = layers;

    return OK;
}/* nnet_init */



/* nnet_save */
int nnet_save(tneuronet *nnet, char *filename)
{
    FILE                          *fp;
    unsigned int                        i, l;
    unsigned long                    id = NNETID;

    if (nnet->layers == 0) return ERROR;

    fp = fopen(filename, "wb");
    if (fp == NULL) return ERROR;

    fwrite(&(id), sizeof(id), 1, fp);
    fwrite(&(nnet->type), sizeof(nnet->type), 1, fp);
    fwrite(&(nnet->layers), sizeof(nnet->layers), 1, fp);
    fwrite(&(nnet->neurons), sizeof(nnet->neurons[0]), nnet->layers, fp);

    for (l = 0; l < (nnet->layers)-1; l++)
    {
        for (i = 0; i < (nnet->neurons[l])+1; i++)
        {
            fwrite(nnet->weight[l][i], sizeof(nnet->weight[l][i][0]), nnet->neurons[l+1], fp);
        }
    }

    fclose(fp);
    return OK;
}/* nnet_save */



/* nnet_load */
int nnet_load(tneuronet *nnet, char *filename)
{
    FILE                          *fp;
    unsigned int                        i, l;
    unsigned int                        layers;
    unsigned long                    id;

    fp = fopen(filename, "rb");
    if (fp == NULL) return ERROR;

    nnet_free(&(*nnet));

    fread(&(id), sizeof(id), 1, fp);
    if (id != NNETID) {fclose(fp); return ERROR;}

    fread(&(nnet->type), sizeof(nnet->type), 1, fp);
    fread(&layers, sizeof(layers), 1, fp);
    if ((layers == 0) || (layers > MAXLAYERS)) {fclose(fp); return ERROR;}
    fread(&(nnet->neurons), sizeof(nnet->neurons[0]), layers, fp);

    for (l = 0; l < layers; l++)
    {
        nnet->state[l] = (float *) calloc(nnet->neurons[l], sizeof(float));
        if (nnet->state[l] == 0) {fclose(fp); return ERROR;}

        nnet->sigma[l] = (float *) calloc((nnet->neurons[l])+1, sizeof(float));
        if (nnet->sigma[l] == 0) {fclose(fp); return ERROR;}

        if (l < layers-1)
        {
            nnet->weight[l] = (float **) calloc((nnet->neurons[l])+1, sizeof(float*));
            if (nnet->weight[l] == 0) {fclose(fp); return ERROR;}
            for (i = 0; i < (nnet->neurons[l])+1; i++)
            {
                nnet->weight[l][i] = (float *) calloc(nnet->neurons[l+1], sizeof(float));
                if (nnet->weight[l][i] == 0) {fclose(fp); return ERROR;}
                fread(nnet->weight[l][i], sizeof(nnet->weight[l][i][0]), nnet->neurons[l+1], fp);
            }
        }
    }
    nnet->layers = layers;

    fclose(fp);
    return OK;
}/* nnet_load */



/* nnet_setinputs */
int nnet_setinputs(tneuronet *nnet, float *array)
{
    unsigned int                        i;

    if (nnet->layers == 0) return ERROR;

    for (i = 0; i < nnet->neurons[0]; i++)
    {
        nnet->state[0][i] = array[i];
    }

    return OK;
}/* nnet_setinputs */



/* nnet_getoutputs */
int nnet_getoutputs(tneuronet *nnet, float *array)
{
    unsigned int                        i;

    if (nnet->layers == 0) return ERROR;

    for (i = 0; i < nnet->neurons[(nnet->layers)-1]; i++)
    {
        array[i] = nnet->state[(nnet->layers)-1][i];
    }

    return OK;
}



/* nnet_forward */
int nnet_forward(tneuronet *nnet)
{
    unsigned int                        i, j, l;

    if (nnet->layers == 0) return ERROR;

    for (l = 0; l < (nnet->layers)-1; l++)
    {
        for (j = 0; j < nnet->neurons[l+1]; j++)
        {
            nnet->state[l+1][j] = nnet->weight[l][nnet->neurons[l]][j];
            for (i = 0; i < nnet->neurons[l]; i++)
            {
                nnet->state[l+1][j] += nnet->state[l][i] * nnet->weight[l][i][j];
            }
            nnet->state[l+1][j] = activ(&(*nnet), nnet->state[l+1][j]);
        }
    }

    return OK;
}/* nnet_forward */



/* nnet_error */
float nnet_error(tneuronet *nnet, float *douts)
{
    unsigned int                        i;
    float                           curerror, error;

    error = 0.0;
    for (i = 0; i < nnet->neurons[(nnet->layers)-1]; i++)
    {
        curerror = nnet->state[(nnet->layers)-1][i] - douts[i];
        error += curerror * curerror;
    }

    return error;
}/* nnet_error */



/* nnet_bp */
int nnet_bp(tneuronet *nnet, float *douts, float eta)
{
    unsigned int                        i, j, l;

    for (j = 0; j < nnet->neurons[(nnet->layers)-1]; j++)
    {
        nnet->sigma[(nnet->layers)-1][j] = (nnet->state[(nnet->layers)-1][j] - douts[j]) * deriv(&(*nnet), nnet->state[(nnet->layers)-1][j]);
    }

    for (l = (nnet->layers)-1; l > 0; l--)
    {
        for (i = 0; i < nnet->neurons[l-1]; i++)
        {
            nnet->sigma[l-1][i] = 0.0;
            for (j = 0; j < nnet->neurons[l]; j++)
            {
                nnet->sigma[l-1][i] += nnet->sigma[l][j] * nnet->weight[l-1][i][j];
            }
            nnet->sigma[l-1][i] *= deriv(&(*nnet), nnet->state[l-1][i]);
        }

        nnet->sigma[l-1][nnet->neurons[l-1]] = 0.0;
        for (j = 0; j < nnet->neurons[l]; j++)
        {
            nnet->sigma[l-1][nnet->neurons[l-1]] += nnet->sigma[l][j] * nnet->weight[l-1][nnet->neurons[l-1]][j];
        }
        nnet->sigma[l-1][nnet->neurons[l-1]] *= deriv(&(*nnet), 1.0);

        for (i = 0; i < nnet->neurons[l-1]; i++)
        {
            for (j = 0; j < nnet->neurons[l]; j++)
            {
                nnet->weight[l-1][i][j] += -eta * nnet->sigma[l][j] * nnet->state[l-1][i];
            }
        }

        for (j = 0; j < nnet->neurons[l]; j++)
        {
            nnet->weight[l-1][nnet->neurons[l-1]][j] += -eta * nnet->sigma[l][j];
        }
    }

    return OK;
}/* nnet_bp */



/* nnet_setparams */
int nnet_setparams(unsigned long p, unsigned long m, float t, float min, float max)
{
    period = p;
    maxiterations = m;
    threshold = t;
    minrate = min;
    maxrate = max;

    return OK;
}/* nnet_setparams */



/* nnet_train */
int nnet_train(tneuronet *nnet, char *filename)
{
    unsigned int                        i;
    unsigned long                    iteration;
    unsigned long                    pattern;
    FILE                          *fp;
    char                           *tmpfname;
    float                           *douts;
    float                           preverr, curerr;
    float                           eta;

    if (nnet->layers == 0) return ERROR;

    tmpfname = tmpnam(NULL);
    if (tmpfname == NULL) return ERROR;

    fp = fopen(filename, "rt");
    if (fp == NULL) return ERROR;

    douts = (float*) calloc(nnet->neurons[(nnet->layers)-1], sizeof(float));
    if (douts == 0) {fclose(fp); return ERROR;}

    if (nnet_save(&(*nnet), tmpfname) != OK)
    {
        remove(tmpfname);
        fclose(fp);
        free(douts);
        return ERROR;
    }

    preverr = 0.0;
    eta = sqrt(maxrate * minrate);
    iteration = 0;
    do
    {
        curerr = 0.0;
        pattern = 0;
        while (fscanf(fp, "%f", &(nnet->state[0][0])) != EOF)
        {
            for (i = 1; i < nnet->neurons[0]; i++)
            {
                if (fscanf(fp, "%f", &(nnet->state[0][i])) == EOF)
                {
                    remove(tmpfname);
                    fclose(fp);
                    free(douts);
                    return ERROR;
                }
            }
            for (i = 0; i < nnet->neurons[(nnet->layers)-1]; i++)
            {
                if (fscanf(fp, "%f", &(douts[i])) == EOF)
                {
                    remove(tmpfname);
                    fclose(fp);
                    free(douts);
                    return ERROR;
                }
            }

            if (nnet_forward(&(*nnet)) != OK)
            {
                remove(tmpfname);
                fclose(fp);
                free(douts);
                return ERROR;
            }
            if (nnet_bp(&(*nnet), douts, eta) != OK)
            {
                remove(tmpfname);
                fclose(fp);
                free(douts);
                return ERROR;
            }
            pattern++;
            curerr += nnet_error(&(*nnet), douts);
        }
        iteration++;
        curerr /= (float)(pattern);
        rewind(fp);

        if ((period != 0) && (iteration % period == 0))
        {
            if ((curerr < preverr) || (preverr == 0.0))
            {
                if (nnet_save(&(*nnet), tmpfname) != OK)
                {
                    remove(tmpfname);
                    fclose(fp);
                    free(douts);
                    return ERROR;
                }
                eta *= 1.1;
                preverr = curerr;
            }
            else
            {
                if (nnet_load(&(*nnet), tmpfname) != OK)
                {
                    remove(tmpfname);
                    fclose(fp);
                    free(douts);
                    return ERROR;
                }
                eta *= 0.8;
                curerr = preverr;
            }
            if (eta > maxrate) eta = maxrate;
            else if ((eta < minrate) && (threshold != 0.0)) eta = minrate;
        }
    } while ((iteration < maxiterations) && (curerr > threshold) && (eta >= minrate));

    if (curerr > preverr) nnet_load(&(*nnet), tmpfname);
    remove(tmpfname);

    fclose(fp);
    free(douts);

    if (iteration >= maxiterations) return MAXIT;
    if (curerr <= threshold) return THRESH;
    return OK;
}/* nnet_train */



/* nnet_export */
int nnet_export(tneuronet *nnet, char *filename)
{
    FILE                          *fp;
    unsigned int                        i, j, l;


    if (nnet->layers == 0) return ERROR;

    fp = fopen(filename, "wt");
    if (fp == NULL) return ERROR;

    fprintf(fp, "Activation:\n");
    if (nnet->type == SIGMOID) fprintf(fp, "Sigmoid\n");
    else fprintf(fp, "Hypertan\n");

    fprintf(fp, "Layers:\n%u\n", nnet->layers);

    fprintf(fp, "Neurons:\n");
    for (l = 0; l < nnet->layers; l++)
    {
        fprintf(fp, "%u\n", nnet->neurons[l]);
    }

    fprintf(fp, "Weights:\n");

    for (l = 0; l < (nnet->layers)-1; l++)
    {
        for (i = 0; i < nnet->neurons[l]; i++)
        {
            for (j = 0; j < nnet->neurons[l+1]; j++)
            {
                fprintf(fp, "%f\n", nnet->weight[l][i][j]);
            }
        }
    }

    fprintf(fp, "Biases:\n");

    for (l = 0; l < (nnet->layers)-1; l++)
    {
        for (j = 0; j < nnet->neurons[l+1]; j++)
        {
            fprintf(fp, "%f\n", nnet->weight[l][nnet->neurons[l]][j]);
        }
    }

    fclose(fp);
    return OK;
}/* nnet_export */



/* nnet_import */
int nnet_import(tneuronet *nnet, char *filename)
{
    FILE                          *fp;
    unsigned int                        i, j, l;
    unsigned int                        layers;
    char                           string[MAXSTRING];

    fp = fopen(filename, "rt");
    if (fp == NULL) return ERROR;

    nnet_free(&(*nnet));

    fscanf(fp, "%s", string);
    if (*string != 'A') {fclose(fp); return ERROR;}

    fscanf(fp, "%s", string);
    if (*string == 'S') nnet->type = SIGMOID;
    else if (*string == 'H') nnet->type = TANH;
    else {fclose(fp); return ERROR;}

    fscanf(fp, "%s", string);
    if (*string != 'L') {fclose(fp); return ERROR;}
    fscanf(fp, "%u", &layers);
    if ((layers == 0) || (layers > MAXLAYERS)) {fclose(fp); return ERROR;}

    fscanf(fp, "%s", string);
    if (*string != 'N') {fclose(fp); return ERROR;}
    for (l = 0; l < layers; l++) fscanf(fp, "%u", &(nnet->neurons[l]));

    fscanf(fp, "%s", string);
    if (*string != 'W') {fclose(fp); return ERROR;}

    for (l = 0; l < layers; l++)
    {
        nnet->state[l] = (float *) calloc(nnet->neurons[l], sizeof(float));
        if (nnet->state[l] == 0) {fclose(fp); return ERROR;}

        nnet->sigma[l] = (float *) calloc((nnet->neurons[l])+1, sizeof(float));
        if (nnet->sigma[l] == 0) {fclose(fp); return ERROR;}

        if (l < layers-1)
        {
            nnet->weight[l] = (float **) calloc((nnet->neurons[l])+1, sizeof(float*));
            if (nnet->weight[l] == 0) {fclose(fp); return ERROR;}
            for (i = 0; i < (nnet->neurons[l])+1; i++)
            {
                nnet->weight[l][i] = (float *) calloc(nnet->neurons[l+1], sizeof(float));
                if (nnet->weight[l][i] == 0) {fclose(fp); return ERROR;}
                if (i < nnet->neurons[l])
                {
                    for (j = 0; j < nnet->neurons[l+1]; j++) fscanf(fp, "%f", &(nnet->weight[l][i][j]));
                }
            }
        }
    }

    fscanf(fp, "%s", string);
    if (*string != 'B') {fclose(fp); return ERROR;}
   
    for (l = 0; l < layers-1; l++)
    {
        for (j = 0; j < nnet->neurons[l+1]; j++)
        {
            fscanf(fp, "%f", &(nnet->weight[l][nnet->neurons[l]][j]));
        }
    }

    nnet->layers = layers;

    fclose(fp);
    return OK;
}/* nnet_import */

3.Pielikums

Programmas “nnetemu.c” izejas teksts


/***********************************/
/* nnetemu.c by Victor Shooxt */
/***********************************/
#include          
#include          
#include          
#include           "nnet.h"


#ifdef __BORLANDC__
#define             clearscreen() clrscr()
#endif

#ifdef __WATCOMC__
#include          
#define             clearscreen() _clearscreen(0)
#endif


tneuronet                     net;



int main (){
    char               filename[16];
    char               key;
    float               input[64], output[64];
    unsigned int            layers, neurons[MAXLAYERS];
    int                              type;
    int                              retcode;
    unsigned int            i;

    unsigned long        period;
    unsigned long        maxiterations;
    float               threshold;
    float               minrate;
    float               maxrate;

    time_t                        start, stop;

    for (;;) {
        clearscreen();

        printf("* Neuronet emulator v3.0 %s *\n\n", __DATE__);
        printf(" 1. New\n");
        printf(" 2. Save\n");
        printf(" 3. Load\n");
        printf(" 4. Learn\n");
        printf(" 5. Process data\n");
        printf(" 6. Set Learn Parameters\n");
        printf(" 7. Export\n");
   printf(" 8. Import\n");
        printf("________________________\n 0. Exit\n");
        key = getch();

        clearscreen();

        switch (key) {
            case '1': printf("Number of layers (MAX=%u): ", MAXLAYERS); scanf("%u", &layers);
                      for (i = 0; (i < layers) && (i < MAXLAYERS); i++)
                      {
                          printf("Number of neurons in %u layer: ", i); scanf("%u", &neurons[i]);
                      }
                      printf("Activation function: (%u - SIGMOID, %u - TANH): ", SIGMOID, TANH);
                      scanf("%u", &type);
                      retcode = nnet_init(&net, type, layers, neurons[0], neurons[1], neurons[2], neurons[3], neurons[4]);
                      if (retcode == OK) printf("OK\n");
                      else printf("Not enough memory\n");
                      while(!kbhit());
                      break;

            case '2': printf("File name for saving: ");
                      scanf("%s", filename);
                      printf("Trying to save file %s...\n", filename);
                      retcode = nnet_save(&net, filename);
                      if (retcode == OK) printf("OK\n");
                      else printf("Error while saving occured\n");
                      while (!kbhit());
                      break;

            case '3': printf("File name for loading: ");
                      scanf("%s", filename);
                      printf("Loading file %s...\n", filename);
                      retcode = nnet_load(&net, filename);
                      if (retcode == OK) printf("OK\n");
                      else printf("Error while reading occured\n");
                      while (!kbhit());
                      break;

            case '4': printf ("File name with patterns: ");
                      scanf("%s", filename);
                      printf("Training... \n");
                      start = time(NULL);
                      retcode = nnet_train(&net, filename);
                      stop = time(NULL);
                      switch (retcode)
                      {
                          case ERROR: printf("Error while training occured\n"); break;
                          case MAXIT: printf("Maximum of iterations exceed\n"); break;
                          case THRESH: printf("Threshold achived\n"); break;
                          case OK: printf("OK\n");
                      }
                      printf ("Elapsed time is %f seconds\n", difftime(stop, start));
                      while(!kbhit());
                      break;

            case '5': if (net.layers == 0) {
                          printf("The net not found\n");
                          while (!kbhit());
                          break;
                      }
                      for (i = 0; i < net.neurons[0]; i++) {
                          printf("input %u=", i);
                          scanf("%f", &input[i]);
                      }
                      nnet_setinputs(&net, input);

                      retcode = nnet_forward(&net);
                      if (retcode == OK) {
                          nnet_getoutputs(&net, output);
                          for (i = 0; i < net.neurons[net.layers-1]; i++) {
                             printf ("output %u=%f\n", i, output[i]);
                          }
                      }

                      while (!kbhit());
                      break;
            case '6': printf("Period for auto step selection (0 - no auto): ");
                      scanf("%lu", &period);
                      printf("Maximum number of iterations: ");
                      scanf("%lu", &maxiterations);
                      printf("Error threshold: ");
                      scanf("%f", &threshold);
                      if (period == 0) {
                          printf("Learn rate: ");
                          scanf("%f", &minrate);
                          maxrate = minrate;
                      }
                      else {
                          printf("Minimum learn rate: ");
                          scanf("%f", &minrate);
                          printf("Maximum learn rate: ");
                          scanf("%f", &maxrate);
                      }
                      nnet_setparams(period, maxiterations, threshold, minrate, maxrate);
                      break;

            case '7': printf("File name for export: ");
                      scanf("%s", filename);
                      printf("Trying to export file %s...\n", filename);
                      retcode = nnet_export(&net, filename);
                      if (retcode == OK) printf("OK\n");
                      else printf("Error while exporting occured\n");
                      while (!kbhit());
                      break;

            case '8': printf("File name for import: ");
                      scanf("%s", filename);
                      printf("Importing file %s...\n", filename);
                      retcode = nnet_import(&net, filename);
                      if (retcode == OK) printf("OK\n");
                      else printf("Error while importing occured\n");
                      while (!kbhit());
                      break;

            case '0': nnet_free(&net);
                      return 0;
        }

    }
}

4.Pielikums

Fails ar paraugiem apmвcot neironu tоklu atpazоt pasta indeksa ciparus


1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1  1 0 0 0 0 0 0 0 0 0
0 0 0 0 1 0 0 0 1 1 0 0 1 0 1 0 1 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1  0 1 0 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1  0 0 1 0 0 0 0 0 0 0
1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1  0 0 0 1 0 0 0 0 0 0
1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1  0 0 0 0 1 0 0 0 0 0
1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1  0 0 0 0 0 1 0 0 0 0
1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1  0 0 0 0 0 0 1 0 0 0
1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1  0 0 0 0 0 0 0 1 0 0
1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1  0 0 0 0 0 0 0 0 1 0
1 1 1 1 1 1 0 0 0 1 1 0 0 0 1 1 1 1 1 1 0 0 0 0 1 0 0 0 0 1 1 1 1 1 1  0 0 0 0 0 0 0 0 0 1

5.Pielikums

Izejas datu paraugs uzdevumam atpazоt trenda pagrieрanas


26/02/99 13:25:00     0,5633
26/02/99 13:30:00     0,5633
26/02/99 13:35:00     0,5635
26/02/99 13:40:00     0,5633
26/02/99 13:45:00     0,5638
26/02/99 13:50:00     0,5636
26/02/99 13:55:00     0,5629
26/02/99 14:00:00     0,5629
26/02/99 14:05:00     0,5627
26/02/99 14:10:00     0,5624
26/02/99 14:15:00     0,5623
26/02/99 14:20:00     0,5626
26/02/99 14:25:00     0,5625
26/02/99 14:30:00     0,5624
26/02/99 14:35:00     0,5624
26/02/99 14:40:00     0,5622
26/02/99 14:45:00     0,5625
26/02/99 14:50:00     0,5623
26/02/99 14:55:00     0,5623
26/02/99 15:00:00     0,5621
26/02/99 15:05:00     0,5619
26/02/99 15:10:00     0,5626
26/02/99 15:15:00     0,5622
26/02/99 15:20:00     0,5614
26/02/99 15:25:00     0,5611
26/02/99 15:30:00     0,5606
26/02/99 15:35:00     0,5612
26/02/99 15:40:00     0,5610
26/02/99 15:45:00     0,5610
26/02/99 15:50:00     0,5612
26/02/99 15:55:00     0,5611
26/02/99 16:00:00     0,5615
26/02/99 16:05:00     0,5620
26/02/99 16:10:00     0,5621
26/02/99 16:15:00     0,5620
26/02/99 16:20:00     0,5620
26/02/99 16:25:00     0,5620
26/02/99 16:30:00     0,5620
26/02/99 16:35:00     0,5619
26/02/99 16:40:00     0,5622
26/02/99 16:45:00     0,5625
26/02/99 16:50:00     0,5623
26/02/99 16:55:00     0,5618
26/02/99 17:00:00     0,5624
26/02/99 17:05:00     0,5633
26/02/99 17:10:00     0,5633
26/02/99 17:15:00     0,5633
26/02/99 17:20:00     0,5631
26/02/99 17:25:00     0,5632
26/02/99 17:30:00     0,5633
26/02/99 17:35:00     0,5632
26/02/99 17:40:00     0,5631
26/02/99 17:45:00     0,5634
26/02/99 17:50:00     0,5638
26/02/99 17:55:00     0,5633
26/02/99 18:00:00     0,5637
26/02/99 18:05:00     0,5638
26/02/99 18:10:00     0,5635
26/02/99 18:15:00     0,5638
26/02/99 18:20:00     0,5638
26/02/99 18:25:00     0,5639
26/02/99 18:30:00     0,5642
26/02/99 18:35:00     0,5644
26/02/99 18:40:00     0,5642
26/02/99 18:45:00     0,5643
26/02/99 18:50:00     0,5644
26/02/99 18:55:00     0,5643
26/02/99 19:00:00     0,5641
26/02/99 19:05:00     0,5641
26/02/99 19:10:00     0,5643
26/02/99 19:15:00     0,5646
26/02/99 19:20:00     0,5645
26/02/99 19:25:00     0,5644
26/02/99 19:30:00     0,5642
26/02/99 19:35:00     0,5641
26/02/99 19:40:00     0,5641
26/02/99 19:45:00     0,5638
26/02/99 19:50:00     0,5638
26/02/99 19:55:00     0,5640
26/02/99 20:00:00     0,5638
26/02/99 20:05:00     0,5639
26/02/99 20:10:00     0,5639

Nav komentāru:

Ierakstīt komentāru