Реферати
Доклади
Курсови работи
Дипломни работи
Есета
Лекции
... и много други документи

 

 

       
Back to Referatite.com     Изтегли



Изследване на невронна мрежа за разпознаване на изображения на подписи и изграждане на база данни



Технически Университет - София

Факултет по Компютърни Системи и Управление

Дипломна работа

на тема:

Изследване на невронна мрежа за разпознаване на изображения на подписи и изграждане на база данни

Автор: Научен ръководител:

Калоян Петков доц.д-р.инж.Гочо Гочев

Ф.Н. 13014585

София - 2001

1 Въведение

Увод

Целта на тази дипломна работа е:

  • обзор на проблема за разпознаване и класификация

  • обзор на НМ с право разпространение на сигнала - FANNs(Feedforward artificial neural networks)

  • изследване на невронните мрежи с обратно разпространение на грешката - BPNNs(Backpropagation artificial neural networks) използвани за разпознаване на подписи по предварително определени характеристики

  • разработка на алгоритми и програмна реализация за симулиране работата на невронната мрежа

  • изграждане на БД за съхранение на данните свързани с използването на НМ

Невронните мрежи FANN са широко използвани като средство за решаване на задачи за разпознаване и класификация. За симулацията на НМ се приема алгоритмичен подход, защото е много подходящ за реализация като компютърна програма.

  • Въведение

    1. Същност на разпознаването и класификацията

    Разпознаването представлява процес, при който се определя, че даден обект от популация P принадлежи на клас (подпопулация) S. Разпознаването на даден обект като един уникален клас (състоящ се само от един обект) е процес на идентификация[ 1][2].

    Класификацията е процес, при който се извършва групиране на обекти в класове (подпопулации) в зависимост от тяхното сходство. Класификацията по същество е процес на обучение. Една система се обучава променяйки вътрешните си параметри, с което променя поведението си. Това е анти-ентропен процес, акумулиращ и концентриращ опит във вътрешни промени на системата.

    Задачата по разпознаване на подписи включва и двата процеса и принадлежи към областта на изкуствения интелект (ИИ). В настоящата дипломна работа се използват изкуствени невронни мрежи (ИНМ), като система извършваща класификацията (обучение) и разпознаването на подписи.

      1. Какво е ИНМ

    Изследванията върху ИНМ са мотивирани от знанията за човешкия

    мозък. Една техническа дефиниция определя мозъкът като комплексен, нелинеен, паралелен компютър за обработване на информация [3]. Той има възможността да организира своите структурни единици (неврони) така, че да извършва изчисления много по-бързо и от най-бързият цифров компютър. Това поражда идеи за създаване на ИНМ по подобие на човешкия мозък.

    Тук можем да даден дефиниция за ИНМ като адаптивна машина [3]:

    Изкуствената невронна мрежа е система с масивен и разпределен паралелизъм, изградена от прости изпълнителни единици (неврони), имащи възможността да съхраняват опитни знания и да ги използват. Подобието с човешкия мозък е в две направления:

    • Знанията се получават от околната среда чрез процес на обучение

    • Устойчивостта на междуневронните връзки, известни като синаптични тегла, се използват за съхранение на придобитите знания

    Процесът на обучение, известен като обучаващ алгоритъм, се използва за промяна на синаптичните тегла по такъв начин, че да се постигне необходимото обучение.

      1. Предимства на ИНМ

    ИНМ дължат изчислителната си мощ на масивния и разпределен паралелизъм и на възможността да се учат и обобщават. Обобщаването е възможността на ИНМ да дават отговор за входни данни, неизползвани при обучението. Това прави ИНМ подходящи за решаване на сложни проблеми като разпознаването на подписи.

    Ето някои от предимствата на ИНМ.

        1. Нелинейност

    Изкуствените неврони могат да бъдат линейни или нелинейни. Мрежа състояща се от връзки между нелинейни неврони е сама по себе си нелинейна. Нещо повече, нелинейността е специален вид чувствителност разпределена по цялата мрежа.

        1. Съпоставянето Вход-Изход (класификация)

    Процесът на класификация, известен като метод на обучение води до промяна на синаптичните тегла на ИНМ, чрез възприемане на множество от обучаващи примери. Всеки пример се състои от уникален входен сигнал и желан отговор(изход). Самото обучение става като на входа на НМ се подаде примерния сигнал и синаптичните тегла се променят така, че да се минимизира разликата между резултатния изходния сигнал на НМ и желания сигнал. Това се повтаря по много пъти за всички примери, докато се постигне обучено състояние на НМ при, което промяната на синаптичните тегла е несъществена. Така ИНМ се обучава да съпоставя входни сигнали с изходни сигнали.

        1. Адаптивност

    ИНМ имат вградена възможност да променят синаптичните си тегла в зависимост от промени в околната среда. Това позволява една обучена ИНМ да бъде преобучена, в съответствие с промени на външни за НМ условия. Съчетанието на архитектурата на ИНМ за разпознаване с тяхната адаптивност, ги правят мощно средство в за реализация на адаптираща се класификация. Като правило може да се каже, че колкото по-адаптираща е една система, толкова по-стабилна е тя.

        1. Точност на отговора

    В контекста на задачата за разпознаване, ИНМ не само определят принадлежността на един обект към даден клас, но и дават информация колко точен е техният отговор. Това може да се използва за оптимизиране на процеса по класификация.

        1. Глобалност на информация

    Знанията, се представят в ИНМ като структура и активация на невроните, които ги изграждат. Всеки неврон е потенциално повлиян от активацията на всички неврони. Следователно, глобалността (контекстуалността) на информацията е естествено свойство на ИНМ.

        1. Устойчивост от грешка

    ИНМ имат потенциал да са устойчиви към грешки.

    Това означава, че ако малка част от неврони не работят, отговорите на мрежата няма да се променят съществено. Този ефект се дължи на разпределения характер на знанията, запомнени от ИНМ.

        1. Биологична аналогия

    Както разбрахме, ИНМ се опитват да симулират структурата и работата на естествените невронни системи като човешкия мозък. Невробиолозите разглеждат ИНМ като изследователско средство за интерпретиране на биологичните невронни системи. От друга страна, инженерите гледат на невробиологията като източник на нови идеи за решаване на сложни проблеми, като разпознаването на образи.

      1. Невронът - градивна единица на НМ

    Ефективността на НМ се дължи на големия брой елементарни изпълнителни единици, известни като неврони.

    Нека разгледаме биологичен и изкуствен неврон.

        1. Биологичен неврон

    Структурата на биологична нервна клетка е дадена на фиг.1.1. Тя се състои от тяло, входни връзки - дендрити, единствена изходна връзка - аксон. Местата където нервните клетки образуват връзки се наричат синапси.

    Предаването на сигнала става като във всеки един момент от времето, клетката приема сигнали (по дендритите) от други клетки. В зависимост от тези сигнали тялото промени електрическия потенциал на мембраната си. Ако той достигне стойност над определен праг се генерира електрически импулс, който се разпространява по аксона достигайки до други клетки, с които има образувани синапси. Импулса разпространяващ се по аксона има винаги една и съща амплитуда, което прилича на двоично предаване на информация. Невробиолозите смятат, че информацията се предава посредством честотата на импулсите, т.е. чрез честотно кодиране.

        1. Изкуствен неврон

    Структурата на изкуствен неврон -фиг.1.2 е по аналогия с биологичната нервна клетка. Могат да се отличат три главни елемента в модела на изкуствения неврон:

    • Множество от връзки (синапси) всяка от които се характеризира с теглови коефициент . За разлика от биологичните синапси, тегловите коефициенти на изкуствения неврон могат да приемат положителни и отрицателни стойности.

    • Суматор, сумиращ входните сигнали претеглени(умножени) по съответните теглови коефициенти. Най-широко използвания суматорът е линейният, който е използван в настоящата дипломна работа.

    • Активираща функция имаща за цел да ограничи изходния сигнал на неврона.

    Моделът включва също и праг, означен като , който увеличава или намалява входния сигнал към активиращата функция, в зависимост от това дали е положителен или отрицателен и действа като отместване.

    Математическото описание на неврон, можем да дадем чрез следните две равенства:

    (1.1)

    и

    (1.2)

    където са входните сигнали; са синаптичните тегла на неврон ; е линеен суматор на входните сигнали; е праговата стойност; (.) е активиращата функция; е изходния сигнал на неврона. Праговата стойност се използва като отместване и представлява транслация на активиращата функция по отношение на изходната стойност на суматора , както си личи от равенството

    (1.3)

    ще наричаме активиращ входен сигнал за неврон .

    Начинът, по който отместването влияе на активиращата функция, е показано на фиг.1.3.

          1. Типове активиращи функции

    Активиращата функция означена по-горе като (), определя изхода на неврона в зависимост от активиращия входен сигнал. Тук ще посочим на използваните активиращи функция в ИНМ.

            1. Прагова функция

    За праговата функция имаме:

    ш 1 ако  " 0 ш 1 ако  " 0

    ()= ш или ()= ш 0 ако  = 0 (1.4)

    ш 0 ако  < 0 ш -1 ако  < 0

    Неврон, който използва такава функция е известен като модел на McCulloch-Pitts.

    При този модел, изходът на неврона приема стойност 1 ако сумата от претеглените входове е неотрицателна, и 0 ако сумата е отрицателна - фиг.1.4.

            1. Линейна функция

    За линейната функция имаме:

    ш 1,  " +

    ()= ш , + >  > " (1.5)

    ш -1,  " "

    Тази активираща функция може да бъде разглеждана като апроксимация на нелинеен усилвател - фиг. 1.5.

            1. Сигмоидна функция

    За сигмоидната функция имаме:

    1

    ()= _____ (1.6)

    1 + exp("a)

    Сигмоидната функция е най-често използваната активационна функция в различните организации на НМ. Тя е непрекъснато нарастваща функция, предлагаща оптимален баланс между линейно и нелинейно поведение.

    Функцията е дефинирана в интервала ("",+") и стойностите й са в отворения интервала (0, 1) - фиг. 1.6.

    Параметърът `а' определя наклона на функцията. При много голяма стойност на този параметър, функцията се превръща в прагова функция.

    Важна характеристика на тази функция е нейната диференцируемост, като производната се изразява чрез самата функция.

    Производната на функцията е:

     () = -а () ( 1 " () ) (1.8)

            1. Хиперболичен тангенс

    За хиберболичния тангенс имаме:

    (1.9)

    Има същите характеристики като сигмоидната функция с изключение на изходните стойности, които са в отворения интервал (-1, 1) - фиг. 1.7.

    Също както сигмоидната и тази функция е диференцируема и нейната производна се изразява чрез самата функция.

    Производната на функцията е:

     () = ( 1 " ) (1.10)

      1. Класификация на НМ

    Класификацията на ИНМ може да се направи по различни характеристики:

    • Характеристика на обработващия елемент

    • Топология на мрежата

    • Състояние на активация на мрежата

    • Модел на НМ

    • Обработващ алгоритъм

    • Взаимодействие с околната среда

    • Обучаващ алгоритъм

    Една примерна класификация е показана на фиг. 1.8, която е непълна, но достатъчна в контекста на настоящата дипломна работа.

    Според вида на активиращата функция на невроните се определят две групи НМ:

    • Линейни : () = A*  + B, където A и B са коефициенти. В частност изхода повтаря входния сигнал

    • Нелинейни : За активираща функция може да се избере всяка плавно ограничаваща диференцируема функция. Най често се използват:

    • сигмоидната:

    1

    ()= _____

    1 + exp(")

    • хиперболичен тангенс:

    ()= tanh()

    Начинът на свързване на невроните определя топологиите на НМ, които ще бъдат дискутирани по-нататък.

    Съществува също деление на НМ по отношение на обучаващия алгоритъм:

    • обучение с учител

    • обучение без учител

      1. Фази на работа на НМ при разпознаване

      Процесът на разпознаване с помощта на НМ се извършва на два

      основни етапа:

      • Обучение - класификация

      • Обработка на информацията - разпознаване

          1. Обучение - класификация

        Обучението е може би най-значимото свойство на НМ. Чрез обучението НМ се приспособяват към околната среда, при което подобряват своята работа.

        По-подробно обучението е разгледано в глава 1.8.

            1. Обработка на данни - разпознаване

        След като се обучи една НМ, тя може да бъде използвана за обработка на данни неизползвани при обучението. Това е фазата, в която НМ извършва полезна работа - разпознаването. Процесът протича като първо се подаде изследвания обект (неговите характеристики) на входа и след това се изчисли изхода на НМ. Полученият резултат на изхода на НМ се използва за вземане на решение по разпознаването.

          1. Архитектури на НМ

        Начинът по който са свързани невроните определят архитектурата (топологията) на НМ и е силно свързан с алгоритъма на обучение. За улеснение в повечето НМ, невроните се групират в слоеве, като неврон от един слой е свързан с всички неврони от съседните слоеве.

        Различават се три фундаментални архитектури на ИНМ.

            1. Еднослойна права НМ

        Най-простата топология на НМ е еднослойната, която има само входен и изходен слой. Входният слой получава информация от околната среда, която подлежи на обработка. Изходният слой обработва информацията достигнала до него и извежда резултата от работата на НМ към околната среда. Информацията се разпространява само в една посока(права НМ): напред - от входа към изхода. Въпреки, че има два слоя този тип НМ е наречена еднослойна защото само един слой (изходния) извършва обработка на информацията. Входния слой не се брои тъй като в него не се извършва обработка.

            1. Многослойна права НМ

        Многослойната НМ е също с право разпространение на входния сигнал и се различава от еднослойната само по наличието на скрити (междинни) слоеве. Скритите слоеве нямат връзка с околната среда и служат само за обработка.

            1. НМ с обратна връзка - рекурентна

        НМ с обратна връзка се различават от правите НМ по това, че имат поне една обратна връзка. Обратната връзка може да бъде положителна или отрицателна. Положителната обратна връзка увеличава нестабилността на НМ и прави невъзможно обучението й. Отрицателната обратна връзка стабилизира НМ и подобрява обучението.

          1. Представяне на знания в ИНМ и начини на обучение

        Изследователите в областта на ИНМ, Mendel и McClaren (1970) [3], дават следното определение за обучение:

        Обучението е процес, при който се адаптират свободните параметри на НМ, чрез процес на стимулиране от околната среда. Типът на обучение зависи от начина по, който се адаптират параметрите на ИНМ.

        Разработени са два основни начина на обучение - с учител и без учител.

        На фиг. 1.9 и фиг. 1.10 са дадени блок диаграми на обучение с учител и без учител.

        Дефиницията на процеса на обучение определя следната последователност от събития:

        • Стимулиране на НМ от околната среда;

        • Адаптация - промяна на теглата по определен алгоритъм с цел постигането на желания резултат.

        • НМ отговаря по нов начин на околната среда, вследствие от адаптацията

        Знанията (опита), придобит от околната среда, се представят (запомнят) в ИНМ чрез синаптичните тегла (свободните параметри). Начините по които се адаптират теглата определят различни алгоритми на обучение.

            1. Обучение с обратно разпространение на грешката

        Обучението с обратно разпространение на грешката е един от най-често използваните методи. Използва се за прави двуслойни или многослойни НМ. Базира се на т.нар. алгоритъм за спускане по градиента (LMS - алгоритъм).

        Същността му е следната:

        • Дефинира се сигнал на грешката:

        за изходните неврони (1.11)

        за скритите неврони (1.12)

        където d е желаната стойност на изхода за i-ти неврон, m e номерът на обучаващия вектор (образ), C е множеството на изходните неврони, а L е номерът на слоя, е градиента на грешката за неврон к.

        • Дефинира се средноквадратична грешка за един образец (MSE):

        = (1.13)

        • Дефинира се оценъчна функция или мярка усреднена грешка по всички образци:

        (1.14)

        където M е броят на обучаващите образи. В повечето случаи обаче се използва средно квадратична грешка за един образец.

        Ясно е, че колкото Е е по-малка, толкова входния образ е по-близко до желания. Стремежът е Е да клони към 0. По определение функцията E(w) дефинира в пространството на теглата повърхнини с глобален минимум в нулата. Знаейки стойността на Е ние можем да променяме така теглата, че да се стремим да се плъзгаме по повърхнината към минимума. Кратко казано, алгоритъмът за спускане по градиента се състои в променяне на теглата пропорционално на градиента в текущата точка:

        (1.15)

        където  е отново коефициента на обучение.

        Диференцирайки се получава следното уравнение:

        (1.16)

        Не трябва да се забравя, че означението е за тегло от j-ти към i-ти слой. Тук с е означен локалния градиент:

        (1.17)

        където с е означен входния сигнал на неврона (пропуснато е означението за всеки образец.

        От тези две уравнения се вижда, че теглата на даден вътрешен слой се променят в зависимост от изходния сигнал. Поради това алгоритъмът се нарича с обратно разпространение на грешката.

        На фиг. 1.11 е показан инкременталния вариант на една двуслойна права НМ. При него грешките се изчисляват и теглата се променят след подаването на всеки един образец. Възможен е вариант и на пакетно обучение с използване на средно квадратичната грешка. В първия вариант обаче обучението е по-бързо.

        Алгоритъмът на работа на НМ има следния вид:

        • а) инициализират се тегловите коефициенти между входа и скрития слой;

        • б) инициализират се тегловите коефициенти между скрития слой и изхода;

        • в) на входа на НМ се подава един входен вектор - хm за m = 1..M

        • г) изчисляват се последователно стойностите на активация и изходите на всеки неврон от вътрешния слой;

        • д) изчисляват се последователно стойностите на активация и изходите на всеки неврон от изходния слой;

        Дотук мрежата работи по основните правила. Интересен е обаче
        обучаващия алгоритъм:

        • е) изчислява се отклонението (грешката) на получения изходен вектор от желания (искания);

        • ж) изчислява се локалния градиент за изходния слой;

        • з) изчислява се локалния градиент за скрития слой;

        • и) изчислява се промяната на теглата;

        • й) теглата се променят по;

        • к) на входа на мрежата се подава следващия входен вектор;

        За край на обучението (край на подаването на входни образи) най-често се следи по стойността на средноквадратичната грешка.

            1. Обучение на Хеб

        Този метод на обучение е наречен в чест на невропсихолога

        Хеб(1949). Той прави следното заключение за начина, по който се обучават нервните клетки:

        Когато сигнала по аксона на клетка А е почти достатъчен за да възбуди клетка Б и често участва в нейното възбуждане, тогава започва нарастващ процес или метаболични промени в едната или двете клетки, които водят до нарастване на възможността клетка А да възбужда клетка Б.

        Хеб предлага тази промяна като основа на асоциативното обучение (на клетъчно ниво), която води до трайни промени в активността на пространствено разпределени групи от клетки.

        Определението на Хеб е направено в контекста на невробиологията, но в областта на ИНМ то може да изглежда като правило от две части:

        • Ако два неврона от двете страни на синапса (връзката) са активирани едновременно, то теглото на връзката се увеличава;

        • Ако два неврона от двете страни на синапса (връзката) не са активни едновременно, то теглото на връзката се намалява.

        Синапс (връзка), който изпълнява горното правило се нарича синапс на Хеб

        От горното правило можем да изведем следните четири ключови механизма характеризиращи връзката на Хеб:

        1. Време - зависим механизъм. Този механизъм отговаря за правилото, че промените във връзката зависят от времето на появяване на сигналите от двете страни на синапса.

        2. Локален механизъм. В същността си синапсите (връзките) на Хеб са трансферен елемент, в който информационните сигнали са в пространствено-времева зависимост. Тази зависимост се използва за определяне на промяната на тегловите коефициенти.

        3. Механизъм на взаимодействие. Този механизъм отразява зависимостта на синаптичните промени (промени на теглата) от сигналите от двете страни на синапса.

        4. Съединителен механизъм. Една от интерпретациите на постулата на Хеб е, че условията за промени в синапса се определят моментното съгласуването на сигналите от двете страни на синапса. Другата възможна интерпретация да разглежда синаптичните промени в статистическа форма. В частност, зависимостта на сигналите от двете страни на синапса по отношение на времето, определя промените в ефективността на връзката (промяната на теглата).

        Математическата формулировка на правилото на Хеб за k-ти неврон изглежда така:

        (1.18)

        където n е времето изразено като n-та итерацията на обучение,

        е изхода на неврона k, е претегления входен сигнал от j-тия неврон.

        Най-простата форма на обучение по правилото на Хеб е:

        (1.19)

        където  е положителна константа определяща скоростта на обучение.

            1. Състезателно обучение

        При този метод на обучение, невроните се състезават кой да бъде

        активен. Докато при НМ с обучение базирано на правилото на Хеб може да има няколко активни изходни неврони, то при НМ със състезателно обучение само един изходен неврон може да бъде активен.

        Има три основни елемента при състезателното обучение:

        • Множество от еднакви неврони, които се различават само по синаптичните тегла, поради което отговарят различно на дадено множество от входни образци

        • Наложено е ограничение на силата на всеки неврон

        • Механизъм, който се грижи да има само един активен неврон в даден момент. Невронът, който е активиран е победител.

        За да бъде неврон k победител, входният му сигнал за даден

        входен образец, трябва да бъде най-голям измежду входните сигнали на другите неврони.

        Математическата дефиниция на състезателното правило е:

        ш 1 ако :

        k(k) = ш иначе (1.20)

        ш 0

        Началната инициализация на теглата е произволна, но сумата от

        теглата на един неврон трябва да е равна на 1:

        за (1.21)

        Ако един неврон не се активира за даден входен образец, тогава не се осъществява промяна на теглата му. Ако невронът се активира, тогава теглата на входните му връзки се променят.

        Формата на обучение изглежда математически по следния начин:

        ш ako неврон k е победител

        = ш (1.22)

        ш 0 ako неврон k е губещ

          1. БД за съхранение на информацията за НМ

        Системите за управление на БД - СУБД (DBMS - Database Management System) са основна част от съвременните информационни системи. Въпреки голямото си развитие, те продължават да са област на активно проучване и развитие.

        В исторически план развитието в тази област изглежда така:

        • Предшественика на СУБД са файловите системи за съхранение на информация. Те представляват множество от програми предлагащи различни услуги на потребителите. Всяка програма дефинира и управлява свои собствени данни. Въпреки, че файловите системи са голям напредък в сравнение с ръчните системи (записване на данните ръчно върху хартиен носител), те имат значителни проблеми като повторяемостта и зависимостта на данните.

        • Подходът за централизирано съхранение на данните, с което се решават проблемите на файловите системи, води до появата на системите за управление на БД - СУБД. Самата база данни представлява съвкупност от логически свързани данни и тяхната дефиниция. СУБД като цяло представлява програмна система, която позволява на потребителите да дефинират, създават и да управляват съхранението на данните. За тази цел е изграден език за дефиниране на данни (DDL - Data Definition Language) и език за управление то им (DML - Data Manipulation Language). Системата предлага защита на данните като извършва контрол на достъпа на потребителите и техните права.

        • СУБД са базирани на файловите системи. Йерархичните и мрежовите системите представляват първата генерация на СУБД. Йерархичният модел е представен от Управляващите Информационни Системи - УИС(IMS - Information Management System), а мрежовите (CODASYL) модели са представени от системи за интегрирано съхранение на данни - СИСД(IDS - Integrated Data Store). Двата модела са разработени в средата на 60-те години. Релационният модел, представен от Код (E.F.Kodd - 1970), поставя началото на втората генерация на СУБД. Този модел оказва значителен ефект върху развитието и разпространението на информационните системи. Третата генерация на СУБД е представена от обектно-релационните и обектно-ориентираните системи.

        Изхождайки от факта, че НМ мрежа е изградена според правилата на обектно-ориентираното програмиране, то ако използваме релационна БД трябва да се реализира трансформиране на обектни данни в таблични структури. Тази трансформация не се налага ако се използва обектна организация на БД. Това определя избора на обектен тип БД за съхранение на НМ.

          1. Обобщение

        Въз основа на теоретичното изложение, за решаване задачата по разпознаване на подписи, се избира права невронна мрежа и обучаващ алгоритъм с обратно разпространение на грешката. В глава 3 се прави теоретично и експериментално изследване върху избраната ИНМ за подобряване на нейната работа.

        • Същност на НМ за разпознаване на подписи

        Изследванията в тази глава са концентрирани върху права НМ и метод

        на обучение с обратно разпространение на грешката, която занапред ще се нарича само НМ, за краткост.

          1. Общи проблеми при НМ за разпознаване и класификация

        Тук са разгледани различни проблеми на НМ с обратно разпространение на грешката, анализирани в контекста на решавания проблем за разпознаване на подписи.

        Теоремата на Hornik-Stinchcombe-White установява, че мрежите с право разпространение на сигнала са напълно в състояние да изпълнят нелинейно разграничаване на изследваните образци. Неуспехите за разпознаване на този тип НМ, се дължат на:

        • неподходящо обучение

        • неподходяща архитектура

        • силен шум във входните данни

        • неразделимост на признаците - неподходящо установяване на признаците

        Съвременния подход за реализация на разпознаване използва

        прави невронни мрежи (Fausett, 1994; Fu, 1994; Zurada, 1992). Работата на правите НМ е по същество трансформация на N-мерно кубично пространство T в M-мерно кубично пространство O:

        T:[a, b]! O:[a, b], означаващо следното (x, …, x) ! (y, …, y),

        където a x,y b, T е пространството на входните вектори от признаци, които се подават на входа на НМ, а O е пространството на класовете или векторите, които се появяват на изхода на НМ.

            1. Представяне на входните сигнали

        Стандартния N-мерен куб [0, 1] е най-често използваното входно пространство. Друго често използвано входно пространство е [-1, 1]. Това означава, че признаците идентифициращи даден обект трябва да са в интервала [0, 1]. Величините, които идентифицират даден обект и принадлежат на входното пространство T:[0, 1] ще наричаме признаци на обекта. Трябва да се съобразим с това, че реалните величини p, които описват обектите имат стойности в интервала (-","), които ще наричаме характеристики на обекта. Това показва, че вектор с реалните характеристики на обекта p = (p, …, p) трябва да се трансформират до вектор от признаци на обекта x = (x, …, x) от пространството T.

        Ще разгледаме три възможни начина за тази трансформация, като трябва да се отбележи, че не са единствените. Условието, което ще поставим е трансформацията да запазва броя и смисъла на параметрите идентифициращи обектите. Това условие се налага от факта, че реалните характеристики на обектите, в частност подписите, се определят от външна система, която не е обект на изследване в настоящата дипломна работа.

        Друго важно условие, което трябва да изпълнява трансформацията е да запазва разделимостта на обектите в пространството на признаците T, такова каквото е в реалното пространство.

        Първата възможна трансформация е да се извърши нормализация на вектора от характеристики, при което се получава нормализиран вектор с признаци, чиято дължина е единица (единичен вектор). На НМ се подава получения единичния вектор.

        Формулата за нормализиране на вектора P = (p, …, p) до единичен вектор X = (x, …, x) относно всеки елемент на вектора е:

        (3.1)

        където .

        От формулата е ясно, че два обекта описвани с характеристични вектори P1 и P2, могат да имат един и същ единичен вектор. Виждаме, че при тази трансформация не се запазва разделимостта на обектите във входното пространство на признаците T. Поради това нито една система за разпознаване не може да различи два или повече обекта, които имат един и същ вектор на признаците (единичен вектор).

        Втората трансформация представлява нормиране на всяка отделна характеристика спрямо максимална и минимална стойност, която може да приема тази характеристика. Максималната и минималната стойност се определят измежду всички стойности участващи в обучаващото множество за дадена НМ. Нека имаме две НМ, като първата е обучена да разпознава подпис A, а втората разпознава подпис B. Опитваме се да установим подобието на трети подпис C с подписи A и B, като трите подписа са напълно разделими в реалното пространство P. Оказва се, че е възможно и двете НМ на подписи A и B да покажат голямо съвпадение с тестовия подпис C, което очевидно е неправилно, защото подписите за различни. Този опит показва, че е нарушена разделимостта на обектите в пространството на признаците T.

        Третата трансформация е подобна на втората. Различието се състои в това, че максималната и минималната стойност на всяка характеристика са определени статистически и са общи за всички подписи. Това определя единен начин за нормализиране параметрите на подписите, което поставя всички НМ при общи условия и единно пространство на признаците, в което се запазва разделимостта им.

        Трите трансформации са изследвани с реализираната симулация на НМ за разпознаване на подписи и се установява, че най-подходяща е третата, която се препоръчва за използване при системи за разпознаване.

        Трудността при тази трансформация е нуждата от статистическо изследване, за което може да се направят справки с подходяща литература и експерти.

            1. Оценъчна функция

        Оценъчната функция се използва за определяне състоянието на обученост на НМ. Когато се достигне желана стойност на оценъчната функция, обучението се прекратява и се смята, че НМ е обучена. В настоящата реализация се използва усреднена средноквадратична грешка за всичките образци:

        (3.2)

        където M е броя образци в обучаващото множество, а е средно квадратичната грешка за образец m.

            1. Структура и размер на мрежата

        Теоретичните справки показват, че повечето нормални функции могат да бъдат апроксимирани от ИНМ с един скрит слой, в който има N - 1 на брой неврони, където N е броя на изследваните образци. От друга страна, реалните възможности ни ограничават до използването на малък брой неврони в скрития слой. Авторите Тамура (Tamura) и Татеиши (Tateishi) [3], доказват, че повечето функции могат да бъдат апроксимирани от НМ с два скрити слоя, които общо имат само N/2 + 3 неврона. Това е значително по-обнадеждаващо от гледна точка на реализацията.

        В настоящата дипломна работа се използва ИНМ с един скрит слой, тъй като класовете, които трябва да разпознава НМ са само два - “истински” и “фалшив”. Нелинейната апроксимация, която се постига с един слой е достатъчна за разделянето на входното пространство на два класа.

            1. Коефициент на обучение

        Коефициентът на обучение  определя колко големи ще са измененията на теглата на връзките. Ако стойността на коефициента е малка, обучението ще е бавно, но е по-сигурно, че обучението ще е успешно. При големи стойности, промените на теглата са големи и е много вероятно да се пропусне минимума на грешката (E) и НМ да не се обучи. Поради това се предлага, коефициента на обучение да се изменя в процеса на обучение по следния начин:

        (3.3)

        ш+a, ako < 0 (t-1; t-s)

        ш -b., ako > 0 (3.4)

        ш 0, ako = 0

        където a и b са предварително избрани константи, е изменението на оценъчната функция, а с означението (t-1; t-s) се показва, че трябва да е по-малка от 0 няколко поредни стъпки - последните s стъпки.

            1. Начална инициализация на теглата

        Известно е, че две различни инициализиращи множества на теглата

        могат да доведат до напълно различни резултати. Първоначалните проучвания посочват, че началните стойности на теглата трябва да са малки (по-малки от 0.5). Предполага се, че така се избягва запушването и насищането на невроните. Изследвания на тази тема се правят от Fahlman(1989), Zurada(1992), Russo (1991) и Nguyen и Widrow (1990).

        Russo(1991) предлага емпирично правило за начално установяване на теглата:

        -2.4/М 2.4/M (3.5)

        където M е броя на входните връзки на j -тия неврона.

        Nguyen и Widrow (1990) предлагат правило за начална инициализация на невроните от скритите слоеве. Нека N е броя на входните връзки и M е броя на невроните в слоя. Те дефинират следния параметър:

        (3.7)

        и установяват теглата {} случайно между -1 и 1. След това модифицират теглата по следното правило:

        (3.8)

        където . Множеството {} се приема като начално стойности на теглата. Този метод спомага за избягването на насищането на невроните в скритите слоеве, поради което е избран в настоящата симулация на НМ. Методът на Russo(1991) е избран за инициализация на теглата на изходния слой.

          1. Специфични проблеми при НМ за разпознаване на подписи

        Подходите за реализация на система за разпознаване на подписи с

        ИНМ са основно два. При първия, за всеки индивид се изгражда и пази една НМ, която има само един изходен неврон, с възможни състояние - истински или фалшив (подпис). Вторият метод ползва една обща мрежа, която има толкова изходи (изходни неврони) колкото е броят на индивидите. Тогава активността на един неврон показващ принадлежността на подадения входен подпис към даден индивид. Към двата варианта може да бъде добавен още един неврон за състояние “не зная”. Първата реализация ще бъде по-точна, защото подавания входен вектор ще има много по-малко възможни стойности. Този вариант обаче ще изисква по-големи ресурси и като цяло е по-сложна за реализиране. Вторият подход изисква добавяне на още един изходен неврон за всеки нов индивид и преобучаване на НМ.

        За да се избегне този проблем може да се използва НМ, при която изходните стойности да се третират като идентификационен код на индивида. Тъй като изходните стойности са аналогови, това ще доведе до трудности в определянето на точния идентификационен код.

        При решаването на задачата за разпознаване на подписи полезно би било, ако освен отговора истински ли е или фалшив, да се покаже и степента на сигурност на отговора. Най-често като такъв критерий се използва оценъчната функция.

        За да бъде по-точно разпознаването, много важно е предварителното извличане на характеристиките на подписа, тъй като те се подават на входовете на НМ. Това поставя проблеми като: колко голямо трябва да бъде множеството от еталонни (обучаващи) подписи и множеството от тестови подписи, през какво време трябва да се взимат пробите на подписи, какви методи и средства да се ползват за обработка на изображенията на подписите и др. Логиката подсказва, че повечето подписи използвани при обучение ще доведе до по-добри резултати. Това обаче е за сметка на по-голям обем памет необходим за съхраняването на пробите и по-дългото време за обучение. Възможно е обучаващите образци да се подават по няколко пъти на входа. Това обаче трябва да става по случаен ред за да не може НМ да се приспособи само към някой отделен подпис.

        • Програмна среда и реализация на НМ и БД

        Като среда за създаване на програмата за симулация на НМ е използвана Microsoft Visual C++ 6.0.

        Общ алгоритъм за работа на НМ

          1. Алгоритъм за създаване на НМ

        Създаването на НМ преминава през следните етапи:

        1. Определяне броя на слоевете;

        2. Задаване броя неврони за всеки слой;

        3. Създаване обекта на НМ - създаване на обект представляващ невронната мрежа

        4. Създаване обектите на слоевете на НМ;

        5. Създаване обектите на невроните за всеки слой;

        6. Инициализация на теглата - алгоритъмът е даден по-подробно в точка 4.3;

          1. Алгоритъм за начална инициализация на теглата

        Алгоритъмът за начална инициализация използва правилото на

        Nguyen и Widrow (1990) за установяване на теглата от скритите слоеве и правилото на Russo(1991) за изходния слой.

        Абстрактното описание на алгоритъма е:

        w0.0; /дължината на вектора ||w||

        ; / параметъра на Nguyen и Widrow

        for m = 1 to M do

        for j = 1 to J do

        draw randomly in [-1, 1]; /За изходния слой

        (2.4/М) ;

        for n = 1 to N do

        draw randomly in [-1, 1] /За скритите тегла

        ; ;

        for m =1 to M do

        for n = 1 to N do

        / метод на Nguyen и Widrow

          1. Алгоритъм за обучение на НМ

        Обучението с учител за един образец преминава през два основни етапа:

        • Стимулиране и установяване на изхода на НМ - на входа на НМ се подава образец и се изчислява изхода на НМ (изходен сигнал);

        • Изчисляване на грешката

        • Изчисляване на изхода на НМ

        • Адаптация - промяна на теглата по определен алгоритъм с цел постигането на желания резултат. Алгоритъмът за адаптацията на един неврон е дефиниран в точка 4.9.

          1. Алгоритъм за разпространение на сигнала напред

        Алгоритъмът за разпространение напред има следното абстрактно описание:

        1. Установяване на входовете със входните сигнали

        2. for i = 1 to L //За всеки слой

        3. for n = 1 to N //За всеки неврон от слой I

        4. neuron.forward_signal //Невронът провежда сигнала напред

        5. End //Край

          1. Алгоритъм за разпространение назад на сигнала на грешката

        Алгоритъмът за разпространение назад има следното абстрактно описание:

        1. Установяване на входовете със входните сигнали

        2. for i = L to 1 //За всеки слой от края към началото

        3. for n = 1 to N //За всеки неврон от слой I

        4. neuron.backward_signal //Невронът провежда сигнала назад

        5. End //Край

          1. Алгоритъм за разпространение на сигнала напред в един неврон

        Алгоритъмът за разпространение напред има следното абстрактно описание:

        1. //Нулиране на сумата на входа

        2. for m = 1 to M //За всяка входна връзка

        3. //Умножаване на входни сигнал с теглото на връзката и добавянето му към общата сума

        4. //Изчисляване на активиращата функция

        5. //Установяване на изхода на неврона

          1. Алгоритъм за разпространение назад на сигнала на грешката в един неврон

        Алгоритъмът за разпространение назад има следното абстрактно описание:

        1. //Нулиране на грешката за неврона

        2. For o = 1 to OUTPUTS //За всички изходи

        3. //Сумиране на входните грешки от предишните слоеве. Ако невронът е изходен тогава e грешката на изхода.

        4. //Изчисляване градиента на грешката

        5. for m=1 to M //За всяка входна връзка

        6. //Претегляне на грешката с тегловия коефициент на връзката

          1. Алгоритъм за обучение на един неврон

        Алгоритъмът за обучение на една връзка има следното абстрактно описание:

        1. For m=1 to M //За всяка входна връзка

        2. //Обучение на връзката

          1. Алгоритъм за съхранение

        Процесът на съхранение осигурява запис и четене на данни от

        постоянната памет (дисков файл). Обектите с чиято помощ се симулира работата на НМ, имат вграден механизъм за съхранение на свързаните с тях данни. Те получават “сигнали” за четене или запис и извършват съответната операция.

        Алгоритъмът се базира на идеята, че всеки обект трябва да може да запише текущото си състояние, което се представя от стойностите на неговите атрибути. Запис е реализиран като обекта записва в последователен ред стойностите на атрибутите си. Четенето става като последователно се прочетат всички записани стойности.

        Алгоритъмът за записване състоянието на една НМ има следния вид:

        1. Network->store //Подаване сигнал за съхранение на НМ

        2. For l = 1 to L //За всеки слой

        3. For n = 1 to N //За всеки неврон

        4. Neuron->store //Сигнал за съхранение на неврона

          1. Програмни структури за симулация на НМ

        На фиг. 4.1 е показана UML-диаграма на класовете. За проектирането на структурите е използван UML(Unified Modeling Language) средата на RationalRose2001.

        • Заключение

        От направеното теоретично изложение и от посочените тестови резултати се вижда, че НМ с обратно разпространение на грешката са много ефективни при разпознаване на подписи. Въпреки, че са способни да извършат нелинейно разделяне на входните данни, колкото повече класове трябва да разпознава една НМ толкова по-неточни стават отговорите, при запазване на същата архитектура.

        Проблемът на НМ с един скрит слой е, че невроните си взаимодействат глобално, което прави невъзможно подобряването на апроксимацията в една точка без да се наруши в друга точка. Наличието на втори скрит слой прави апроксимациите в отделните точки независими, което води до значително по-добро нелинейно разделяне на входното пространство. Повечето слоеве обаче изискват повече изчислителни ресурси и е необходимо повече време за обучение.

        В настоящия случай на разпознаване на подписи се използват НМ, които се обучават да разделят входното пространство на два класа - “истински” и “фалшив”. За реализиране на тази задача е достатъчна права НМ с един скрит слой. По този начин се постига по-бързо обучение и достатъчно голяма точност, което може да се види от експерименталните резултати.

        Идеалното обучение на една НМ за разпознаване на подписи е практически невъзможно, поради нестабилния характер на данните.

        Това се дължи на факта, че подписа на един човек зависи от възрастта, от физическото и психическото му състояние, от вида на хартията, върху която се подписва, от вида на писалката и още много други. Целта на разпознаването е да се изградят статистически правила, с които да се обединят подписите на една личност, но същевременно да се разграничат от подписите на останалите личности. Това може да стане чрез увеличаване на размерността на входното пространство на признаците, използване на подобрени модифицирани алгоритми за обучение и нови топологии на НМ.

        При използването на НМ за различаване на подписи на различни

        индивиди се постигат значително добри резултати. Не толкова добре стоят нещата когато трябва да се изследват подправени подписи. Самият процес на подправяне (фалшификация) означава, че един индивид (фалшификатор) се опитва да имитира подписа на друг индивид. Можем да се досетим, че подправеният подпис по никакъв начин (използвайки НМ) не можем да го определим като истински подпис на фалшификатора. Но да го определим, че не принадлежи на потърпевшия индивид е много трудно, тъй като характеристиките на фалшивия подпис попадат в статистическото разпределение на характеристиките на истинските подписи на индивида.

        Въпреки това, процесът на откриване на подправени подписи се улеснява от това, че аматьорските (грубите) фалшификации са 94% от случаите срещани в практиката. Можем да се възползваме от това като разделим процеса на разпознаване на две степени. В първата степен се извършва разпознаване на произволните и прости фалшификации. В случай, че има съмнение за фалшификация се използва втора степен, с чиято помощ се прави опит да се покрият останалите 6% фалшификации. Предимството на този подход е, че първата степен на разпознаване е много бърза.

        • Приложение - тестови примери

          1. Тест1

        Този тест има за цел да установи оптималната архитектура на НМ.

        Тествани са две НМ:

        • НМ с един скрит слой с 26 неврона и един изход. Коефициентът на обучение за скрития слой е 1.0, а за изходния 0.1.

        • НМ с два скрити слоя и един изход. Първият скрит слой е с 26 неврона, а втория е с 13. Коефициентът на обучение за първия слой е 1.0, за втория е 0.1, а за изходния неврон слой е 0.01.

        Условието за прекратяване на обучението е оценъчната функция -MSE да стане по-малка от 0.001. Обучаващото множество се състои от общо 40 образеца, като 20 са истински.

        От показаните резултати се вижда, че обучението е по-бързо при двуслойната мрежа при сравнително запазване на грешката.

        Двуслойна НМ

        Обучение

        Епоха #

        664

        Минимална MSE

        0,000992788

        Последна MSE

        0,000992788

        Двуслойна Нм

        Желан резултат

        MSE

        0,002443934

        Min Abs Error

        0,002866149

        Max Abs Error

        0,097755969

        Трислойна НМ

        Training

        Епоха #

        5098

        Минимална MSE

        0,000998758

        Последна MSE

        0,000998758

        Трислойна НМ

        DesiredOutput

        MSE

        0,002465026

        Min Abs Error

        0,035263062

        Max Abs Error

        0,070315123

          1. Тест2

        Този тест има за цел да изследва коефициента на обучение.

        Опитът е проведен върху две двуслойни НМ с 26 неврона в скрития слой и един изход. Двете НМ се различават само по коефициента на обучение, който е 13.0 за първата НМ и 26.0 за втората НМ. Като допълнителен тест може да се разглежда двуслойната НМ от Тест1. Обучаващото множество се състои от общо 40 образеца, като 20 са истински.

        Двуслойна НМ

        Обучение

        Епоха #

        27

        Минимална MSE

        0,000413437

        Последна MSE

        0,000413437

        Коеф.об.

        13.0

        Двуслойна НМ

        ЖеланИзход

        MSE

        0,000944581

        Min Abs Error

        0,00116539

        Max Abs Error

        0,073911846

        Двуслойна НМ

        Обучение

        Епоха #

        31

        Минимална MSE

        7,60749E-05

        Последна MSE

        7,60749E-05

        Коеф.об.

        26.0

        Двуслойна НМ

        ЖеланИзход

        MSE

        0,000187492

        Min Abs Error

        8,51154E-05

        Max Abs Error

        0,027748914

        • Приложение - разпечатка на програмата

        // AAxon.h

        //

        #if !defined(AAxon_h)

        #define AAxon_h

        /*

        * AAxon carry on the signal from the body and provides artificial

        * management of all outputs.

        */

        #include "resource.h"

        #include "ANeuralUnit.h"

        class AAxonTerminal;

        class ASynapse;

        class ANeuron;

        class ALayeredNet;

        class ANeuralDisplay;

        class AAxon : public ANeuralUnit

        {

        friend ANeuron;

        friend ASynapse;

        friend ALayeredNet;

        friend ANeuralDisplay;

        public:

        AAxon();

        AAxon(ALocation loc);

        /*

        * Defaults initializations

        */

        void init();

        virtual ~AAxon();

        void setImpulse(ASIGNAL impulse);

        /*

        * Add terminal to the list of axon terminals.

        */

        void addterminal(ALocation loc, ANEUROTRANSMITTER NTTstore, ANEUROTRANSMITTER NTTproduction, ASynapse* pSynapse);

        protected:

        //***************** Parts the AxonTerminal *********************

        /*

        * Membrane of the terminal

        */

        APotentialMembrane m_membrane;

        //***************** Artificial properties **********************

        //***************** Methods ************************************

        virtual void accommodation();

        /*

        * Gives to unit the ability to do something.

        */

        virtual void propagate();

        /*

        * Recover the unit status from previous action.

        */

        virtual void recover();

        private:

        /*

        * List with axon terminals.

        */

        typedef CTypedPtrList<CPtrList, AAxonTerminal*> AxonList;

        AxonList m_terminalList;

        };

        #endif /* AAxon_h */

        // AAxon.cpp

        //

        #include "stdafx.h"

        #include "AAxon.h"

        #include "AAxonTerminal.h"

        #include "ASynapse.h"

        AAxon::AAxon()

        {

        this->init();

        }

        AAxon::AAxon(ALocation loc) : ANeuralUnit(loc)

        {

        this->init();

        }

        void AAxon::init()

        {

        //Defaults

        this->m_membrane.init(ADAT_THRESHOLD, ADAT_ACTIONPOTENTIAL, ADAT_RESTINGPOTENTIAL);

        this->m_refractoryperiod = ADAT_REFRACTPERIOD;

        }

        AAxon::~AAxon()

        {

        //Destroy the list

        AAxonTerminal* node;

        POSITION pos = this->m_terminalList.GetHeadPosition();

        while(pos != NULL)

        {

        node = this->m_terminalList.GetNext(pos);

        delete node;

        }

        this->m_terminalList.RemoveAll();

        }

        void AAxon::propagate()

        {

        //Reset previous total error value

        if (this->m_terminalList.GetCount() > 0)

        this->m_accommodation = AACC_MIN;

        //Proccess all terminals

        AAxonTerminal* node;

        POSITION pos = this->m_terminalList.GetHeadPosition();

        while(pos != NULL)

        {

        node = this->m_terminalList.GetNext(pos);

        //transport the accommodation impulse from the terminal

        // this->m_accommodation += node->m_accommodation;

        //transport the impulse to the terminal

        node->m_membrane.m_impulspotential = this->m_membrane.m_impulspotential;

        //proccess the terminal

        node->go();

        }

        }

        void AAxon::recover()

        {

        }

        void AAxon::setImpulse(ASIGNAL impulse)

        {

        this->m_membrane.m_impulspotential = impulse;

        }

        void AAxon::addterminal(ALocation loc, ANEUROTRANSMITTER NTTstore, ANEUROTRANSMITTER NTTproduction, ASynapse* pSynapse)

        {

        //create terminal

        AAxonTerminal* pNewTerminal = new AAxonTerminal();

        //init terminal

        pNewTerminal->m_membrane = this->m_membrane;

        //...

        pNewTerminal->m_location = loc;

        pNewTerminal->m_pPreSynaptic = pSynapse;

        //connect terminal with synapse

        pSynapse->m_pPreSynaptic = pNewTerminal;

        //insert the terminal into the list of terminals

        this->m_terminalList.AddHead(pNewTerminal);

        }

        void AAxon::accommodation()

        {

        if (this->m_terminalList.GetCount() > 0)

        this->m_accommodation = AACC_MIN;

        AAxonTerminal* node;

        POSITION pos = this->m_terminalList.GetHeadPosition();

        while(pos != NULL)

        {

        node = this->m_terminalList.GetNext(pos);

        //transport the accommodation impulse from the terminal

        this->m_accommodation += node->m_accommodation;

        }

        }

        // AAxonTerminal.h

        //

        #if !defined(AAxonTerminal_h)

        #define AAxonTerminal_h

        /*

        * The AAxonTerminal is the artificial analogue of the neural

        * output(axon terminals).

        */

        #include "resource.h"

        #include "ANeuralUnit.h"

        #include "ANeuralMeasures.h" // Added by ClassView

        class AAxon;

        class ASynapse;

        class AAxonTerminal : public ANeuralUnit

        {

        friend AAxon;

        friend ASynapse;

        public:

        void init();

        AAxonTerminal();

        virtual ~AAxonTerminal();

        protected:

        //***************** Parts the AxonTerminal *****************

        /*

        * Membrane of the terminal

        */

        APotentialMembrane m_membrane;

        //***************** Artificial properties **********************

        /*

        * Quantity of neurotransmitters stored in the vesicles.

        */

        ANEUROTRANSMITTER m_NTTstore;

        /*

        * Quantity of neurotransmitter production.

        */

        ANEUROTRANSMITTER m_NTTproduction;

        /*

        * Quantity of neurotransmitters which will be released in the

        * synaptic cleft when the synapse is propagated.

        */

        ANEUROTRANSMITTER m_NTTreleased;

        ANEUROTRANSMITTER m_NTTmaxreleased;

        ANEUROTRANSMITTER m_NTTrestingreleased;

        ASynapse* m_pPreSynaptic;

        //***************** Methods ************************************

        virtual void accommodation();

        virtual ANEUROTRANSMITTER impulse();

        /*

        * Gives to unit the ability to do something.

        */

        virtual void propagate();

        /*

        * Recover the unit status from previous action.

        */

        virtual void recover();

        /*

        * Release a quantity of neurotransmiters

        * into the synaptic clift.

        */

        virtual ANEUROTRANSMITTER dischargeNTT();

        private:

        };

        #endif /* AAxonTerminal_h */

        // AAxonTerminal.cpp

        //

        #include "stdafx.h"

        #include "AAxonTerminal.h"

        #include "ASynapse.h"

        AAxonTerminal::AAxonTerminal()

        {

        this->init();

        }

        void AAxonTerminal::init()

        {

        //Defaults

        //membrane is already initialized from tha Axon::addterminal();

        this->m_pPreSynaptic = NULL;

        this->m_NTTproduction = ADAT_NTTPRODUCTION;

        this->m_NTTstore = ADAT_NTTSTORE;

        this->m_NTTmaxreleased = ADAT_NTTRELEASED;

        this->m_NTTrestingreleased = ADAT_NTTRESTING;

        this->m_NTTreleased = this->m_NTTrestingreleased;

        }

        AAxonTerminal::~AAxonTerminal()

        {

        }

        ANEUROTRANSMITTER AAxonTerminal::dischargeNTT()

        {

        ANEUROTRANSMITTER rel = this->m_NTTreleased;

        this->m_NTTreleased = ADAT_NTTRESTING;

        return rel;

        }

        void AAxonTerminal::propagate()

        {

        // this->accommodation();

        this->m_NTTreleased = this->impulse();

        this->m_NTTreleased = (this->m_NTTstore < this->m_NTTreleased) ? this->m_NTTstore : this->m_NTTreleased;

        this->m_NTTstore -= this->m_NTTreleased;

        //sync with synapse

        this->m_pPreSynaptic->sync();

        }

        void AAxonTerminal::recover()

        {

        //produce neurotransmitters

        this->m_NTTstore += this->m_NTTproduction;

        //stop production if max store is reached

        this->m_NTTstore = (this->m_NTTstore > ADAT_NTTSTORE) ? ADAT_NTTSTORE : this->m_NTTstore;

        this->m_NTTreleased = ADAT_NTTRESTING;

        this->m_accommodation = AACC_MIN;

        }

        ANEUROTRANSMITTER AAxonTerminal::impulse()

        {

        if (A_IMPULSE_SIGNAL)

        {

        if (this->m_membrane.m_impulspotential > this->m_membrane.m_threshold)

        {

        //impulse signal

        return this->m_NTTmaxreleased;

        }

        }

        else

        {

        //Analog signal - percent of the signal

        return (this->m_membrane.m_impulspotential / (this->m_membrane.m_actionpotential - this->m_membrane.m_restingpotential) + this->m_membrane.m_restingpotential) * (this->m_NTTmaxreleased - this->m_NTTrestingreleased) + this->m_NTTrestingreleased;

        }

        return this->m_NTTrestingreleased;

        }

        void AAxonTerminal::accommodation()

        {

        }

        // ANeuron.h

        //

        #if !defined(ANeuron_h)

        #define ANeuron_h

        /*

        * Represents the artificial neuron.

        * Realize the managment for all parts of the neuron as body, axon

        * and dendrites.

        */

        #include "resource.h"

        #include "ANeuralUnit.h"

        class ADendrite;

        class ANeuronBody;

        class AAxon;

        class ANeuron : public ANeuralUnit

        {

        public:

        virtual void accommodation();

        virtual void setError(AERROR aError);

        virtual OnDraw();

        ANeuron();

        ANeuron(ALocation loc, ANeuralUtility::NEURONTYPE type);

        virtual ~ANeuron();

        ASIGNAL getImpulse();

        bool getFired();

        void setFired(ASIGNAL fire);

        ADendrite* getDendrite();

        ANeuronBody* getBody();

        AAxon* getAxon();

        protected:

        virtual void recover();

        /*

        * Gives to unit the ability to do something.

        */

        virtual void propagate();

        /*

        * The dendrite structure of the nuron.

        * This is a list with all dendrite terminals.

        */

        ADendrite *m_pDendrite;

        /*

        * The body of the neuron.

        */

        ANeuronBody *m_pBody;

        /*

        * The axon of the neuron.

        * This is a list with all axon terminals.

        */

        AAxon *m_pAxon;

        private:

        };

        #endif /* ANeuron_h */

        // ANeuron.cpp

        //

        #include "stdafx.h"

        #include "ANeuron.h"

        #include "ADendrite.h"

        #include "ANeuronBody.h"

        #include "AAxon.h"

        #include "ANeuralEnvironment.h"

        ANeuron::ANeuron()

        {

        //Create the parts of the neuron

        this->m_pAxon = new AAxon();

        this->m_pBody = new ANeuronBody();

        this->m_pDendrite = new ADendrite();

        }

        ANeuron::ANeuron(ALocation loc, ANeuralUtility::NEURONTYPE type) : ANeuralUnit(loc)

        {

        //Create the parts of the neuron

        this->m_pAxon = new AAxon(loc);

        this->m_pBody = new ANeuronBody(loc, type);

        this->m_pDendrite = new ADendrite(loc);

        }

        ANeuron::~ANeuron()

        {

        //Destroy the parts of the neuron

        delete this->m_pAxon;

        delete this->m_pBody;

        delete this->m_pDendrite;

        }

        bool ANeuron::getFired()

        {

        return (bool) this->m_pBody->m_fired;

        }

        ASIGNAL ANeuron::getImpulse()

        {

        return this->m_pBody->m_membrane.m_impulspotential;

        }

        void ANeuron::setFired(ASIGNAL fire)

        {

        // this->getBody()->m_mustfire = fire;

        this->getBody()->m_membrane.m_threshold = fire;

        }

        void ANeuron::propagate()

        {

        //Proccess all parts of the neuron

        //process dendrite

        //process the dendrite

        this->m_pDendrite->go();

        //transport the impulse to the body

        this->m_pBody->m_dendriteimpulse = this->m_pDendrite->getImpulse() + this->m_pBody->m_membrane.m_restingpotential;

        //process body

        this->m_pBody->go();

        //transport the activation to the axon

        this->m_pAxon->m_membrane.m_impulspotential = this->m_pBody->m_membrane.m_impulspotential;

        //process axon

        this->m_pAxon->go();

        }

        void ANeuron::recover()

        {

        }

        ADendrite* ANeuron::getDendrite()

        {

        return (ADendrite*)this->m_pDendrite;

        }

        ANeuronBody* ANeuron::getBody()

        {

        return (ANeuronBody*)this->m_pBody;

        }

        AAxon* ANeuron::getAxon()

        {

        return (AAxon*)this->m_pAxon;

        }

        ANeuron::OnDraw()

        {

        this->getEnvironment()->m_Display.drawNeuron(this);

        }

        void ANeuron::setError(AERROR aError)

        {

        this->m_pAxon->m_accommodation = aError;

        }

        void ANeuron::accommodation()

        {

        //Backpropage process

        this->getAxon()->accommodation();

        this->getBody()->m_accommodation = this->getAxon()->m_accommodation;

        this->getAxon()->m_accommodation = AACC_MIN;

        this->getBody()->accommodation();

        this->getDendrite()->m_accommodation = this->getBody()->m_accommodation;

        this->getDendrite()->accommodation();

        OnDraw();

        }

        // ANeuronBody.h

        //

        #if !defined(ANeuronBody_h)

        #define ANeuronBody_h

        /*

        * Body simulates the generation of the artificial output

        * potential.

        */

        #include "ANeuralUnit.h"

        #include "ANeuralMeasures.h" // Added by ClassView

        class ANeuron;

        class ANeuronBody : public ANeuralUnit

        {

        friend ANeuron;

        friend ANeuralDisplay;

        public:

        virtual void accommodation();

        void init();

        ANeuronBody();

        ANeuronBody(ALocation loc, ANeuralUtility::NEURONTYPE type = ANeuralUtility::NT_HIDDEN);

        virtual ~ANeuronBody();

        /*

        * Simulates the artificial function of the activating neuron.

        * In artificial simulation the generated impulse can be smaller

        * than activation potential, which in the real neuron is the

        * generated impulse.

        */

        virtual ASIGNAL impulse();

        protected:

        /*

        * Gives to unit the ability to do something.

        */

        virtual void propagate();

        /*

        * Recover the unit status from previous action.

        */

        virtual void recover();

        /*

        * Signals that the neuron is fired.

        */

        bool m_fired;

        ANeuralUtility::NEURONTYPE m_neuronType;

        /*

        * Membrane of the body

        */

        APotentialMembrane m_membrane;

        ASIGNAL m_dendriteimpulse;

        private:

        bool m_mustfire;

        };

        #endif /* ANeuronBody_h */

        // ANeuronBody.cpp

        //

        #include "stdafx.h"

        #include "ANeuronBody.h"

        #include "APotentialMembrane.h"

        #include "ANeuralEnvironment.h"

        ANeuronBody::ANeuronBody()

        {

        this->init();

        }

        ANeuronBody::ANeuronBody(ALocation loc, ANeuralUtility::NEURONTYPE type) : ANeuralUnit(loc)

        {

        this->init();

        this->m_neuronType = type;

        }

        void ANeuronBody::init()

        {

        //Defaults

        this->m_membrane.init(ADB_THRESHOLD, ADB_ACTIONPOTENTIAL, ADB_RESTINGPOTENTIAL);

        this->m_dendriteimpulse = this->m_membrane.m_restingpotential;

        this->m_fired = false;

        this->m_refractoryperiod = ADB_REFRACTPERIOD;

        this->m_mustfire = false;

        this->m_neuronType = ANeuralUtility::NT_HIDDEN;

        }

        ANeuronBody::~ANeuronBody()

        {

        }

        void ANeuronBody::propagate()

        {

        // this->accommodation();

        if (this->m_refractoryclock <= 0)

        {

        //check if the neuron must fire

        if (this->m_mustfire)

        {

        //fire neuron and set the refractory clock

        this->m_dendriteimpulse = this->m_membrane.m_actionpotential;

        this->m_mustfire = false;

        }

        this->impulse();

        }

        }

        void ANeuronBody::recover()

        {

        this->m_fired = false;

        this->m_accommodation = 0.0;

        }

        ASIGNAL ANeuronBody::impulse()

        {

        /*

        if (this->m_dendriteimpulse > (this->m_membrane.m_threshold))

        { //Induced impulse to the neuron is up the threshold and

        //the neuron will be fired

        //Generated impulse is some function of the dendrite signal

        this->m_membrane.m_impulspotential = ADB_ACTIVATION_FUNCTION(this->m_dendriteimpulse, this->m_membrane.m_actionpotential, this->m_membrane.m_restingpotential);

        //fire neuron and set the refractory clock

        this->m_refractoryclock = this->m_refractoryperiod;

        this->m_fired = true;

        }

        else

        {

        //Generated impulse is some function of the dendrite signal

        this->m_membrane.m_impulspotential = ADB_ACTIVATION_FUNCTION(this->m_dendriteimpulse, this->m_membrane.m_actionpotential, this->m_membrane.m_restingpotential);

        // this->m_membrane.m_impulspotential = this->m_membrane.m_restingpotential;

        }

        */

        //Generated impulse is some function of the dendrite signal

        //Add threshold to the dendrite signal

        this->m_dendriteimpulse += this->m_membrane.m_threshold * this->m_membrane.m_actionpotential;

        if (this->m_neuronType != ANeuralUtility::NT_INPUT)

        { //Hidden or output neuron

        this->m_membrane.m_impulspotential = ADB_ACTIVATION_FUNCTION(this->m_dendriteimpulse, this->m_membrane.m_actionpotential, this->m_membrane.m_restingpotential);

        if (this->m_membrane.m_impulspotential > ((this->m_membrane.m_actionpotential+this->m_membrane.m_restingpotential)/2))

        {

        //fire neuron and set the refractory clock

        this->m_refractoryclock = this->m_refractoryperiod;

        this->m_fired = true;

        }

        }

        else

        { //Input neuron - must be simple imput

        this->m_membrane.m_impulspotential = this->m_dendriteimpulse;

        }

        return this->m_membrane.m_impulspotential;

        }

        void ANeuronBody::accommodation()

        {

        if (this->m_neuronType != ANeuralUtility::NT_INPUT)

        { //Hidden or output neuron

        double imp = (this->m_membrane.m_impulspotential - this->m_membrane.m_restingpotential) / (this->m_membrane.m_actionpotential - this->m_membrane.m_restingpotential);

        // if (imp != 0.0)

        {

        //Gradient

        this->m_accommodation *= ADB_DERIVATIVE_FUNCTION(this->m_dendriteimpulse);

        this->m_membrane.m_threshold += 0.5 * this->m_accommodation;

        }

        }

        }

        // ADendrite.h

        //

        #if !defined(ADendrite_h)

        #define ADendrite_h

        /*

        * ADendrite provides artificial management of all inputs and

        * simulates the camputation of total impulse from all dendrite

        * terminals.

        */

        #include "resource.h"

        #include "ANeuralUnit.h"

        #include "ASynapse.h"

        #include "ADendriteTerminal.h"

        class ANeuron;

        class ANeuralDisplay;

        class ALayeredNet;

        class ADendrite : public ANeuralUnit

        {

        friend ANeuron;

        friend ANeuralDisplay;

        friend ALayeredNet;

        public:

        virtual void accommodation();

        ADendrite();

        ADendrite(ALocation loc);

        virtual ~ADendrite();

        ASIGNAL getImpulse();

        /*

        * Adds new terminal to the list of dedrite terminals.

        */

        void addterminal(ALocation loc, ASIGNAL refractperiod, ASIGNAL actionpotential, ASIGNAL restingpotential, ANEUROTRANSMITTER maxusageNTT, ASynapse* pSynapse);

        protected:

        /*

        * Absolute impulse inudeced in terminals

        */

        ASIGNAL m_absolutimpuls;

        //***************** Methods ************************************

        virtual void recover();

        /*

        * Calculate the total impulse from all dendrite terminals.

        * Simplest calculation is to sum all inputs.

        *

        * Doesnot used at now!

        */

        // virtual void impulse();

        /*

        * Gives to unit the ability to do something.

        */

        virtual void propagate();

        private:

        /*

        * List with dendrite terminals.

        */

        typedef CTypedPtrList<CPtrList, ADendriteTerminal*> DendriteList;

        DendriteList m_terminalList;

        };

        #endif /* ADendrite_h */

        // ADendrite.cpp

        //

        #include "stdafx.h"

        #include "ADendrite.h"

        #include "ALocation.h"

        #include "ASynapse.h"

        #include "ADendriteTerminal.h"

        ADendrite::ADendrite()

        {

        this->m_absolutimpuls = 0;

        }

        ADendrite::ADendrite(ALocation loc)

        {

        this->m_absolutimpuls = 0;

        this->m_location = loc;

        }

        ADendrite::~ADendrite()

        {

        //Destroy the list

        ADendriteTerminal* node;

        POSITION pos = this->m_terminalList.GetHeadPosition();

        while(pos != NULL)

        {

        node = this->m_terminalList.GetNext(pos);

        delete node;

        }

        this->m_terminalList.RemoveAll();

        }

        void ADendrite::recover()

        {

        this->m_absolutimpuls = 0;

        }

        void ADendrite::propagate()

        {

        //Process all terminals

        ADendriteTerminal* node;

        POSITION pos = this->m_terminalList.GetHeadPosition();

        while(pos != NULL)

        {

        node = this->m_terminalList.GetNext(pos);

        //pass the accommodation value

        // node->m_accommodation = this->m_accommodation;

        //process

        node->go();

        //calculate total impulse

        this->m_absolutimpuls += node->getScaledRelativeImpulse();

        }

        }

        ASIGNAL ADendrite::getImpulse()

        {

        return this->m_absolutimpuls;

        }

        void ADendrite::addterminal(ALocation loc, ASIGNAL refractperiod, ASIGNAL actionpotential, ASIGNAL restingpotential, ANEUROTRANSMITTER maxusageNTT, ASynapse* pSynapse)

        {

        //create terminal

        ADendriteTerminal* pNewTerminal = new ADendriteTerminal;

        //init terminal

        //...

        pNewTerminal->m_location = loc;

        //connect terminal with synapse

        pNewTerminal->m_pPostSynaptic = pSynapse;

        pSynapse->m_pPostSynaptic = pNewTerminal;

        pSynapse->m_location = loc;

        //insert the terminal into the list of terminals

        this->m_terminalList.AddHead(pNewTerminal);

        }

        void ADendrite::accommodation()

        {

        ADendriteTerminal* node;

        POSITION pos = this->m_terminalList.GetHeadPosition();

        while(pos != NULL)

        {

        node = this->m_terminalList.GetNext(pos);

        //pass the accommodation value

        node->m_accommodation = this->m_accommodation;

        node->accommodation();

        }

        }

        // ADendriteTerminal.h

        //

        #if !defined(ADendriteTerminal_h)

        #define ADendriteTerminal_h

        /*

        * The ADendriteTerminal is the artificial analogue of the neural

        * input.

        */

        #include "ANeuralMeasures.h" // Added by ClassView

        #include "resource.h"

        #include "ANeuralUnit.h"

        class ADendrite;

        class ASynapse;

        class ANeuralDisplay;

        class ADendriteTerminal : public ANeuralUnit

        {

        friend ADendrite;

        friend ASynapse;

        friend ANeuralDisplay;

        public:

        virtual ASIGNAL getScaledRelativeImpulse();

        virtual void accommodation();

        ADendriteTerminal();

        virtual ~ADendriteTerminal();

        protected:

        //***************** Parts the DendrideTerminal *****************

        /*

        * Membrane of the terminal

        */

        APotentialMembrane m_membrane;

        //***************** Artificial properties **********************

        /*

        * Maximum quantity of neurotransmitters that can affect the

        * dendrite, and induces the max impulse equal to the action

        * potential.

        * This dendrite's property can be used to learn the dendrite.