42613

Використанням складних нейромереж в системах розпізнавання образів

Лабораторная работа

Информатика, кибернетика и программирование

Зворотне розповсюдження (Backpropagation algorithm) - це найпопулярніший алгоритм для навчання за допомогою зміни ваги зв'язків. Помилка розраховується від вихідного шару до вхідного, тобто в напрямі, протилежному напряму проходження сигналу при нормальному функціонуванні мережі. Хоча алгоритм достатньо простий, його розрахунок може зайняти досить багато ресурсу, залежно від розміру помилки.

Украинкский

2013-10-30

1.63 MB

1 чел.

DATE \@ "dd.MM.yyyy" 06.09.2010    КНЕУ   ФІСІТ    ІСЕ   Іванченко Г.Ф.  ©

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

КИЇВСЬКИЙ НАЦІОНАЛЬНИЙ ЕКОНОМІЧНИЙ УНІВЕРСИТЕТ

імені ВАДИМА ГЕТЬМАНА

Лабоpатоpна pобота № 1-1

По курсу  СИСТЕМИ РОЗПІЗНАВАННЯ ОБРАЗІВ

Тема: „Використанням складних нейромереж в системах розпізнавання образів

Виконав: студент

 Висоцький Максим  Вікторович

1 група, 5 курс,

спеціальність 8404

Перевірив: викладач

Доц. Іванченко Г. Ф.

КИЇВ 2010


Зворотне розповсюдження (Backpropagation algorithm) - це найпопулярніший алгоритм для навчання за допомогою зміни ваги зв'язків. Помилка розраховується від вихідного шару до вхідного, тобто в напрямі, протилежному напряму проходження сигналу при нормальному функціонуванні мережі. Хоча алгоритм достатньо простий, його розрахунок може зайняти досить багато ресурсу,  залежно від розміру помилки.

Виконання алгоритму починається із створення коефіцієнтів ваги, що довільно генеровані, для багатошарової мережі. Потім процес, описаний нижче, повторюється, поки середня помилка на вході не буде визнана достатньо рисою:

1.Береться значення вхідного сигналу Е з відповідним  правильним значенням виходу С.

2.Розраховується пряме розповсюдження Е через мережу (визначаються вагові суми   і активатори     для кожної клітини).

3.Починаючи з виходів, виконується зворотний рух через клітини вихідного і проміжного шарів, при цьому програма розраховує значення помилок .

- для вихідної клітини.

- для всіх прихованих клітин.

4.Нарешті, вага в мережі обновляється таким чином:

- для  ваги з'єднань між прихованим шаром і виходом .

- для  ваги  з'єднань між прихованим шаром і входом .

  - коефіцієнт навчання або розмір кроку. Це невелике значення обмежує зміну, яка може відбутися при кожному кроці. Параметр  можна визначити так, щоб він показував швидкість просування алгоритму зворотного розповсюдження до вирішення. Краще почати тестування з невеликого значення а потім поступово його підвищувати. Коефіцієнт навчання   робить значний вплив на швидкість навчання багатошарового персептрона і збіжність рішення. Вибір   звичайно здійснюють експериментально. Відносно великі значення   забезпечують швидке навчання, але при цьому існує небезпека одержати невірне рішення. Діапазон можливих значень   від   до . Окрім цього, конкретні значення , вибрані на початку процесу навчання, можуть виявитися не зовсім відповідними в кінці навчання. Тому, у ряді випадків,   змінюють в ході навчання. Один із способів управління значенням   полягає в контролі помилки. Якщо корекція вагових зв'язків при виконанні алгоритму приводить до збільшення помилки, то необхідно   зменшити. І навпаки, якщо помилка монотонно зменшується, то необхідно збільшити .

Просування вперед по мережі обновлює значення ваг так, щоб мінімізувати помилку для даного вхідного сигналу. Коефіцієнт  мінімізує відсоток зміни, яка може відбутися з ваговими коефіцієнтами. Хоча при невеликому коефіцієнті процес може зайняти більше часу, ми мінімізуємо можливість втрати правильної комбінації ваг. Якщо коефіцієнт навчання дуже великий, мережа може ніколи не зійтися, тобто не буде знайдена правильна вага зв'язків.

Алгоритм зворотнього розповсюдження застосований при створенні нейроконтролерів (НК)  для навчальної програми студентів. Нейроконтролером (Neurocontroller) звичайно називаються нейроні мережі, які використовуються  при управлінні. В цьому додатку ми задаємо нейронну мережу, щоб вибрати відповідь з доступного переліку відповідей на підставі того, в якій ситуації знаходиться студент і як він володіє матеріалом.

Причина використання  ШНМ як НК полягає в тому, що неможливо задати для штучного інтелекту навчальну поведінку, яка охоплювала б всі можливі в навколишньому середовищі ситуації. Тому необхідно навчити нейронну мережу на обмеженій кількості прикладів (тобто зразків відповідей  залежно від питань і ситуації), а потім дозволити їй самостійно генерувати поведінку студента в усіх інших ситуаціях. Здатність генерувати правильну реакцію на різні ситуації, що не входять в набір навчальних ситуацій, є ключовим чинником при створенні НК. Іншою перевагою НК є те, що він не є строго заданою функцією, яка забезпечує взаємодію між навколишнім середовищем і реакцією. Незначні зміни в навколишньому середовищі можуть викликати різну реакцію у НК, тому бесіда з  програмою  виглядає природніше. Фіксовані дерева поведінки або кінцеві автомати викликають передбачену реакцію, що досить погано відображається  на імітації штучного інтелекту.

Навчальне  середовище надає для студента певну інформацію, яка потім передається ШНМ. Процес «сприйняття» ШНМ навколишнього середовища називається передчуттям. НК забезпечує можливість вибору дії, за допомогою якої студент  взаємодіє з навколишнім середовищем. Навколишнє середовище при цьому змінюється, студент знов звертається до сприйняття НК, і цикл поновлюється.

У навчальній програмі НК використовуватимемо архітектуру  ШНМ, побудованої  за принципом «переможець отримує все». Така архітектура корисна в тому випадку, якщо виходи повинні бути розділені на декілька класів. В  ШНМ, створеної за цим  принципом  вихідна нейроклітина з більшою сумою вагових є «переможцем» групи і допускається до прийняття дії, тобто навчання студента. В даному прикладі кожна клітина представляє певний  результат, який доступний  для  ШНМ. Як приклади поведінки НК підбирається база знань  учбового матеріалу, тем, питань, задач  та відповідей, висновків, міркувань. І передбачається, що ШНМ вибиратиме дію поведінки і слідуватиме їй.

  1.   В роботі вибрана  архітектура ШНМ з трьома прихованими клітинами. Три приховані клітини можуть бути навчені для всіх представлених прикладів з 100% точністю, змінюється тільки кількість ітерацій. Зменшення кількості клітин до двох або до однієї приводить до створення ШНМ, яка не може правильно класифікувати всі навчальні приклади.

  1.  Підготовка вхідних даних.

Навчання НК полягає в наданні повчальних прикладів з невеликої групи бажаних дій. Потім слідує виконання алгоритму зворотного розповсюдження з урахуванням бажаного результату і дійсного результату. Дані для тестування є декількома сценаріями з набором умов (тем) і дій (поведінки та відповідей). Оскільки вимагається, щоб НК поводився так само, як справжня  людина, ми не навчатимемо його для кожного випадку. ШНМ повинна розраховувати реакцію на входи і виконувати дію, яка буде схожою на навчальні сценарії. Приклади, які використовуються для навчання мережі, представлені в Таблиці 1.

Таблиця 1. Приклади, які використовуються для навчання НК

В

И

С

О

Ц

Ь

К

И

Й

  1.  Навчальні приклади для нейроконтроллера.
  2.  

{ 1, 1, 1, 1, 1, 0,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 1, 1, 1, 1, 0,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 1, 1, 1, 1, 0,

{ 1, 0, 0, 0, 0, 0, 0, 0 }},

{ 1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 1, 1,

  1, 0, 0, 1, 0, 1,

  1, 0, 1, 0, 0, 1,

  1, 1, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

{ 0, 1, 0, 0, 0, 0, 0, 0 }},

{ 0, 1, 1, 1, 1, 0,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 0,

  1, 0, 0, 0, 0, 0,

  1, 0, 0, 0, 0, 0,

  1, 0, 0, 0, 0, 0,

  1, 0, 0, 0, 0, 1,

  0, 1, 1, 1, 1, 0,

{ 0, 0, 1, 0, 0, 0, 0, 0} },

{ 0, 1, 1, 1, 1, 0,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  0, 1, 1, 1, 1, 0,

{ 0, 0, 0, 1, 0, 0, 0, 0 }}, { 1, 0, 0, 0, 1, 0,

  1, 0, 0, 0, 1, 0,

  1, 0, 0, 0, 1, 0,

  1, 0, 0, 0, 1, 0,

  1, 0, 0, 0, 1, 0,

  1, 0, 0, 0, 1, 0,

  1, 1, 1, 1, 1, 1,

  0, 0, 0, 0, 0, 1,

{ 0, 0, 0, 0, 1, 0, 0, 0 }},

{ 1, 0, 0, 0, 0, 0,

  1, 0, 0, 0, 0, 0,

  1, 0, 0, 0, 0, 0,

  1, 1, 1, 1, 1, 0,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 1, 1, 1, 1, 0,

{ 0, 0, 0, 0, 0, 1, 0, 0 }}, { 1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 1, 0,

  1, 0, 0, 1, 0, 0,

  1, 0, 1, 0, 0, 0,

  1, 1, 1, 0, 0, 0,

  1, 0, 0, 1, 0, 0,

  1, 0, 0, 0, 1, 0,

  1, 0, 0, 0, 0, 1,

{ 0, 0, 0, 0, 0, 0, 1, 0 }},

{ 1, 0, 1, 1, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

  1, 0, 0, 0, 1, 1,

  1, 0, 0, 1, 0, 1,

  1, 0, 1, 0, 0, 1,

  1, 1, 0, 0, 0, 1,

  1, 0, 0, 0, 0, 1,

{ 0, 0, 0, 0, 0, 0, 0, 1 }}


  1.  Приклад роботи програми.

Дані, приведені в табл.1, були передані мережі в довільному порядку під час навчання за допомогою алгоритму зворотного розповсюдження. Графік зниження середньої помилки показаний на рис.4.

На рис.4(а) показано якісний характер залежності помилки ШНМ на етапах навчання і перевірки. Помилка залежить від кількості циклів навчання  ітерацій. Якщо припустити, що для людини один цикл навчання відповідає одному дню життя (навчання), то 36500 циклів відповідатиме періоду 100 рокам “життя” моделі ШНМ. Спочатку обидві помилки зменшуються. Це означає, що мережа коректно навчається на структурі даних вхідних сигналів. Проте якщо мережа є надмірно гнучкою (тобто володіє великою кількістю ступенів свободи), то помилка перевірки після деякого числа циклів навчання починає зростати. Це означає, що при навчанні ШНМ швидше враховує особливості, властиві конкретному набору даних, а не структурам даних, що представляють вхідні образи. Наприклад, дані можуть бути зашумлені, і мережа в цьому випадку узагальнює властивості шуму. Тоді говорять, що мережа "перевчилася". В зв'язку з цим виникає питання про правильність структури ШНМ. Якщо помилка перевірки зростає, то необхідно скоротити число нейронів прихованих шарів ШНМ. Разом з тим, якщо помилка зменшується, але залишається відносно великою до кінця процесу навчання, необхідно збільшити число нейронів прихованих шарів. Альтернативним варіантом є запам'ятовування ваги зв'язків, коли помилка перевірки досягає мінімуму, і видача цих коефіцієнтів ваги як рішення. В цьому випадку структура мережі не зміняється. Такий спосіб виявлення ситуації "перенавчання" називають ранньою зупинкою. Проте це не означає, що навчання необхідно припинити. Навчання слід продовжити, щоб переконатися в тому, що не є локальним мінімумом.

Рис.4.Графики зниження середньої похибки ШНМ в залежності від періоду навчання.

У більшості випадків ШНМ успішно проходить навчання на всіх представлених прикладах. При збільшенні кількості прихованих клітин, навчання проходить ідеально. Проте в цьому випадку для роботи НК потрібно набагато більше комп'ютерних ресурсів. Тому було вибрано три приховані клітини з декількома циклами навчання. Для навчання НК було виконано стільки ітерацій, скільки потрібно для отримання ідеального результату на підставі тестових даних.

Щоб протестувати НК, ШНМ були представлені нові приклади. Це дозволило визначити, як мережа реагуватиме на сценарії, про які їй нічого не відомо. Дані тести дають відповідь на питання, наскільки добре НК може генерувати і виконувати потрібні дії, реагуючи на непередбачену ситуацію.

Розглянемо код реалізації алгоритму зворотного розповсюдження для ШНМ, а також код, який виконує навчання і тестування НК.

  1.  Текст програми.

//------------------------------------------------------------------------------

#pragma argsused

#pragma hdrstop

#include <condefs.h>

#include <math.h>

#include <conio.h>

#include <iostream.h>

#include <stdio.h>

#include <string.h>

#include <fstream.h>

//------------------------------------------------------------------------------

#define INPUT_NEURONS  32

#define HIDDEN_NEURONS 20

#define OUTPUT_NEURONS 12

//------------------------------------------------------------------------------

/* Вхід прихованих осередків (із зсувом) */

double wih[INPUT_NEURONS + 1][HIDDEN_NEURONS];

/* Вхід вихідних осередків (із зсувом) */

double who[HIDDEN_NEURONS + 1][OUTPUT_NEURONS];

/* Активатори */

double inputs[INPUT_NEURONS];

double hidden[HIDDEN_NEURONS];

double target[OUTPUT_NEURONS];

double actual[OUTPUT_NEURONS];

/* Помилки */

double erro[OUTPUT_NEURONS];

double errh[HIDDEN_NEURONS];

#define LEARN_RATE  0.2   /* Коефіцієнт навчання */

#define RAND_WEIGHT ( (float)rand() / (float)RAND_MAX - 0.5 )

#define getSRandO   ( (float)rand() / (float)RAND_MAX )

#define getRand(x)  (int)( x * getSRand() )

#define sqr(x)      (x * x)

typedef struct {

   double podie_1;

   double podie_2;

   double podie_3;

   double podie_4;

   double podie_5;

   double podie_6;

   double podie_7;

   double podie_8;

   double podie_9;

   double podie_10;

   double podie_11;

   double podie_12;

   double podie_13;

   double podie_14;

   double podie_15;

   double podie_16;

   double podie_17;

   double podie_18;

   double podie_19;

   double podie_20;

   double podie_21;

   double podie_22;

   double podie_23;

   double podie_24;

   double podie_25;

   double podie_26;

   double podie_27;

   double podie_28;

   double podie_29;

   double podie_30;

   double podie_31;

   double podie_32;

   double podie_33;

   double podie_34;

   double podie_35;

   double podie_36;

   double podie_37;

   double podie_38;

   double podie_39;

   double podie_40;

   double podie_41;

   double podie_42;

   double podie_43;

   double podie_44;

   double podie_45;

   double podie_46;

   double podie_47;

   double podie_48;

   double out[OUTPUT_NEURONS];

} ELEMENT;

#define MAX_SAMPLES 14

/* база  знань */

ELEMENT samples[MAX_SAMPLES] = {

{ 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 1,

{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 1,

{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 1, 1,

 1, 0, 0, 1, 0, 1,

 1, 0, 1, 0, 0, 1,

 1, 1, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 0, 1, 1, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 1, 1,

 1, 0, 0, 1, 0, 1,

 1, 0, 1, 0, 0, 1,

 1, 1, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 1, 0, 0,

 1, 0, 1, 0, 0, 0,

 1, 1, 1, 0, 0, 0,

 1, 0, 0, 1, 0, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 0, 1,

{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}

},

{ 0, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 0, 1, 1, 1, 1, 0,

{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}

},

{ 0, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 1,

 0, 1, 1, 1, 1, 0,

{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}

},

{ 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 1, 1, 1, 1, 1,

 0, 0, 0, 0, 0, 1,

{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}

},

{ 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}

},

{ 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}

}};

char *strings[12] = {"B", "V", "E", "Y", "I", "K", "O", "R", "S", "C", "'", " "};

int main() {

   void assignRandomWeights(void);

   double sigmoid(double val);

   double sigmoidDerivative(double val);

   void feedForward();

   void backPropagate(void);

   int action(double *vector) ;

   double err;

   int i, sample = 0, iterations = 0;

   int sum = 0;

   ofstream outfile("result.dat");

   /* Ініціалізувати генератор випадкових чисел */

   srand(time(NULL));

   assignRandomWeights();

   /* Навчити мережу */

   while (1) {

       if (++sample == MAX_SAMPLES) sample = 0;

       inputs[0]  = samples[sample].podie_1;

       inputs[1]  = samples[sample].podie_2;

       inputs[2]  = samples[sample].podie_3;

       inputs[3]  = samples[sample].podie_4;

       inputs[4]  = samples[sample].podie_5;

       inputs[5]  = samples[sample].podie_6;

       inputs[6]  = samples[sample].podie_7;

       inputs[7]  = samples[sample].podie_8;

       inputs[8]  = samples[sample].podie_9;

       inputs[9]  = samples[sample].podie_10;

       inputs[10] = samples[sample].podie_11;

       inputs[11] = samples[sample].podie_12;

       inputs[12] = samples[sample].podie_13;

       inputs[13] = samples[sample].podie_14;

       inputs[14] = samples[sample].podie_15;

       inputs[15] = samples[sample].podie_16;

       inputs[16] = samples[sample].podie_17;

       inputs[17] = samples[sample].podie_18;

       inputs[18] = samples[sample].podie_19;

       inputs[19] = samples[sample].podie_20;

       inputs[20] = samples[sample].podie_21;

       inputs[21] = samples[sample].podie_22;

       inputs[22] = samples[sample].podie_23;

       inputs[23] = samples[sample].podie_24;

       inputs[24] = samples[sample].podie_25;

       inputs[25] = samples[sample].podie_26;

       inputs[26] = samples[sample].podie_27;

       inputs[27] = samples[sample].podie_28;

       inputs[28] = samples[sample].podie_29;

       inputs[29] = samples[sample].podie_30;

       inputs[30] = samples[sample].podie_31;

       inputs[31] = samples[sample].podie_32;

       inputs[32] = samples[sample].podie_33;

       inputs[33] = samples[sample].podie_34;

       inputs[34] = samples[sample].podie_35;

       inputs[35] = samples[sample].podie_36;

       inputs[36] = samples[sample].podie_37;

       inputs[37] = samples[sample].podie_38;

       inputs[38] = samples[sample].podie_39;

       inputs[39] = samples[sample].podie_40;

       inputs[40] = samples[sample].podie_41;

       inputs[41] = samples[sample].podie_42;

       inputs[42] = samples[sample].podie_43;

       inputs[43] = samples[sample].podie_44;

       inputs[44] = samples[sample].podie_45;

       inputs[45] = samples[sample].podie_46;

       inputs[46] = samples[sample].podie_47;

       inputs[47] = samples[sample].podie_48;

       target[0]  = samples[sample].out[0];

       target[1]  = samples[sample].out[1];

       target[2]  = samples[sample].out[2];

       target[3]  = samples[sample].out[3];

       target[4]  = samples[sample].out[4];

       target[5]  = samples[sample].out[5];

       target[6]  = samples[sample].out[6];

       target[7]  = samples[sample].out[7];

       target[8]  = samples[sample].out[8];

       target[9]  = samples[sample].out[9];

       target[10]  = samples[sample].out[10];

       target[11]  = samples[sample].out[11];

       feedForward();

       err = 0.0;

       for (i = 0; i < OUTPUT_NEURONS; i++) {

           err += sqr( (samples[sample].out[i] - actual[i]) );

       }

       err = 0.5 * err;

       outfile << err << endl;

       printf("ERROR = %g\n", err);

       if (iterations++ > 18000) {

           getch();

           break;

       }

       

       backPropagate();

   }

   /* Перевірити мережу */

   for (i = 0; i < MAX_SAMPLES; i++) {

       inputs[0]  = samples[i].podie_1;

       inputs[1]  = samples[i].podie_2;

       inputs[2]  = samples[i].podie_3;

       inputs[3]  = samples[i].podie_4;

       inputs[4]  = samples[i].podie_5;

       inputs[5]  = samples[i].podie_6;

       inputs[6]  = samples[i].podie_7;

       inputs[7]  = samples[i].podie_8;

       inputs[8]  = samples[i].podie_9;

       inputs[9]  = samples[i].podie_10;

       inputs[10] = samples[i].podie_11;

       inputs[11] = samples[i].podie_12;

       inputs[12] = samples[i].podie_13;

       inputs[13] = samples[i].podie_14;

       inputs[14] = samples[i].podie_15;

       inputs[15] = samples[i].podie_16;

       inputs[16] = samples[i].podie_17;

       inputs[17] = samples[i].podie_18;

       inputs[18] = samples[i].podie_19;

       inputs[19] = samples[i].podie_20;

       inputs[20] = samples[i].podie_21;

       inputs[21] = samples[i].podie_22;

       inputs[22] = samples[i].podie_23;

       inputs[23] = samples[i].podie_24;

       inputs[24] = samples[i].podie_25;

       inputs[25] = samples[i].podie_26;

       inputs[26] = samples[i].podie_27;

       inputs[27] = samples[i].podie_28;

       inputs[28] = samples[i].podie_29;

       inputs[29] = samples[i].podie_30;

       inputs[30] = samples[i].podie_31;

       inputs[31] = samples[i].podie_32;

       inputs[32] = samples[i].podie_33;

       inputs[33] = samples[i].podie_34;

       inputs[34] = samples[i].podie_35;

       inputs[35] = samples[i].podie_36;

       inputs[36] = samples[i].podie_37;

       inputs[37] = samples[i].podie_38;

       inputs[38] = samples[i].podie_39;

       inputs[39] = samples[i].podie_40;

       inputs[40] = samples[i].podie_41;

       inputs[41] = samples[i].podie_42;

       inputs[42] = samples[i].podie_43;

       inputs[43] = samples[i].podie_44;

       inputs[44] = samples[i].podie_45;

       inputs[45] = samples[i].podie_46;

       inputs[46] = samples[i].podie_47;

       inputs[47] = samples[i].podie_48;

       target[0]  = samples[i].out[0];

       target[1]  = samples[i].out[1];

       target[2]  = samples[i].out[2];

       target[3]  = samples[i].out[3];

       target[4]  = samples[i].out[4];

       target[5]  = samples[i].out[5];

       target[6]  = samples[i].out[6];

       target[7]  = samples[i].out[7];

       target[8]  = samples[i].out[8];

       target[9]  = samples[i].out[9];

       target[10]  = samples[i].out[10];

       target[11]  = samples[i].out[11];

       feedForward();

       if (action(actual) != action(target)) {

           cout << inputs[0] << " " << inputs[1] << " " << inputs[2] << " " << inputs[3];

           cout << strings[action(actual)] << " " << strings[action(target)];

           cout << endl;

       } else {

           sum++;

       }

   }

   printf("\nNetwork is %g%% correct\n\n", ((float)sum / (float)MAX_SAMPLES) * 100);

   /* Виконання тестів - BOBER */

   //------------------------------------Б-------------------------------------

   inputs[0]  = 1; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 0;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 1; inputs[20] = 1; inputs[21] = 1; inputs[22] = 1; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------О-------------------------------------

   inputs[0]  = 0; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 0; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 0; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------Б-------------------------------------

   inputs[0]  = 1; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 0;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 1; inputs[20] = 1; inputs[21] = 1; inputs[22] = 1; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------Е-------------------------------------

   inputs[0]  = 1; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 0;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 1; inputs[20] = 1; inputs[21] = 1; inputs[22] = 1; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 0;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 0;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 0;

   inputs[42] = 1; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 1;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------Р-------------------------------------

   inputs[0]  = 1; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 0; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 1; inputs[26] = 1; inputs[27] = 1; inputs[28] = 1; inputs[29] = 0;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 0;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 0;

   inputs[42] = 1; inputs[43] = 0; inputs[44] = 0; inputs[45] = 0; inputs[46] = 0; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   printf(" means BOBER\n");

   /* Виконання тестів - VYSOC'KYI */

   //------------------------------------В-------------------------------------

   inputs[0]  = 1; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 1; inputs[20] = 1; inputs[21] = 1; inputs[22] = 1; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------И-------------------------------------

   inputs[0]  = 1; inputs[1]  = 0; inputs[2]  = 0; inputs[3]  = 0; inputs[4]  = 0; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 1; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 1; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 1; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 1; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 0; inputs[44] = 0; inputs[45] = 0; inputs[46] = 0; inputs[47] = 1;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------С-------------------------------------

   inputs[0]  = 0; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 0; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 0;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 0;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 0; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------О-------------------------------------

   inputs[0]  = 0; inputs[1]  = 1; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 1; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 0; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 0; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------Ц-------------------------------------

   inputs[0]  = 1; inputs[1]  = 0; inputs[2]  = 0; inputs[3]  = 0; inputs[4]  = 1; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 1; inputs[11] = 0;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 1; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 1; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 1; inputs[29] = 0;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 1; inputs[35] = 0;

   inputs[36] = 1; inputs[37] = 1; inputs[38] = 1; inputs[39] = 1; inputs[40] = 1; inputs[41] = 1;

   inputs[42] = 0; inputs[43] = 0; inputs[44] = 0; inputs[45] = 0; inputs[46] = 0; inputs[47] = 1;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------Ь-------------------------------------

   inputs[0]  = 1; inputs[1]  = 0; inputs[2]  = 0; inputs[3]  = 0; inputs[4]  = 0; inputs[5]  = 0;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 0;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 1; inputs[20] = 1; inputs[21] = 1; inputs[22] = 1; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 0; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 1; inputs[44] = 1; inputs[45] = 1; inputs[46] = 1; inputs[47] = 0;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------К-------------------------------------

   inputs[0]  = 1; inputs[1]  = 0; inputs[2]  = 0; inputs[3]  = 0; inputs[4]  = 0; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 1; inputs[11] = 0;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 1; inputs[16] = 0; inputs[17] = 0;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 1; inputs[21] = 0; inputs[22] = 0; inputs[23] = 0;

   inputs[24] = 1; inputs[25] = 1; inputs[26] = 1; inputs[27] = 0; inputs[28] = 0; inputs[29] = 0;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 0; inputs[33] = 1; inputs[34] = 0; inputs[35] = 0;

   inputs[36] = 1; inputs[37] = 0; inputs[38] = 0; inputs[39] = 0; inputs[40] = 1; inputs[41] = 0;

   inputs[42] = 1; inputs[43] = 0; inputs[44] = 0; inputs[45] = 0; inputs[46] = 0; inputs[47] = 1;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------И-------------------------------------

   inputs[0]  = 1; inputs[1]  = 0; inputs[2]  = 0; inputs[3]  = 0; inputs[4]  = 0; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 1; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 1; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 1; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 1; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 0; inputs[44] = 0; inputs[45] = 0; inputs[46] = 0; inputs[47] = 1;

   feedForward();

   printf("%s", strings[action(actual)]);

   //------------------------------------Й-------------------------------------

   inputs[0]  = 1; inputs[1]  = 0; inputs[2]  = 1; inputs[3]  = 1; inputs[4]  = 0; inputs[5]  = 1;

   inputs[6]  = 1; inputs[7]  = 0; inputs[8]  = 0; inputs[9]  = 0; inputs[10] = 0; inputs[11] = 1;

   inputs[12] = 1; inputs[13] = 0; inputs[14] = 0; inputs[15] = 0; inputs[16] = 0; inputs[17] = 1;

   inputs[18] = 1; inputs[19] = 0; inputs[20] = 0; inputs[21] = 0; inputs[22] = 1; inputs[23] = 1;

   inputs[24] = 1; inputs[25] = 0; inputs[26] = 0; inputs[27] = 1; inputs[28] = 0; inputs[29] = 1;

   inputs[30] = 1; inputs[31] = 0; inputs[32] = 1; inputs[33] = 0; inputs[34] = 0; inputs[35] = 1;

   inputs[36] = 1; inputs[37] = 1; inputs[38] = 0; inputs[39] = 0; inputs[40] = 0; inputs[41] = 1;

   inputs[42] = 1; inputs[43] = 0; inputs[44] = 0; inputs[45] = 0; inputs[46] = 0; inputs[47] = 1;

   feedForward();

   printf("%s", strings[action(actual)]);

   printf(" means VYSOC'KYI");

   //--------------------------------------------------------------------------

   outfile.close();

   getch();

   return 0;

}

//------------------------------------------------------------------------------

void assignRandomWeights(void) {

   int  hid, inp, out;

   for (inp = 0; inp < INPUT_NEURONS + 1; inp++) {

       for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

           wih[inp][hid] = RAND_WEIGHT;

       }

   }

   for (hid = 0; hid < HIDDEN_NEURONS + 1; hid++) {

       for (out = 0; out < OUTPUT_NEURONS; out++) {

           who[hid][out] = RAND_WEIGHT;

       }

   }

}

//------------------------------------------------------------------------------

double sigmoid(double val) {

   return (1.0 / (1.0 + exp(-val)));

}

//------------------------------------------------------------------------------

double sigmoidDerivative(double val) {

   return (val * (1.0 - val));

}

//------------------------------------------------------------------------------

void feedForward() {

   int inp, hid, out;

   double sum;

   /* Обчислити вхід в прихований шар */

   for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

       sum = 0.0;

       for (inp = 0; inp < INPUT_NEURONS; inp++) {

           sum += inputs[inp] * wih[inp][hid];

       }

       /* Додати зсув */

       sum += wih[INPUT_NEURONS][hid];

       hidden[hid] = sigmoid(sum);

   }

   /* Обчислити вхід у вихідний шар */

   for (out = 0; out < OUTPUT_NEURONS; out++) {

       sum = 0.0;

       for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

           sum += hidden[hid] * who[hid][out];

       }

       /* Додати зсув */

       sum += who[HIDDEN_NEURONS][out];

       actual[out] = sigmoid( sum );

   }

}

//------------------------------------------------------------------------------

void backPropagate(void)  {

   int inp, hid, out;

   /* Обчислити помилку вихідного шару (крок 3 для вихідних осередків) */

   for (out = 0; out < OUTPUT_NEURONS; out++) {

       erro[out] = (target[out] - actual[out]) * sigmoidDerivative(actual[out]);

   }

   /* Обчислити помилку прихованого шару (крок 3 для прихованого шару) */

   for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

       errh[hid] = 0.0;

       for (out = 0; out < OUTPUT_NEURONS; out++) {

           errh[hid] += erro[out] * who[hid][out];

       }

       errh[hid] *= sigmoidDerivative(hidden[hid]);

   }

   /* Відновити вагу для вихідного шару (крок 4 для вихідних осередків) */

   for (out = 0; out < OUTPUT_NEURONS; out++) {

       for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

           who[hid][out] += (LEARN_RATE * erro[out] * hidden[hid]);

       }

       /* Відновити зсув */

       who[HIDDEN_NEURONS][out] += (LEARN_RATE * erro[out]);

   }

   /* Відновити вагу для прихованого шару (крок 4 для прихованого шару) */

   for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

       for (inp = 0; inp < INPUT_NEURONS; inp++) {

           wih[inp][hid] += (LEARN_RATE * errh[hid] * inputs[inp]);

       }

       /* Відновити зсув */

       wih[INPUT_NEURONS][hid] += (LEARN_RATE * errh[hid]);

   }

}

//------------------------------------------------------------------------------

int action(double *vector) {

   int index, sel;

   double max;

   sel = 0;

   max = vector[sel];

   for (index = 1; index < OUTPUT_NEURONS; index++) {

       if (vector[index] > max) {

           max = vector[index]; sel = index;

       }

   }

   return(sel);

}

//------------------------------------------------------------------------------

ага визначається як вага з'єднань між вхідним і прихованим (wih), а також між прихованим і вихідним шарами (who). Вага з'єднання є вагою входу в прихований шар, представлений wih[0][0]. Вага зсуву займає останній рядок в кожній таблиці і ідентифікується за допомогою значення +1 в масивах wih і who. Значення сигналів зберігаються в чотирьох масивах. Масив inputs визначає значення вхідних клітин, масив hidden містить вихід для прихованих клітин, масив target надає бажане значення мережі для заданих входів, а масив асtual відображає реальний результат роботи мережі. Помилки мережі надаються в двох масивах. Масив еrrо береже помилку для кожного вхідного клітина. Масив errh містить помилки прихованих клітини.

Щоб знайти довільну вагу для ініціалізації мережі, створюється група макросів: RAND_WEIGHT ;     getSRandO)  ; getRand(x) ; sqr(x).

Вага довільно вибирається в діапазоні від -0,5 до 0,5. Коефіцієнт навчання задається як 0,2. Діапазон ваг і коефіцієнт навчання можуть бути змінені залежно від проблеми і необхідної точності рішення.

Існують три допоміжні функції, які використовуються, щоб задавати довільну вагу для мережі, а також для роботи алгоритму. Функція assignRandomWeights довільно задає вагу для всіх з'єднань мережі (включаючи всі зсуви). Функція sigmoid визначає значення функції стиснення (сигмоїда), яка використовується при прямому обчисленні ваг. Функція sigmoidDerivative встановлює значення похідної функції sigmoid і використовується при зворотному розповсюдженні помилки. Функція  feedForward реалізує фазу прямого обчислення алгоритму . Алгоритм прямого розповсюдження починає свою роботу з розрахунку активації для прихованих шарів з урахуванням входів з вхідного шару. Зсув додається в клітину до обчислення функції сигмоїда. Потім аналогічним чином розраховується вихідний шар. Мережа може мати одну або декілька вихідних клітин. Тому обробка вихідних клітин розміщена в циклі, щоб розрахувати всі необхідні активації на виході.

Спочатку розраховується помилка вихідної клітини з використанням дійсного і бажаного результатів. Далі визначаються помилки для прихованих клітин. Нарешті, обновлюється вага для всіх з'єднань залежно від того, знаходяться вони у вхідному або вихідному прихованому шарі. Тут важливо відзначити, що в алгоритмі не розраховується вага для зсуву, а просто застосовується помилка до самого зсуву. В алгоритмі прямого розповсюдження зсув додається без використання для нього ваги. Даний алгоритм дозволяє розрахувати вихід багатошарової ШНМ і її зміни за допомогою алгоритму зворотного розповсюдження. Задачею структури ELEMENT samples[MAX_SAMPLES]   є відображення прикладів для навчання. Структура задає входи {Подія 1 ... 4 } , а також значення бажаного результату  {  Відповідь 1 ... 4 }.

Оскільки мережа побудована за принципом «переможець одержує все», функція int асtion()  визначає вихідну клітину з найбільшою сумою ваг. Вона виконує  пошук по вектору максимального значення і повертає рядок, який відображає потрібну дію. Повернене значення потім може використовуватись як індекс в масиві рядків strings і дозволяє вивести текст, що показує реакцію ШНМ.

Після ініціалізації генератора випадкових чисел за допомогою функції srand довільно генеруються ваги з'єднань мережі. Потім для навчання мережі виконується цикл while. Приклади розглядаються послідовно, а не в довільному порядку. Виконується розрахунок реакції мережі на вхідний вектор, а потім - перевірка середньої помилки. Запускається алгоритм зворотного розповсюдження, щоб змінити вагу з'єднань мережі. Після виконання ряду ітерацій програма виходить з циклу і мережа тестується на точність на основі значень, заданих для навчання. Після стандартного тестування виконується тестування мережі з прикладами, які не входили до початкової групи при навчанні. Ваги можуть бути виведені у файл для подальшого використання. На цьому етапі мережу можна оптимізувати, щоб зменшити кількість ресурсів, необхідних для розрахунків.

Коли НК пройшов навчання його можна використовувати для роботи із  студентом. В ШНМ може бути сформована функція пам'яті. Для всіх входів створюються лінії затримки (при цьому вхідний вектор розширяється в одному або двох вимірюваннях). Перший вхід від навколишнього середовища не зникає, а стає частиною іншого входу в мережу. Дана функція може бути виконана для декількох елементів, що дозволяє запрограмувати для мережі деяку пам'ять, а також багато інших можливостей, що властиві розумним істотам.

Цей метод також включає зворотний зв'язок. Останні дії можуть прямувати в мережу, що дозволяє НК  пам'ятати про них. Додатковий зворотний зв'язок може включати інформацію про оточення  студента, а також його емоційний стан. Дані механізми сприяють генерації складних дій, схожих на вчинки людини.

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

КИЇВСЬКИЙ НАЦІОНАЛЬНИЙ ЕКОНОМІЧНИЙ УНІВЕРСИТЕТ

імені ВАДИМА ГЕТЬМАНА

Лабоpатоpна pобота № 1-2

Тема: „Розробка графічного інтерфейсу для програми розпізнавання образів”

Виконав: студент

 Висоцький Максим  Вікторович

1 група, 5 курс,

спеціальність 8404

Перевірив: викладач

Доц.  Іванченко Г. Ф.

КИЇВ 2010


  1.  Головна форма в режимі конструктора.

  1.  Головне вікно програми.
  2.  

  1.  Подання результатів роботи програми.

  1.  


Текст програми.

//------------------------------------------------------------------------------

#include <vcl.h>

#pragma argsused

#pragma hdrstop

#include <condefs.h>

#include <math.h>

#include <conio.h>

#include <iostream.h>

#include <stdio.h>

#include <string.h>

#include <fstream.h>

//------------------------------------------------------------------------------

#define INPUT_NEURONS  32

#define HIDDEN_NEURONS 20

#define OUTPUT_NEURONS 12

//------------------------------------------------------------------------------

#include "Unit1.h"

//------------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

int pixels[9][8][6];

/* Вхід прихованих осередків (із зсувом) */

double wih[INPUT_NEURONS + 1][HIDDEN_NEURONS];

/* Вхід вихідних осередків (із зсувом) */

double who[HIDDEN_NEURONS + 1][OUTPUT_NEURONS];

/* Активатори */

double inputs[INPUT_NEURONS];

double hidden[HIDDEN_NEURONS];

double target[OUTPUT_NEURONS];

double actual[OUTPUT_NEURONS];

/* Помилки */

double erro[OUTPUT_NEURONS];

double errh[HIDDEN_NEURONS];

#define LEARN_RATE  0.2   /* Коефіцієнт навчання */

#define RAND_WEIGHT ( (float)rand() / (float)RAND_MAX - 0.5 )

#define getSRandO   ( (float)rand() / (float)RAND_MAX )

#define getRand(x)  (int)( x * getSRand() )

#define sqr(x)      (x * x)

typedef struct {

   double podie_1;

   double podie_2;

   double podie_3;

   double podie_4;

   double podie_5;

   double podie_6;

   double podie_7;

   double podie_8;

   double podie_9;

   double podie_10;

   double podie_11;

   double podie_12;

   double podie_13;

   double podie_14;

   double podie_15;

   double podie_16;

   double podie_17;

   double podie_18;

   double podie_19;

   double podie_20;

   double podie_21;

   double podie_22;

   double podie_23;

   double podie_24;

   double podie_25;

   double podie_26;

   double podie_27;

   double podie_28;

   double podie_29;

   double podie_30;

   double podie_31;

   double podie_32;

   double podie_33;

   double podie_34;

   double podie_35;

   double podie_36;

   double podie_37;

   double podie_38;

   double podie_39;

   double podie_40;

   double podie_41;

   double podie_42;

   double podie_43;

   double podie_44;

   double podie_45;

   double podie_46;

   double podie_47;

   double podie_48;

   double out[OUTPUT_NEURONS];

} ELEMENT;

#define MAX_SAMPLES 14

/* база  знань */

ELEMENT samples[MAX_SAMPLES] = {

{ 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

{1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

{0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 1,

{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 1,

{0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 1, 1,

 1, 0, 0, 1, 0, 1,

 1, 0, 1, 0, 0, 1,

 1, 1, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

{0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 0, 1, 1, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 1, 1,

 1, 0, 0, 1, 0, 1,

 1, 0, 1, 0, 0, 1,

 1, 1, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

{0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}

},

{ 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 1, 0, 0,

 1, 0, 1, 0, 0, 0,

 1, 1, 1, 0, 0, 0,

 1, 0, 0, 1, 0, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 0, 1,

{0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}

},

{ 0, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 0, 1, 1, 1, 1, 0,

{0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}

},

{ 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

{0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0}

},

{ 0, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 1,

 0, 1, 1, 1, 1, 0,

{0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}

},

{ 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 0, 0, 0, 1, 0,

 1, 1, 1, 1, 1, 1,

 0, 0, 0, 0, 0, 1,

{0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}

},

{ 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 0, 0, 0, 0, 0,

 1, 1, 1, 1, 1, 0,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 0, 0, 0, 0, 1,

 1, 1, 1, 1, 1, 0,

{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0}

},

{ 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

 0, 0, 0, 0, 0, 0,

{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}

}};

char *strings[12] = {"Б", "В", "Е", "И", "Й", "К", "О", "Р", "С", "Ц", "Ь", " "};

//------------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

   : TForm(Owner)

{

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid1DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[0][Row][Col] == 0) {

           StringGrid1->Canvas->Brush->Color = clBlack;

           pixels[0][Row][Col] = 1;

       } else {

           StringGrid1->Canvas->Brush->Color = clWindow;

           pixels[0][Row][Col] = 0;

       }

       StringGrid1->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid2DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[1][Row][Col] == 0) {

           StringGrid2->Canvas->Brush->Color = clBlack;

           pixels[1][Row][Col] = 1;

       } else {

           StringGrid2->Canvas->Brush->Color = clWindow;

           pixels[1][Row][Col] = 0;

       }

       StringGrid2->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid3DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[2][Row][Col] == 0) {

           StringGrid3->Canvas->Brush->Color = clBlack;

           pixels[2][Row][Col] = 1;

       } else {

           StringGrid3->Canvas->Brush->Color = clWindow;

           pixels[2][Row][Col] = 0;

       }

       StringGrid3->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid4DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[3][Row][Col] == 0) {

           StringGrid4->Canvas->Brush->Color = clBlack;

           pixels[3][Row][Col] = 1;

       } else {

           StringGrid4->Canvas->Brush->Color = clWindow;

           pixels[3][Row][Col] = 0;

       }

       StringGrid4->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid5DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[4][Row][Col] == 0) {

           StringGrid5->Canvas->Brush->Color = clBlack;

           pixels[4][Row][Col] = 1;

       } else {

           StringGrid5->Canvas->Brush->Color = clWindow;

           pixels[4][Row][Col] = 0;

       }

       StringGrid5->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid6DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[5][Row][Col] == 0) {

           StringGrid6->Canvas->Brush->Color = clBlack;

           pixels[5][Row][Col] = 1;

       } else {

           StringGrid6->Canvas->Brush->Color = clWindow;

           pixels[5][Row][Col] = 0;

       }

       StringGrid6->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid7DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[6][Row][Col] == 0) {

           StringGrid7->Canvas->Brush->Color = clBlack;

           pixels[6][Row][Col] = 1;

       } else {

           StringGrid7->Canvas->Brush->Color = clWindow;

           pixels[6][Row][Col] = 0;

       }

       StringGrid7->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid8DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[7][Row][Col] == 0) {

           StringGrid8->Canvas->Brush->Color = clBlack;

           pixels[7][Row][Col] = 1;

       } else {

           StringGrid8->Canvas->Brush->Color = clWindow;

           pixels[7][Row][Col] = 0;

       }

       StringGrid8->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::StringGrid9DrawCell(TObject *Sender, int Col,

     int Row, TRect &Rect, TGridDrawState State) {

   if (State.Contains(gdFocused)) {

       if (pixels[8][Row][Col] == 0) {

           StringGrid9->Canvas->Brush->Color = clBlack;

           pixels[8][Row][Col] = 1;

       } else {

           StringGrid9->Canvas->Brush->Color = clWindow;

           pixels[8][Row][Col] = 0;

       }

       StringGrid9->Canvas->FillRect(Rect);

   }

}

//------------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender) {

   void assignRandomWeights(void);

   double sigmoid(double val);

   double sigmoidDerivative(double val);

   void feedForward();

   void backPropagate(void);

   int action(double *vector) ;

   double err;

   char s[250];

   int i, k, sample = 0, iterations = 0;

   int sum = 0;

   ofstream outfile("result.dat");

   /* Ініціалізувати генератор випадкових чисел */

   srand(time(NULL));

   assignRandomWeights();

   /* Навчити мережу */

   while (1) {

       if (++sample == MAX_SAMPLES) sample = 0;

       inputs[0]  = samples[sample].podie_1;

       inputs[1]  = samples[sample].podie_2;

       inputs[2]  = samples[sample].podie_3;

       inputs[3]  = samples[sample].podie_4;

       inputs[4]  = samples[sample].podie_5;

       inputs[5]  = samples[sample].podie_6;

       inputs[6]  = samples[sample].podie_7;

       inputs[7]  = samples[sample].podie_8;

       inputs[8]  = samples[sample].podie_9;

       inputs[9]  = samples[sample].podie_10;

       inputs[10] = samples[sample].podie_11;

       inputs[11] = samples[sample].podie_12;

       inputs[12] = samples[sample].podie_13;

       inputs[13] = samples[sample].podie_14;

       inputs[14] = samples[sample].podie_15;

       inputs[15] = samples[sample].podie_16;

       inputs[16] = samples[sample].podie_17;

       inputs[17] = samples[sample].podie_18;

       inputs[18] = samples[sample].podie_19;

       inputs[19] = samples[sample].podie_20;

       inputs[20] = samples[sample].podie_21;

       inputs[21] = samples[sample].podie_22;

       inputs[22] = samples[sample].podie_23;

       inputs[23] = samples[sample].podie_24;

       inputs[24] = samples[sample].podie_25;

       inputs[25] = samples[sample].podie_26;

       inputs[26] = samples[sample].podie_27;

       inputs[27] = samples[sample].podie_28;

       inputs[28] = samples[sample].podie_29;

       inputs[29] = samples[sample].podie_30;

       inputs[30] = samples[sample].podie_31;

       inputs[31] = samples[sample].podie_32;

       inputs[32] = samples[sample].podie_33;

       inputs[33] = samples[sample].podie_34;

       inputs[34] = samples[sample].podie_35;

       inputs[35] = samples[sample].podie_36;

       inputs[36] = samples[sample].podie_37;

       inputs[37] = samples[sample].podie_38;

       inputs[38] = samples[sample].podie_39;

       inputs[39] = samples[sample].podie_40;

       inputs[40] = samples[sample].podie_41;

       inputs[41] = samples[sample].podie_42;

       inputs[42] = samples[sample].podie_43;

       inputs[43] = samples[sample].podie_44;

       inputs[44] = samples[sample].podie_45;

       inputs[45] = samples[sample].podie_46;

       inputs[46] = samples[sample].podie_47;

       inputs[47] = samples[sample].podie_48;

       target[0]  = samples[sample].out[0];

       target[1]  = samples[sample].out[1];

       target[2]  = samples[sample].out[2];

       target[3]  = samples[sample].out[3];

       target[4]  = samples[sample].out[4];

       target[5]  = samples[sample].out[5];

       target[6]  = samples[sample].out[6];

       target[7]  = samples[sample].out[7];

       target[8]  = samples[sample].out[8];

       target[9]  = samples[sample].out[9];

       target[10]  = samples[sample].out[10];

       target[11]  = samples[sample].out[11];

       feedForward();

       err = 0.0;

       for (i = 0; i < OUTPUT_NEURONS; i++) {

           err += sqr( (samples[sample].out[i] - actual[i]) );

       }

       err = 0.5 * err;

       outfile << err << endl;

       if (iterations++ > 18000) {

           getch();

           break;

       }

       

       backPropagate();

   }

   /* Перевірити мережу */

   for (i = 0; i < MAX_SAMPLES; i++) {

       inputs[0]  = samples[i].podie_1;

       inputs[1]  = samples[i].podie_2;

       inputs[2]  = samples[i].podie_3;

       inputs[3]  = samples[i].podie_4;

       inputs[4]  = samples[i].podie_5;

       inputs[5]  = samples[i].podie_6;

       inputs[6]  = samples[i].podie_7;

       inputs[7]  = samples[i].podie_8;

       inputs[8]  = samples[i].podie_9;

       inputs[9]  = samples[i].podie_10;

       inputs[10] = samples[i].podie_11;

       inputs[11] = samples[i].podie_12;

       inputs[12] = samples[i].podie_13;

       inputs[13] = samples[i].podie_14;

       inputs[14] = samples[i].podie_15;

       inputs[15] = samples[i].podie_16;

       inputs[16] = samples[i].podie_17;

       inputs[17] = samples[i].podie_18;

       inputs[18] = samples[i].podie_19;

       inputs[19] = samples[i].podie_20;

       inputs[20] = samples[i].podie_21;

       inputs[21] = samples[i].podie_22;

       inputs[22] = samples[i].podie_23;

       inputs[23] = samples[i].podie_24;

       inputs[24] = samples[i].podie_25;

       inputs[25] = samples[i].podie_26;

       inputs[26] = samples[i].podie_27;

       inputs[27] = samples[i].podie_28;

       inputs[28] = samples[i].podie_29;

       inputs[29] = samples[i].podie_30;

       inputs[30] = samples[i].podie_31;

       inputs[31] = samples[i].podie_32;

       inputs[32] = samples[i].podie_33;

       inputs[33] = samples[i].podie_34;

       inputs[34] = samples[i].podie_35;

       inputs[35] = samples[i].podie_36;

       inputs[36] = samples[i].podie_37;

       inputs[37] = samples[i].podie_38;

       inputs[38] = samples[i].podie_39;

       inputs[39] = samples[i].podie_40;

       inputs[40] = samples[i].podie_41;

       inputs[41] = samples[i].podie_42;

       inputs[42] = samples[i].podie_43;

       inputs[43] = samples[i].podie_44;

       inputs[44] = samples[i].podie_45;

       inputs[45] = samples[i].podie_46;

       inputs[46] = samples[i].podie_47;

       inputs[47] = samples[i].podie_48;

       target[0]  = samples[i].out[0];

       target[1]  = samples[i].out[1];

       target[2]  = samples[i].out[2];

       target[3]  = samples[i].out[3];

       target[4]  = samples[i].out[4];

       target[5]  = samples[i].out[5];

       target[6]  = samples[i].out[6];

       target[7]  = samples[i].out[7];

       target[8]  = samples[i].out[8];

       target[9]  = samples[i].out[9];

       target[10]  = samples[i].out[10];

       target[11]  = samples[i].out[11];

       feedForward();

       if (action(actual) == action(target)) {

           sum++;

       }

   }

   sprintf(s, "%g%%", ((float)sum / (float)MAX_SAMPLES) * 100);

   Label1->Caption = s;

   /* Виконання тестів */

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid1->RowCount; i++) {

       for(int j = 0; j < StringGrid1->ColCount; j++) {

           inputs[k] = pixels[0][i][j];

           k++;

       }

   }

   feedForward();

   Edit1->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid2->RowCount; i++) {

       for(int j = 0; j < StringGrid2->ColCount; j++) {

           inputs[k] = pixels[1][i][j];

           k++;

       }

   }

   feedForward();

   Edit2->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid3->RowCount; i++) {

       for(int j = 0; j < StringGrid3->ColCount; j++) {

           inputs[k] = pixels[2][i][j];

           k++;

       }

   }

   feedForward();

   Edit3->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid4->RowCount; i++) {

       for(int j = 0; j < StringGrid4->ColCount; j++) {

           inputs[k] = pixels[3][i][j];

           k++;

       }

   }

   feedForward();

   Edit4->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid5->RowCount; i++) {

       for(int j = 0; j < StringGrid5->ColCount; j++) {

           inputs[k] = pixels[4][i][j];

           k++;

       }

   }

   feedForward();

   Edit5->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid6->RowCount; i++) {

       for(int j = 0; j < StringGrid6->ColCount; j++) {

           inputs[k] = pixels[5][i][j];

           k++;

       }

   }

   feedForward();

   Edit6->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid7->RowCount; i++) {

       for(int j = 0; j < StringGrid7->ColCount; j++) {

           inputs[k] = pixels[6][i][j];

           k++;

       }

   }

   feedForward();

   Edit7->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid8->RowCount; i++) {

       for(int j = 0; j < StringGrid8->ColCount; j++) {

           inputs[k] = pixels[7][i][j];

           k++;

       }

   }

   feedForward();

   Edit8->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   k = 0;

   for(int i = 0; i < StringGrid9->RowCount; i++) {

       for(int j = 0; j < StringGrid9->ColCount; j++) {

           inputs[k] = pixels[8][i][j];

           k++;

       }

   }

   feedForward();

   Edit9->Text = strings[action(actual)];

   //--------------------------------------------------------------------------

   getch();

   outfile.close();

   TStringList* List;

   int ListCount;

   List = new TStringList;

   List->LoadFromFile("result.dat");

   ListCount = List->Count;

   Chart1->Series[0]->Clear();

   for (int i = 0; i < ListCount; i = i + 18)

   {

       Chart1->Series[0]->Add(StrToFloat(StringReplace(List->Strings[i], ".", ",",

       TReplaceFlags() << rfReplaceAll)),i,clRed);

   }

}

//------------------------------------------------------------------------------

void assignRandomWeights(void) {

   int  hid, inp, out;

   for (inp = 0; inp < INPUT_NEURONS + 1; inp++) {

       for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

           wih[inp][hid] = RAND_WEIGHT;

       }

   }

   for (hid = 0; hid < HIDDEN_NEURONS + 1; hid++) {

       for (out = 0; out < OUTPUT_NEURONS; out++) {

           who[hid][out] = RAND_WEIGHT;

       }

   }

}

//------------------------------------------------------------------------------

double sigmoid(double val) {

   return (1.0 / (1.0 + exp(-val)));

}

//------------------------------------------------------------------------------

double sigmoidDerivative(double val) {

   return (val * (1.0 - val));

}

//------------------------------------------------------------------------------

void feedForward() {

   int inp, hid, out;

   double sum;

   /* Обчислити вхід в прихований шар */

   for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

       sum = 0.0;

       for (inp = 0; inp < INPUT_NEURONS; inp++) {

           sum += inputs[inp] * wih[inp][hid];

       }

       /* Додати зсув */

       sum += wih[INPUT_NEURONS][hid];

       hidden[hid] = sigmoid(sum);

   }

   /* Обчислити вхід у вихідний шар */

   for (out = 0; out < OUTPUT_NEURONS; out++) {

       sum = 0.0;

       for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

           sum += hidden[hid] * who[hid][out];

       }

       /* Додати зсув */

       sum += who[HIDDEN_NEURONS][out];

       actual[out] = sigmoid( sum );

   }

}

//------------------------------------------------------------------------------

void backPropagate(void)  {

   int inp, hid, out;

   /* Обчислити помилку вихідного шару (крок 3 для вихідних осередків) */

   for (out = 0; out < OUTPUT_NEURONS; out++) {

       erro[out] = (target[out] - actual[out]) * sigmoidDerivative(actual[out]);

   }

   /* Обчислити помилку прихованого шару (крок 3 для прихованого шару) */

   for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

       errh[hid] = 0.0;

       for (out = 0; out < OUTPUT_NEURONS; out++) {

           errh[hid] += erro[out] * who[hid][out];

       }

       errh[hid] *= sigmoidDerivative(hidden[hid]);

   }

   /* Відновити вагу для вихідного шару (крок 4 для вихідних осередків) */

   for (out = 0; out < OUTPUT_NEURONS; out++) {

       for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

           who[hid][out] += (LEARN_RATE * erro[out] * hidden[hid]);

       }

       /* Відновити зсув */

       who[HIDDEN_NEURONS][out] += (LEARN_RATE * erro[out]);

   }

   /* Відновити вагу для прихованого шару (крок 4 для прихованого шару) */

   for (hid = 0; hid < HIDDEN_NEURONS; hid++) {

       for (inp = 0; inp < INPUT_NEURONS; inp++) {

           wih[inp][hid] += (LEARN_RATE * errh[hid] * inputs[inp]);

       }

       /* Відновити зсув */

       wih[INPUT_NEURONS][hid] += (LEARN_RATE * errh[hid]);

   }

}

//------------------------------------------------------------------------------

int action(double *vector) {

   int index, sel;

   double max;

   sel = 0;

   max = vector[sel];

   for (index = 1; index < OUTPUT_NEURONS; index++) {

       if (vector[index] > max) {

           max = vector[index]; sel = index;

       }

   }

   return(sel);

}

//------------------------------------------------------------------------------

Література

1.Хьюбел Д. Око, мозок, зір. Пер. з англ. - М.: Мир, 1990. -239с.

2.Бондарев В.Н., Аді Ф.Г. Штучний інтелект. Навчальний посібник для вузів. -Севастополь, Вид-во СевНТУ, 2002. -615 з.

3.Штучний інтелект. Довідник. - В 3-х томах. - М.: Радіо і зв'язок, 1990.

4.Уинстон П. Штучний інтелект. - М.:Мир, 1980. - 520 з.


 

А также другие работы, которые могут Вас заинтересовать

80480. Запис і читання трицифрових чисел. Випадки додавання й віднімання трицифрових чисел, пов’язаних з нумерацією 1.31 MB
  Мета: формувати вміння читати і записувати трицифрові числа в нумераційну таблицю, закріпити додавання і віднімання розрядних чисел та додавання і віднімання одиниці, вдосконалювати вміння розв’язувати складені задачі на «зменшення», «збільшення» на кілька одиниць, задач геометричного змісту...
80481. СУСПІЛЬНО-ПОЛІТИЧНИЙ ЛАД І ПРАВО УКРАЇНИ ПІСЛЯ ПЕРЕМОГИ ЛЮТНЕВОЇ ДЕМОКРАТИЧНОЇ РЕВОЛЮЦІЇ (лютий—жовтень 1917 р.) 38.27 KB
  Тимчасовий уряд та його органи в Україні. Законодавство Тимчасового уряд. За згодою між лідерами Тимчасового комітету і керівництвом Петроградської Ради робітничих і солдатських депутатів був утворений Тимчасовий уряд. Через кризи прорахунки та помилки коаліційний Тимчасовий уряд представлений кадетами народними соціалістами меншовиками та есерами вів країну до Установчих зборів котрі як він сподівався мали розвязати кардинальні питання її нового буття.
80482. УКРАЇНСЬКІ ЗЕМЛІ ПІД ВЛАДОЮ РЕЧІ ПОСПОЛИТОЇ 106.5 KB
  ЗАГАЛЬНИЙ ІСТОРИЧНИЙ ОГЛЯД Після Люблінської унії 1569 року Велике князівство Литовське втратило не лише свої землі а й державне значення. Перше велике козацькоселянське повстання вибухнуло у 1591 році і тривало до 1593 року. Восени 1595 року все українське Правобережжя і ПівденноСхідна Білорусія опинилися в руках повстанців. Згідно зі статтями Переяславської угоди від 29 травня 1630 року козаки визнавали свою провину однак не підлягали покаранню за участь в повстанні.
80483. УКРАЇНСЬКА ДЕРЖАВА ТА ПРАВО В РОКИ ВИЗВОЛЬНОЇ ВІЙНИ. ЕВОЛЮЦІЯ ДЕРЖАВНО - ПРАВОВОЇ СИСТЕМИ (середина ХVІІ – ХVІІІ ст.ст.) 218 KB
  Політичне та економічне становище України було дуже тяжким. Український історик і юрист Андрій Яковлів підкреслював що українським проектом договору гарантувалася повнота внутрішньої автономії держави й усувалося будьяке втручання влади московського царя у внутрішні справи України. Самостійність України визнавалась і на міжнародній арені. Спочатку і Москва ставилась до України як до вільної держави.
80484. УТВОРЕННЯ УКРАЇНСЬКОЇ РАДЯНСЬКОЇ РЕСПУБЛІКИ. ДЕРЖАВА І ПРАВО УСРР В РОКИ ГРОМАДЯНСЬКОЇ ВІЙНИ І ВОЄННОЇ ІНТЕРВЕНЦІЇ 122.5 KB
  Радянське державне будівництво в Україні в умовах громадянської війни та воєнної інтервенції весна 1918 кінець 1920 рр. в Україні розгорталися в загальному контексті громадянської війни на території Росії. Під час збройної боротьби на політичну арену вийшли різноманітні отамани діяльність яких стала однією з характерних рис громадянської війни в Україні. Більшовики спираючись на допомогу радянської Росії докладали чимало зусиль щоб відновити в Україні радянську владу.
80485. СУСПІЛЬНО-ПОЛІТИЧНИЙ ЛАД І ПРАВО УКРАЇНИ В ПЕРІОД З ПОЧАТКУ XX ст. до 1917 року 27.16 KB
  Кожний стан поділявся на групи становища які мали особливі тільки їм надані законом права та обов\'язки. У Луганську та Катеринославі Ради розпустили міські думи і провели роботу по підготовці виборів нового складу цих органів на засадах загального та рівного виборчого права. Вона містила норми про права підданих яких не було в попередніх редакціях Основних законів. Джерела права.
80486. УКРАЇНСЬКА НАЦІОНАЛЬНА ДЕРЖАВНІСТЬ (листопад 1917 — квітень 1918 рр.) 49.43 KB
  Центральна Рада вважала що в такій ситуації можливий єдиний вихід щоб вона стала дійсною фактичною крайовою владою це утворення Української Народної Республіки. Особливе місце в структурі вищих органів УНР займала Центральна Рада. У III Універсалі міститься конструкція згідно з якою Центральна Рада поставлена українським народом разом з братніми народами України. берегти права здобуті боротьбою а в IV Універсалі сказано: Ми Українська Центральна Рада представниця робочого народу селян робітників і солдатів .
80487. СУСПІЛЬНО-ПОЛІТИЧНИЙ ЛАД І ПРАВО УКРАЇНИ В ПЕРІОД УТВЕРДЖЕННЯ КАПІТАЛІЗМУ (друга половина XIX – поч. ХХ ст.) 43.41 KB
  Сільські і волосні органи самоуправління були підпорядковані не тільки системі державних органів управління селянами мировим посередникам повітовим мировим з\'їздам і губернським по селянських справах присутствіям але й поміщикам. Сфера діяльності нових органів всестанового самоврядування була обмежена господарськокультурними справами: освітою охороною здоров\'я торгівлею будівництвом та ін. Маніфест декларував створення Державної думи як законодавчого органу на основі загального виборчого права а також введення громадянських свобод. У...
80488. ГАЛИЦЬКО-ВОЛИНСЬКЕ КНЯЗІВСТВО — ПРОДОВЖЕННЯ ТРАДИЦІЇ РУСЬКО-УКРАЇНСЬКОЇ ДЕРЖАВНОСТІ (перша пол. XIII — друга пол. XIV ст.) 40.5 KB
  Державний лад та правова система Галицько – Волинського князівства. У Новгороді та Пскові утворилися феодальні республіки у ВолодимироСуздальській землі утвердилась одноосібна влада князя в ГалицькоВолинській землі великий вплив на владні відносини мала боярська аристократія. Вершини могутності ГалицькоВолинське князівство досягло під час князювання Романа Мстиславича...