Функциональные модели универсального нейрокомпьютера

  • Вид работы:
    Магистерская работа
  • Предмет:
    Информатика, ВТ, телекоммуникации
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    1,32 Mb
  • Опубликовано:
    2008-12-09
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Функциональные модели универсального нейрокомпьютера

ИНСТИТУТ ВЫЧИСЛИТЕЛЬНОГО МОДЕЛИРОВАНИЯ СО РАН

КРАСНОЯРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ

 

На правах рукописи

 

 

МИРКЕС ЕВГЕНИЙ МОИСЕЕВИЧ

 

Функциональные Модели универсального нейрокомпьютера

 

 

05.13.11 – Математическое и программное обеспечение вычислительных машин, комплексов и компьютерных сетей

 

 

 

 

Диссертация на соискание ученой степени

доктора технических наук

 

 

Консультант: д.ф.-м.н.,                             

профессор    А.Н. Горбань

 

 

 

Красноярск 2001

Оглавление

Общая характеристика работы.. 8

Введение к диссертации.. 14

1.       Функциональные компоненты... 22

1.1.    Краткий обзор нейрокомпьютеров.. 22

1.2.    Выделение компонентов.. 24

1.3.    Запросы компонентов нейрокомпьютера.. 27

1.3.1.     Запросы к задачнику. 28

1.3.2.     Запрос к предобработчику. 28

1.3.3.     Запрос к исполнителю.. 29

1.3.4.     Запросы к учителю.. 29

1.3.5.     Запрос к контрастеру. 29

1.3.6.     Запрос к оценке. 29

1.3.7.     Запрос к интерпретатору ответа. 29

1.3.8.     Запросы к сети. 29

1.4.    Запросы общие для всех компонентов.. 30

1.4.1.     Стандарт типов данных. 30

1.4.2.     Переменные типа цвет и операции с цветами. 33

1.4.2.1.  Значение переменной типа цвет (Color) 33

1.4.2.2.  Операции с переменными типа цвет (Color) 34

1.4.3.     Предопределенные константы.. 35

1.4.4.     Использование памяти. 37

1.4.5.     Обработка ошибок. 38

1.4.5.1.  Процедура обработки ошибок. 38

1.4.5.2.  Установить обработчик ошибок (OnError) 38

1.4.5.3.  Дать номер ошибки (GetError) 39

1.4.6.     Запросы, однотипные для всех компонентов. 40

1.4.6.1.  Запрос на установление текущего компонента. 41

Сделать текущей (xxSetCurrent) 41

1.4.6.2.  Запросы, работающие со структурой компонента. 41

Добавление нового экземпляра (xxAdd) 41

Удаление экземпляра компонента (xxDelete) 42

Запись компонента (xxWrite) 42

Вернуть имена структурных единиц (xxGetStructNames) 43

Вернуть тип структурной единицы (xxGetType) 44

1.4.6.3.  Запросы на изменение параметров. 45

Получить параметры (xxGetData) 45

Получить имена параметров (xxGetName) 45

Установить параметры (xxSetData) 46

1.4.6.4.  Инициация редактора компоненты.. 47

Редактировать компонента (xxEdit) 47

2.       Задачник и обучающее множество.. 48

2.1.    Структуры данных задачника.. 48

2.2.    Поля задачника.. 49

2.3.    Состав данных задачника.. 49

2.3.1.     Цвет примера и обучающая выборка. 50

2.3.2.     Входные данные. 50

2.3.3.     Комментарии. 50

2.3.4.     Предобработанные данные. 51

2.3.5.     Правильные ответы.. 51

2.3.6.     Полученные ответы.. 51

2.3.7.     Оценки. 51

2.3.8.     Вес примера. 51

2.3.9.     Достоверность ответа. 51

2.3.10.   Уверенность в ответе. 52

2.4.    Запросы к компоненту задачник.. 53

2.4.1.     Чтение и запись задачника. 54

2.4.1.1.  Прочитать задачник (tbAdd) 54

2.4.1.2.  Записать задачник (tbWrite) 54

2.4.1.3.  Закрыть задачник (tbDelete) 55

2.4.2.     Начало и конец сеанса. 55

2.4.2.1.  Начало сеанса (InitSession) 55

2.4.2.2.  Конец сеанса (EndSession) 56

2.4.3.     Перемещение по примерам.. 56

2.4.3.1.  В начало (Home) 56

2.4.3.2.  В конец (End) 57

2.4.3.3.  Следующий (Next) 57

2.4.3.4.  Предыдущий (Prev) 58

2.4.3.5.  Конец (Last) 59

2.4.3.6.  Начало (First) 60

2.4.3.7.  Пример номер (Example) 60

2.4.4.     Определение, получение и изменение данных. 61

2.4.4.1.  Дать пример (Get) 61

2.4.4.2.  Обновить данные (Put) 62

2.4.4.3.  Сбросить предобработку (RemovePrepare) 62

2.4.5.     Окраска примеров. 63

2.4.5.1.  Дать цвет примера (GetColor) 63

2.4.5.2.  Покрасить пример (PaintCurrent) 63

2.4.6.     Ошибки компонента задачника. 64

3.       Предобработчик.. 66

3.1.    Нейрон.. 67

3.2.    Различимость входных данных.. 67

3.3.    Классификация компонентов входных данных.. 69

3.4.    Кодирование бинарных признаков.. 70

3.5.    Кодирование неупорядоченных качественных признаков.. 71

3.6.    Кодирование упорядоченных качественных признаков.. 71

3.7.    Числовые признаки.. 71

3.8.    Простейшая предобработка числовых признаков.. 72

3.9.    Оценка способности сети решить задачу.. 72

3.9.1.     Оценка константы Липшица сети. 74

3.9.2.     Способ вычисления константы Липшица. 74

3.9.3.     Синапс. 75

3.9.4.     Умножитель. 75

3.9.5.     Точка ветвления. 75

3.9.6.     Сумматор. 75

3.9.7.     Нелинейный Паде преобразователь. 76

3.9.8.     Нелинейный сигмоидный преобразователь. 76

3.9.9.     Адаптивный сумматор. 76

3.9.10.   Константа Липшица сигмоидной сети. 77

3.10.       Предобработка, облегчающая обучение. 78

3.11.       Другие способы предобработки числовых признаков.. 79

3.11.1.   Модулярная предобработка. 80

3.11.2.   Функциональная предобработка. 80

3.11.3.   Позиционная предобработка. 82

3.12.       Составной предобработчик.. 82

3.13.       Запросы к компоненту предобработчик.. 83

3.13.1.   Запрос на предобработку. 84

3.13.1.1.  Предобработать вектор сигналов (Prepare) 84

3.13.2.   Остальные запросы.. 85

3.13.3.   Ошибки компонента предобработчик. 85

4.       Описание нейронных сетей.. 87

4.1.    Конструирование нейронных сетей.. 87

4.1.1.     Элементы нейронной сети. 88

4.1.2.     Составные элементы.. 89

4.1.3.     Функционирование сети. 90

4.1.4.     Методы построения двойственных сетей. 91

4.1.5.     Элементы самодвойственных сетей. 94

4.1.5.1.  Синапс. 95

4.1.5.2.  Умножитель. 95

4.1.5.3.  Точка ветвления. 96

4.1.5.4.  Сумматор. 96

4.1.5.5.  Нелинейный Паде преобразователь. 97

4.1.5.6.  Нелинейный сигмоидный преобразователь. 97

4.1.5.7.  Произвольный непрерывный нелинейный преобразователь. 98

4.1.5.8.  Пороговый преобразователь. 98

4.1.6.     Правила остановки работы сети. 99

4.1.7.     Архитектуры сетей. 99

4.1.8.     Модификация синаптической карты (обучение) 102

4.1.9.     Контрастирование и нормализация сети. 102

4.2.    Примеры сетей и алгоритмов их обучения.. 103

4.2.1.     Сети Хопфилда. 103

4.2.2.     Сеть Кохонена. 105

4.2.3.     Персептрон Розенблатта. 108

4.3.    Язык описания нейронных сетей.. 110

4.3.1.     Структура компонента. 110

4.3.2.     Сигналы и параметры.. 111

4.3.3.     Обучаемые и не обучаемые параметры и сигналы.. 111

4.3.4.     Дополнительные переменные. 112

4.3.5.     Приведение и преобразование типов. 112

4.3.6.     Операции. 118

4.3.7.     Язык описания нейронных сетей. 120

4.3.7.1.  Ключевые слова языка. 121

4.3.7.2.  Передача аргументов функциям.. 124

4.3.7.3.  Имена структурных единиц. 124

4.3.7.4.  Способ описания синтаксических конструкций. 124

4.3.7.5.  Описание общих синтаксических конструкций. 127

4.3.7.6.  Комментарии. 133

4.3.7.7.  Область действия переменных. 133

4.3.7.8.  Основные операторы.. 134

4.3.7.9.  Описание распределения сигналов. 135

4.3.7.10.  Функции управления памятью.. 136

4.3.7.11.  БНФ языка описания сетей. 138

4.3.7.12.  Описание языка описания сетей. 141

Описание и область действия переменных. 141

Методы Forw и Back для блоков. 141

Описание элементов. 141

Пример описания элементов. 143

Описание блоков. 155

Пример описания блоков. 157

4.3.7.13.  Сокращение описания сети. 164

Раздел описания сигналов и параметров. 164

Раздел описания связей. 165

Частично сокращенное описание. 168

Пример сокращенного описания блоков. 168

4.4.    Запросы к компоненту сеть. 170

4.4.1.     Запросы к компоненту сеть. 171

4.4.2.     Запросы на функционирование. 172

4.4.2.1.  Выполнить прямое Функционирование (Forw) 172

4.4.2.2.  Выполнить обратное Функционирование (Back) 172

4.4.3.     Запросы на изменение параметров. 173

4.4.3.1.  Провести обучение (Modify) 173

4.4.3.2.  Изменить маску обучаемости (ModifyMask) 174

4.4.3.3.  Обнулить градиент (NullGradient) 175

4.4.3.4.  Случайное направление спуска (RandomDirection) 175

4.4.4.     Запросы, работающие со структурой сети. 176

4.4.4.1.  Вернуть параметры сети (nwGetData) 176

4.4.4.2.  Установить параметры сети (nwSetData) 177

4.4.4.3.  Нормализовать сеть (NormalizeNet) 178

4.4.5.     Остальные запросы.. 178

4.4.6.     Ошибки компонента сеть. 179

5.       Оценка и интерпретатор ответа.. 180

5.1.    Интерпретатор ответа.. 180

5.2.    Уровень уверенности.. 182

5.3.    Построение оценки по интерпретатору.. 183

5.4.    Оценка обучающего множества.  Вес примера.. 188

5.5.    Глобальные и локальные оценки.. 190

5.6.    Составные интерпретатор ответа  и оценка.. 195

5.7.    Запросы к компоненту интерпретатор ответа.. 195

5.7.1.     Запрос на интерпретацию.. 196

5.7.1.1.  Интерпретировать массив сигналов (Interpretate) 196

5.7.2.     Остальные запросы.. 197

5.7.3.     Ошибки компонента интерпретатор ответа. 198

5.8.    Запосы к компоненту оценка.. 198

5.8.1.     Запрос на оценивание. 199

5.8.1.1.  Оценить массив сигналов (Estimate) 199

5.8.2.     Остальные запросы.. 200

5.8.2.1.  Установить параметры (SetEstIntParameters) 200

5.8.3.     Ошибки компонента оценка. 201

6.       Исполнитель.. 202

6.1.    Описание компонента исполнитель. 202

6.2.    Запросы к компоненту исполнитель. 203

6.2.1.     Позадачная обработка (TaskWork) 204

6.2.2.     Обработка обучающего множества (TaskSetWork) 206

6.2.3.     Ошибки компонента исполнитель. 209

7.       Учитель.. 210

7.1.    Что можно обучать методом двойственности.. 210

7.2.    Задача обучения сети.. 212

7.3.    Описание алгоритмов обучения.. 213

7.3.1.     Краткий обзор макрокоманд учителя. 213

7.3.2.     Неградиентные методы обучения. 215

7.3.2.1.  Метод  случайной стрельбы.. 216

7.3.2.2.  Метод покоординатного спуска. 217

7.3.2.3.  Подбор оптимального шага. 217

7.3.2.4.  Метод случайного поиска. 218

7.3.2.5.  Метод Нелдера-Мида. 219

7.3.3.     Градиентные методы обучения. 220

7.3.3.1.  Метод наискорейшего спуска. 220

7.3.3.2.  kParTan. 222

7.3.3.3.  Квазиньютоновские методы.. 222

7.4.    Запросы к компоненту учитель. 222

7.4.1.     Обучение сети. 222

7.4.1.1.  Обучить сеть (InstructNet) 223

7.4.1.2.  Провести N шагов обучения (NInstructSteps) 223

7.4.1.3.  Прервать обучение (CloseInstruction) 224

7.4.2.     Чтение/запись учителя. 224

7.4.2.1.  Прочитать учителя (inAdd) 224

7.4.2.2.  Удаление учителя (inDelete) 225

7.4.2.3.  Запись компонента (inWrite) 225

7.4.3.     Инициация редактора учителя. 226

7.4.3.1.  Редактировать компонент (inEdit) 226

7.4.4.     Работа с параметрами учителя. 227

7.4.4.1.  Получить параметры (inGetData) 227

7.4.4.2.  Получить имена параметров (inGetName) 227

7.4.4.3.  Установить параметры (inSetData) 228

7.4.5.     Обработка ошибок. 228

8.       Контрастер. 229

8.1.    Задачи для контрастера.. 229

8.1.1.     Упрощение архитектуры нейронной сети. 229

8.1.2.     Уменьшение числа входных сигналов. 231

8.1.3.     Сведение параметров нейронной сети к выделенным значениям.. 231

8.1.4.     Снижение требований к точности входных сигналов. 232

8.1.5.     Получение явных знаний из данных. 232

8.1.5.1.  Построение логически прозрачных сетей. 233

8.1.5.2.  Получение явных знаний. 234

8.2.    Множества повышенной надежности.. 237

8.2.1.     Формальная постановка задачи. 237

8.2.2.     Классификация дублей. 238

8.2.3.     Прямой дубль первого рода. 238

8.2.4.     Косвенный дубль первого рода. 239

8.2.5.     Прямой дубль второго рода. 240

8.2.6.     Косвенный дубль второго рода. 241

8.2.7.     Косвенный супердубль. 241

8.3.    Процедура контрастирования.. 242

8.3.1.     Контрастирование на основе показателей значимости. 242

8.3.2.     Контрастирование без ухудшения. 243

8.3.3.     Гибридная процедура контрастирования. 244

8.3.4.     Контрастирование при обучении. 245

8.4.    Определение показателей значимости.. 245

8.4.1.     Определение показателей значимости через градиент.. 245

8.4.2.     Усреднение по обучающему множеству. 246

8.4.3.     Накопление показателей значимости. 247

8.5.    Запросы к компоненту контрастер. 248

8.5.1.     Контрастирование сети. 248

8.5.1.1.  Контрастировать сеть(ContrastNet) 248

8.5.1.2.  Прервать контрастирование (CloseContrast) 248

8.5.1.3.  Контрастировать пример (ContrastExample) 249

8.5.2.     Чтение/запись контрастера. 250

8.5.2.1.  Прочитать контрастера (cnAdd) 250

8.5.2.2.  Удаление контрастера (cnDelete) 250

8.5.2.3.  Запись контрастера (cnWrite) 251

8.5.3.     Инициация редактора контрастера. 251

8.5.3.1.  Редактировать контрастера (cnEdit) 251

8.5.4.     Работа с параметрами контрастера. 252

8.5.4.1.  Получить параметры (cnGetData) 252

8.5.4.2.  Получить имена параметров (cnGetName) 252

8.5.4.3.  Установить параметры (cnSetData) 253

8.5.5.     Обработка ошибок. 253

9.       Нейронные сети ассоциативной памяти, функционирующие в дискретном времени.. 255

9.1.    Описание задачи.. 255

9.2.    Формальная постановка задачи.. 256

9.3.    Сети Хопфилда.. 256

9.4.    Функционирование сети. 257

9.5.    Ортогональные сети.. 261

9.6.    Тензорные сети.. 265

9.7.    Сети для инвариантной обработки изображений.. 268

9.8.    Численный эксперимент. 269

9.9.    Доказательство теоремы.. 271

10.     Заключение.. 277

11.     Приложение 1. Логически прозрачная сеть для прогнозирования шизофрении.. 278

12.     Приложение 2. Краткое описание возможностей программы NEUROPRO   285

12.1.       Общие сведения.. 285

12.2.       Требования к аппаратуре. 285

12.3.       Основные возможности программы.. 285

12.4.       Форматы файлов.. 286

12.5.       Нейросетевая парадигма.. 286

12.6.       Подача и снятие сигналов.. 286

12.7.       Точность решения задачи.. 287

12.8.       Обучение нейронной сети.. 288

12.9.       Упрощение нейронной сети.. 288

12.10.     Вербализация нейронной сети.. 289

13.     Приложение 3. Акты о внедрении.. 290

ЛИТЕРАТУРА.. 291

 

Введение

Общая характеристика работы

Актуальность темы. В 80-е годы развитие информатики и средств вычислительной техники во многом определялось программой «Пятое поколение компьютеров». Основной целью данной программы было развитие систем искусственного интеллекта на базе алгоритмических языков. В 1992 году на смену программе «Пятое поколение компьютеров» пришла программа «Вычисления в Реальном мире». Основная цель новой программы – обеспечить возможность вычислительным системам взаимодействовать с реальным миром без посредства человека. Довольно большая часть программы – 30-40% – отведена исследованию естественных нейронных сетей и разработки искусственных нейронных сетей и нейросетевых систем.

Искусственные нейронные сети являются вычислительными устройствами, основанными на использовании большого числа очень простых нейронов. Все навыки искусственных нейронных сетей рассредоточены в синаптических связях. Канадский физиолог Д.Хебб в 1949 году описал такой синапс, как основу возможных механизмов памяти и поведения. Таким образом искусственные нейронные сети были предложены фактически сразу, после возникновения кибернетики. Уже сейчас искусственные нейронные сети применяются для решения очень многих задач обработки изображений, управления роботами и непрерывными производствами, для понимания и синтеза речи, для диагностики заболеваний людей и технических неполадок в машинах и приборах, для предсказания курсов валют и результатов скачек.

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

Несмотря на то, что термин нейроинформатика возник в середине 80-х годов, сравнение электронного и биологического мозга ведется постоянно на протяжении всей истории существования вычислительной техники. Знаменитая книга Н.Винера "Кибернетика", ознаменовавшая рождение этой науки в 1948 г., имеет подзаголовок "Управление в живых системах, технике и обществе".

В середине 80-х размеры элементарных деталей вычислительных устройств стали сравнимы по размерам с нейронами человеческого мозга. Однако, не смотря на то, что быстродействие электронных элементов в миллионы раз выше, с задачами ориентации и принятие решений в естественной среде биологические системы справляются намного эффективнее. Возникла гипотеза, что мозг выигрывает это соревнование за счет специфических механизмов обработки информации. Это послужило основой для активизации фундаментальных и прикладных исследований в области механизмов переработки информации в биологических системах и породило нейроинформатику.

Основная задача нейроинформатики – разработка методов создания (синтеза) нейронных схем, решающих те или иные задачи. Нейрон в искусственных нейронных сетях является достаточно простым устройством. Например, нечто вроде усилителя с большим числом входов и одним выходом. Различие между подходами и методами - в деталях представлений о работе нейрона, и, конечно, в представлениях о работе связей.

Основное отличие нейрокомпьютеров от обычных компьютеров состоит в том, что в обычных компьютерах есть такие четко выделенные элементы как память и универсальный процессор. В нейрокомпьютере вся память рассредоточена в весах связей между простыми процессорами – нейронами. Таким образом основная нагрузка при решении нейрокомпьютером задачи ложится на структуру связей, задающую архитектуру нейронной сети.

Значительную роль в общем подъеме интереса к нейропроблемам сыграла теория, предложенная Джоном Хопфилдом в 1982 г. Другой важный класс нейронных систем введен в рассмотрение финном Тейво Кохоненом. Еще один класс нейроподобных моделей представляют сети с обратным распространением ошибки. Метод имеет длительную историю. В развитии его современных модификаций ведущую роль сыграли французский исследователь ле Кун и профессор А.Н.Горбань из Красноярска.

Средства для решения задач нейроинформатики обычно называют нейрокомпьютерами. Нейрокомпьютеры могут быть аппаратными, программными имитаторами или программно-аппаратными комплексами. В данный момент любой нейрокомпьютер не претендует на звание универсального компьютера, а создается для решения определенного круга задач. В мире имеется несколько десятков специализированных фирм, выпускающих продукцию в области нейроинформатики и, кроме того, многие гиганты индустрии (IBM, Siemence, Mitsubishi и др.) ведут исследования и разработки в этой области.

Сейчас можно уже говорить о традиционных задачах нейроинформатики. К таковым относятся задачи распознавания образов, речи, радарных сигналов, медицинской диагностики и другие трудно формализуемые задачи. Постоянно появляются все новые области приложений. Одним из наиболее значимых можно назвать задачу первичной обработки данных в физике элементарных частиц. Суть этого приложения состоит в том, что с датчиков поступает огромный поток данных о различных частицах. Необходимо с высокой скоростью отобрать данные об интересующих исследователя частицах и отсеять остальные. Большой интерес к нейрокомпьютерам проявляют также военные ведомства многих стран. Однако основной областью применения нейронных сетей и основанных на их использовании устройств будут по всей видимости системы управления роботов. По мнению одного из ведущих исследователей в области нейроинформатики Р. Хехт-нильсена основной продукцией промышленных фирм через 10 лет будут "нейровычислительные роботы".

Цели работы. На основе анализа различных нейросетевых парадигм построить модель универсального нейрокомпьютера. Универсальный нейрокомпьютер должен иметь структуру, позволяющую реализовать большинство нейросетевых парадигм.

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

Разработать тип оценок, позволяющих интерпретатору ответа оценивать уровень уверенности сети в ответе.

Разработать методы получения явных алгоритмов решения задачи с помощью нейронных сетей.

Разработать метод определения минимального набора входных данных, устойчивого к искажениям во входных данных.

Разработать сеть ассоциативной памяти максимальной информационной емкости.

Научная новизна и практическая ценность. В данной работе разработана функциональная модель универсального нейрокомпьютера. Определены принципы выделения функциональных компонентов. Проведена декомпозиция нейрокомпьютера на функциональные компоненты в соответствии с предложенными принципами. Показана универсальность разработанной модели – возможность реализации в рамках данной модели всех основных видов нейронных сетей. Предложенная модель позволяет проводить аргументированное сравнение различных реализаций отдельных компонентов нейрокомпьютера, отслеживать взаимосвязи между компонентами. Для каждого компонента разработан полный (исчерпывающий) список запросов. Это позволяет при разработке больших программных комплексов разрабатывать каждый компонент независимо от других. Более того, в пределах одной вычислительной платформы возможно использование один раз запрограммированного компонента в различных программных комплексах (например, при помощи динамически связываемых библиотек (DLL)). Четкое определение функций каждого компонента позволяет разрабатывать для каждого компонента наиболее эффективные реализации независимо от других компонентов.

Разработан принцип построения нового типа оценок, названный эффективной функцией оценки. Эффективность предложенного типа оценок состоит в том, что их использование позволяет ускорить обучение нейронной сети, оценить уровень уверенности нейронной сети в полученном ответе, обучить с малой надежностью сеть решению тех задач, которые сеть данной архитектуры не может решить с высокой надежностью, учесть при обучении различие в достоверности ответов в разных примерах.

Разработан метод получения явных знаний из данных с помощью логически прозрачных нейронных сетей, получаемых из произвольных обученных сетей специальной процедурой контрастирования (скелетонизации). Этот метод позволяет получить явные зависимости выходных сигналов нейронной сети от входных. В случае решения задач классификации в большинстве случаев удается получить схему логического вывода.

Разработан метод построения минимально необходимых наборов входных данных и построения на их основе наборов входных данных повышенной надежности (устойчивости к искажениям во входных данных). Доказаны теоремы, устанавливающие соотношения между такими наборами, построенными различными способами.

Получены оценки способности сети ассоциативной памяти к точному воспроизведению эталонов. В работе рассмотрена сеть Хопфилда, функционирующая в дискретном времени. Разработаны методы, позволяющие повысить ее информационную емкость. С помощью этих методов построены три сети ассоциативной памяти, имеющие большую информационную емкость и менее зависящие от степени коррелированности эталонов. Предложен метод конструирования сетей ассоциативной памяти со свойствами, необходимыми для решения конкретной задачи. Доказана теорема об информационной емкости ортогональной тензорной сети.

Предложенная функциональная модель была частично реализована в ряде программных продуктов, разработанных Красноярской группой Нейрокомп. Так в программе Eye, разработанной автором в 1989 году, впервые были реализованы и опробованы эффективные функции оценки. Данная программа широко использовалась в учебном процессе и послужила одной из базовых программ при проведении Первой Всесоюзной олимпиады по нейрокомпьютингу (Омск, 1991 год). В 1993 году автором была разработана серия программ, под общим названием «Нейроучебник», которые до сих пор используются в учебном процессе в ряде красноярских вузов. В программе Sigmoid1 из этой серии впервые было реализовано контрастирование. На этой программе была получена первая логически прозрачная нейронная сеть. В программе Hopfield из той же серии впервые была реализована ортогональная сеть ассоциативной памяти.

В 1993-1995 годах на ВЦ СО РАН в г. Красноярске под руководством автора работал программистский семинар по разработке нейросетевых приложений. Одним из результатов работы семинара явилось появление программы MultyNeuron. Результаты использования программы в медицине опубликованы различными исследователями более чем в 50 работах.

В 1996-2000 годах по проекту «Разработка и программная реализация технологии производства явных знаний из данных с помощью обучаемых нейронных сетей» № 05.04.1291 подпрограммы «Перспективные информационные технологии» Федеральной целевой программы на 1996-2000 годы «Исследования и разработки по приоритетным направлениям развития науки и техники гражданского назначения» под руководством автора были разработаны три программы FAMaster [186], NeuroPro [237] и GISNNA [180]. На базе этих программ защищено три кандидатские диссертации. В приложении к диссертации приведены 26 актов о внедрении.

На защиту выносятся.

1. Функциональная модель универсального нейрокомпьютера. Принципы выделения функциональных компонентов. Декомпозиция нейрокомпьютера на функциональные компоненты в соответствии с предложенными принципами.

2. Принцип построения эффективных функций оценки, позволяющих ускорить обучение нейронной сети, оценить уровень уверенности нейронной сети в полученном ответе, обучить с малой надежностью сеть решению тех задач, которые сеть данной архитектуры не может решить с высокой надежностью.

3. Метод получения явных знаний из данных с помощью логически прозрачных нейронных сетей, получаемых из произвольных обученных сетей специальной процедурой контрастирования.

4. Метод построения минимально необходимых наборов входных данных и построения на их основе наборов входных данных повышенной устойчивости к искажениям во входных данных. Теоремы о соотношениях между различными видами таких наборов.

5. Метод описания процедуры конструирования нейронных сетей из простейших элементов и более простых сетей. Язык описания результатов конструирования.

6. Методы повышения информационной емкости сетей ассоциативной памяти, функционирующих в дискретном времени. Метод конструирования сетей ассоциативной памяти со свойствами, необходимыми для решения конкретной задачи. Теорема об информационной емкости ортогональной тензорной сети.

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

Апробация работы. Основные положения и результаты работы докладывались на 1 Всероссийском рабочем семинаре «Нейроинформатика и нейрокомпьютеры», Красноярск (1993); 2, 3, 4, 5, 6, 7, 8 Всероссийских рабочих семинарах «Нейроинформатика и ее приложения», Красноярск (1994 – 2000); научно-технической конференции «Проблемы техники и технологий XXI века», Красноярск (1994); межрегиональной конференции «Проблемы информатизации региона» (1995); 1, 2 IEEE-RNNS Symposium, Rostov-on-Don (1992, 1995); IEEE International Conference on Neural Networks, Houston, IEEE (1997); III Международной конференции "Математика, компьютер, образование". - Москва (1996); International Joint Conference on Neural Networks, Washington, DC, USA, 1999; 10th International. Congress of chemical engineering, chemical equipment design and automation, Praha (1990); Международном конгрессе «Индустриальная и прикладная математика», Новосибирск (1998).

Кроме того, основные положения работы были представлены на Всемирном конгрессе по нейронным сетям (WCNN'95) (1995).

Введение к диссертации

Термин «Нейрокомпьютер» не имеет четкого определения, поэтому определим, что называется нейрокомпьютером в данной работе: нейрокомпьютер это устройство для решения какой либо задачи, в качестве основного решающего устройства использующее искусственную нейронную сеть. Для данной работы не важно в каком виде существует нейронная сеть и весь нейрокомпьютер – в виде программной эмуляции, специализированного устройства или любом другом. Речь пойдет об универсальном (решающем любые задачи) идеальном (не привязанном к какой либо реализации или элементной базе) нейрокомпьютере. Однако прежде чем переходить к содержательному обсуждению, необходимо описать ситуацию в нейроинформатике в целом.

В нейроинформатике существует три направления, которые условно можно назвать биологическим, модельным и инженерным (эта классификация впервые была введена А.Н. Горбанем на лекциях по нейронным сетям, прочитанным в ЛЭТИ в 1991 году в ходе подготовки к Первой Всесоюзной Олимпиаде по нейрокомпьютингу среди студентов и школьников). Цель работ биологического направления – понять, как устроена нервная система (например, [15, 16, 23, 29, 102, 106, 113, 116, 137, 145, 172, 173, 179, 182, 242, 244, 263, 268, 293, 348, 369, 370, 372, 373, 378]). Как правило, работы этого направления проходят следующие этапы. Сначала выдвигается гипотеза о биологическом механизме решения, каким либо отделом мозга определенной задачи. Далее строится компьютерная модель для проверки этой гипотезы. В ходе построения модели используются либо уже известные нейронные сети, либо предлагается новый вид сети.

В работах модельного направления исследуются свойства искусственных нейронных сетей. Как правило, исследователи берут ранее известную нейронную сеть и исследуют ее возможности. В работах этого направления есть она особенность, которая является одновременно и сильным и слабым местом одновременно – фактический отказ от модернизации архитектуры нейронной сети. С точки зрения исследователя модельного направления сеть с модернизированной архитектурой  это совсем другая сеть.

Работы инженерного направления посвящены использованию искусственных нейронных сетей для решения практических задач. При этом степень сходства используемой нейронной сети с биологическим аналогом не имеет значения. Инженерное направление заимствовало из естественных нейронных сетей два основных принципа:

много простых элементов решают сложную задачу;

обучение вместо программирования.

Инженерное направление в свою очередь делится на два поднаправления – теоретическое и практическое. Исследователи теоретического направления занимаются разработкой нейронных сетей для решения определенных задач и исследованием их возможностей. Основное отличие теоретического поднаправления от модельного направления состоит в том, что при необходимости архитектура нейронной сети, правила обучения и другие компоненты нейрокомпьютера свободно модифицируются для решения поставленной задачи. Содержание девятой главы может служить типичным примером работы теоретического инженерного подхода. Другие примеры работ данного направления можно найти , например, в [8, 37, 107, 176, 222, 224, 230, 231, 256, 349, 365, 367]. Работы практического направления, как правило, содержат решение конкретной прикладной задачи. На нейросетевых и медицинских конференциях в последние годы докладываются сотни работ этого направления. В Красноярске на базе нейросетевого эмулятора MultyNeuron [193, 194, 287] разработано свыше двух десятком различных медицинских экспертных систем [18, 49 – 52, 73, 93 – 96, 163, 164, 169, 201]. Число нейросетевых экспертных систем в различных областях насчитывает несколько тысяч. Примерами таких работ могут служить следующие работы [24, 121, 246, 249, 252, 253, 257 – 260, 272, 275, 284, 287, 292, 308, 310, 314, 315, 318, 331, 333 – 335, 337, 339, 342 – 344, 346, 350, 356, 359, 363, 366, 368, 377].

Несмотря на то, что обычно большинство работ нельзя однозначно отнести к какому либо из перечисленных выше направлений, использование предложенной классификации работ позволяет яснее представить место работы в современной нейроинформатике. Автор относит свою работу к теоретическому поднаправлению инженерного направления.

Методы нейроинформатики успешно зарекомендовали себя в настолько широком круге приложений, что стали темой многих публикаций в изданиях, не имеющих прямого отношения к науке [99. 169]. Этот успех опирается на две предпосылки – универсальность нейронных сетей [38, 39, 57, 64, 70, 286] и способность вырабатывать нечто, напоминающее человеческую интуицию [101, 110, 254, 269, 270]. Безусловно, для большинства задач, решаемых методами нейроинформатики, существуют традиционные методы решения (см. например [4, 5, 17, 19, 89, 103, 109, 111, 113, 117 – 119, 128, 129, 271, 319, 360]). Более того, существует ряд работ, посвященных решению классических задач методами нейроинформатики (см. например, [89, 129, 176, 222, 276, 277, 299, 320, 328, 349]). Однако, для применения большинства традиционных методов необходимо, во-первых, знать о них, во-вторых, знать их область их применения и ограничения. В то время, как успех нейроинформатики основан на утверждении «нейронные сети могут все». Это утверждение долгое время было лозунгом нейроинформатики, а сравнительно недавно было строго доказано [38, 39, 57, 64, 70, 136, 266, 323]. Основные задачи и преимущества нейроинформатики подробно рассмотрены в [59 – 62, 71, 74, 108, 146, 151, 152, 170, 174, 245, 248, 262, 279, 281, 288, 290, 317]

Многолетние усилия многих исследовательских групп привели к тому, что к настоящему моменту накоплено большое число различных правил обучения и архитектур нейронных сетей, способов оценивать и интерпретировать их работу, приемов использования нейронных сетей для решения прикладных задач. Каждое правило, архитектура, система оценки и интерпретации составляют отдельный нейрокомпьютер. Причем каждый нейрокомпьютер уникален и отделен от других. Такой тип многообразия принято называть «зоопарком». Многообразие этого типа нетехнологично. Существует другой тип многообразия – технопарк. Такое многообразие строится как совокупность многих «машин» собранных из небольшого набора стандартных деталей. Основная цель данной работы состоит в том, чтобы преобразовать существующий зоопарк нейрокомпьютеров в технопарк.

В качестве примера приведем выдержку из монографии (учебного пособия) одного из наиболее известных Российских ученых–нейроинформатиков А.И. Галушкина [26].

«Основными качественными характеристиками архитектур нейронных сетей являются:

1. Типы входных сигналов (размерность, дискретность и т. д.).

2. Тип операций, реализуемых в разомкнутой нейронной сети (дискретные или непрерывные).

3. Топология связей (прямые, перекрестные, латеральные, обратные и т.д.).

4. Наличие или отсутствие желания сымитировать в структуре конкретную биологическую систему (зрительный или слуховой анализатор, мозжечок, таламус и т.д.).

5. Наличие желания максимально повысить скорость вычислительных операций на нейронной сети.

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

7. Способ объединения в группы процессорных элементов.

8. Способ функционирования во времени (дискретный или непрерывный).

9. Способ изменения весов связей (случайный или упорядоченный).

10. Способ соединения независимо настроенных (или настраиваемых) нейронных сетей вместе.»

Очевидно, что первый пункт приведенного списка относится в основном к методам предобработки и не имеет отношения к архитектуре нейронных сетей. Шестой пункт относится к способу реализации сети и лишь косвенно к архитектуре. Седьмой пункт относится к практике имитации нейронных сетей на компьютерах различной конфигурации. Нельзя считать, что полносвязная нейронная сеть прямого распространения с одним и тем же числом нейронов будет иметь разную архитектуру в зависимости от того, реализована она на обычном персональном компьютере или на нейрокомпьютере Synaps 1. Очевидно, что архитектура нейронной сети будет в обоих случаях одинакова. Изменится только программная реализация сети и нейрокомпьютера в целом. Девятый пункт связывает в одно целое архитектуру сети и метод обучения. В программах группы Нейрокомп, и других разработчиков реализованы различные способы обучения нейронных сетей, как случайные, так и градиентные.

К сожалению, такая практика, соединения архитектуры нейронной сети и алгоритмов обучения в единое целое, имеет место и в разработках многих западных фирм [25, 141, 142].

Для перехода к разнообразию типа технопарк полезен такой подход: каждый нейрокомпьютер из зоопарка должен быть представлен как реализованный на идеальном нейрокомпьютере, имеющем заданную структуру. В пределах данной структуры возможен почти произвольный выбор комплектующих – архитектур сетей, предобработчиков, интерпретаторов ответа и других компонентов. Несомненно, структура этого идеального нейрокомпьютера со временем будет эволюционировать. Однако преимущества даже от первых шагов стандартизации несомненны. Подтверждением этому служит опыт двенадцатилетней работы Красноярской группы НейроКомп по использованию нейронных сетей в различных задачах: распознавания образов [65, 291, 295], медицинской диагностики [18, 49 – 52, 73, 92, 94, 163 – 165, 168, 188 – 192, 195 – 214, 261, 300 – 302, 321, 322, 351 – 355, 361, 372], прогноза [303–305, 374] и др.[89–91, 156, 157, 166, 167, 175, 181, 238, 337].

Группа НейроКомп в течение двенадцати лет отрабатывала принципы организации нейронных вычислений. Различные варианты этих принципов были реализованы в серии программ-нейроимитаторов. Возможность формирования большинства архитектур, алгоритмов и способов использования нейронных сетей на основе небольшого числа стандартных блоков существенно облегчает создание программного обеспечения, и его использования при решении прикладных задач.

Особую актуальность приобретает задача создания универсального нейрокомпьютера в связи с тем, что в течении последних десяти лет десятки серьезных компаний заявили о разработке аппаратных нейрокомпьютеров. При этом существует две крайности. С одной стороны, аппаратно реализованные нейронные сети, способные решать только одну конкретную задачу (например, [10 – 12, 21, 26, 105, 159, 221, 225]). С другой стороны – универсальные нейрокомпьютеры типа «Synaps I», предложенный фирмой Сименс-Никсдорф. Автор имел возможность ознакомиться с техническими характеристиками данного нейрокомпьютера и проектом программного обеспечения для него. К сожалению, этот компьютер является нейрокомпьютером только по названию, поскольку в действительности это обычный хороший высокоскоростной параллельный компьютер. Вся реализация всех типов нейронных сетей, заявленная фирмой Сименс-Никсдорф, содержится полностью в программном обеспечении. Основная проблема, встающая на пути таких разработок – попытка реализовать исходный мелкозернистый параллелизм нейронных сетей, состоящих из простых элементов, на базе относительно малого числа сложных универсальных процессоров. Вопросы параллелизма нейронных сетей рассмотрены во многих работах (см. например, [152, 264]).

В данной работе описана функциональная структура идеального универсального нейрокомпьютера для реализации большинства нейронных сетей одного из крупных отделов «зоопарка». Речь идет о сетях работающих в дискретном времени. Изначально предполагалось, что на предложенном нейрокомпьютере можно будет реализовать только сети связанные с методом обратного распространения ошибки - это мощная и широко применяемая технология обучения нейронных сетей (см. например, [236, 312, 313, 355, 358]). К сожалению, она получила распространение в виде алгоритма, а не в виде способа построения алгоритмов. Более общая теория обучения нейронных сетей - принцип двойственности [9, 13, 14, 45, 55, 56, 65, 255. 256, 289, 295] – мало известна. На данный момент в литературе встречается описание более чем двух десятков различных алгоритмов обучения нейронных сетей по методу обратного распространения ошибки. Однако в ходе работы оказалось, что предложенная структура нейрокомпьютера позволяет реализовать любые сети функционирующие в дискретном времени.

На данный момент нейрокомпьютеры существуют, в основном, в виде программных имитаторов. Предложенный в данной работе подход – сборка нейрокомпьютера из небольшого числа реализаций восьми компонентов – позволяет существенно упростить процесс разработки таких имитаторов. Автором предложены два уровня стандарта нейрокомпьютера, приведенные в первом приложении к данной работе. Первый уровень состоит в разработанном едином языке описания функциональных компонентов нейрокомпьютера. При этом не важно, кем и для каких компьютеров был разработан программный имитатор. Возможность иметь внешнее, по отношению к программному имитатору, описание всех основных компонентов нейрокомпьютера призвана облегчить разработку и распространение архитектур нейронных сетей, правил интерпретации ответов и их оценки, алгоритмов обучения, методов контрастирования (скелетонизации) и т.д. При этом результат становится не зависящим от программы, при помощи которой он был получен, и воспроизводимым другими исследователями. Кроме того, единый подход к описанию структуры нейронной сети, предобработчика и других компонентов нейрокомпьютера облегчает разработку аппаратной реализации нейрокомпьютера или его отдельных компонентов.

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

Ранее уже было предложено несколько вариантов языка описания нейронных сетей. Примером таких языков может служить язык для описания нейронных сетей AXON [311, 324 – 326], разработанный и поддерживаемый группой исследователей под руководством Р. Хехт-Нильсона. Изначально, автор с коллегами из группы НейроКомп пошли по тому же пути [46]. Однако он оказался бесперспективным. Основным отличием способа описания нейрокомпьютера, предложенного в данной работе, от языка AXON является полнота охвата всех компонентов нейрокомпьютера. Язык AXON служит для описания только нейронных сетей, тогда как приведенный в приложении стандарт охватывает все компоненты нейрокомпьютера и средства интерфейса между ними.

Предложенная функциональная модель была частично реализована в ряде программных продуктов, разработанных Красноярской группой Нейрокомп. Так в программе Eye [83, 171], разработанной автором в 1989 году, впервые были реализованы и опробованы эффективные функции оценки. Данная программа широко использовалась в учебном процессе и послужила одной из базовых программ при проведении Первой Всесоюзной олимпиады по нейрокомпьютингу (Омск, 1990 год). В 1993 году автором была разработана серия программ, под общим названием «Нейроучебник», которые до сих пор используются в учебном процессе в ряде красноярских вузов. В программе Sigmoid1 из этой серии впервые было реализовано контрастирование. На этой программе была получена первая логически прозрачная нейронная сеть. В программе Hopfield из той же серии впервые была реализована ортогональная сеть ассоциативной памяти.

В 1993-1995 годах на ВЦ СО РАН в г. Красноярске под руководством автора работал программистский семинар по разработке нейросетевых приложений. Одним из результатов работы семинара явилось появление программы MultyNeuron. Результаты использования программы в медицине опубликованы различными исследователями более чем в 50 работах [18, 49 – 52, 73, 93 – 95, 121, 163, 164, 168, 188 – 192, 195 – 201, 203 – 214, 287, 300 – 302, 321, 322, 351 – 355, 361, 371].

В 1996-2000 годах по проекту «Разработка и программная реализация технологии производства явных знаний из данных с помощью обучаемых нейронных сетей» № 05.04.1291 подпрограммы «Перспективные информационные технологии» Федеральной целевой программы на 1996-2000 годы «Исследования и разработки по приоритетным направлениям развития науки и техники гражданского назначения» под руководством автора были разработаны три программы FAMaster, NeuroPro и GISNNA. На базе этих программ защищено три кандидатские диссертации [180, 186, 237]. В приложении к диссертации приведены 26 актов о внедрении.

Предложенная в данной работе функциональная модель нейрокомпьютера является нетрадиционной. Как правило, под моделью устройства понимают систему уравнений, описывающих ее функционирование. В данном случае такой подход в целом к нейрокомпьютеру затруднен многообразием нейрокомпьютеров. Реально в данной работе предложен двухэтапный способ построения модели нейрокомпьютера. На первом этапе на базе функциональной модели универсального нейрокомпьютера определяется состав специализированного нейрокомпьютера для решения исследуемой задачи. На втором этапе, когда состав и реализации компонентов нейрокомпьютера определены, автоматически получается системы уравнений, описывающие функционирование и обучение этого конкретного нейрокомпьютера.

Такой подход может оказаться эффективным и при аппаратной реализации нейрокомпьютеров. Как уже отмечалось выше, при попытке аппаратной реализации универсального нейрокомпьютера происходит изготовление очередного универсального параллельного вычислителя. Это связано с тем, что аппаратно реализовать нейронную сеть, не наложив существенных ограничений на ее архитектуру, на данном этапе развития вычислительной техники невозможно. Наиболее перспективным выглядит следующий подход к аппаратной реализации нейрокомпьютера. Сначала на программном имитаторе универсального нейрокомпьютера производится отбор необходимых реализаций всех компонентов нейрокомпьютера. Далее на том же имитаторе производится обучение и, при необходимости, контрастирование нейронных сетей. После того, как получена нейросетевая модель задачи, наступает этап аппаратной реализации. Поскольку реализуется решатель конкретной задачи, то требуется не универсальная нейронная сеть, а сеть заданной архитектуры с уже известными параметрами и весами связей. Заранее известен вид используемой предобработки и способ интерпретации ответа. В большинстве случаев такие компоненты как учитель, контрастер, оценка не требуются, поскольку они сыграли свою роль на этапе подготовки нейрокомпьютера.

Несколько слов о структуре диссертации. В первой главе выделяются основные компоненты нейрокомпьютера по следующим признакам.

1. Относительная функциональная обособленность: каждый компонент имеет четкий набор функций. Его взаимодействие с другими компонентами может быть описано в виде небольшого числа запросов.

2. Возможность реализации большинства используемых алгоритмов.

3. Возможность взаимозамены различных реализаций любого компонента без изменения других компонентов.

Кроме того, в последней части первой главы описаны запросы, исполняемые всеми компонентами нейрокомпьютера.

Главы со второй по восьмую посвящены описанию одного или нескольких тесно связанных между собой компонентов нейрокомпьютера, каждая. В каждой главе детально описаны функции компонента, которому она посвящена, взаимосвязь этого компонента с другими компонентами. Кроме того, в большинстве глав содержатся оригинальные разработки, такие как эффективные оценки, логическая прозрачность и т.д. В последней части каждой главы приведено описание запросов к описываемому в данной главе компоненту нейрокомпьютера. В предпоследней части пятой главы приведена БНФ языка описания структуры нейронной сети, библиотек элементов и подсетей.

В девятой главе проиллюстрирован теоретический подход к решению задачи о построении сети ассоциативной памяти с максимальной информационной емкостью. Доказана теорема об информационной емкости тензорных сетей, приведены результаты численных экспериментов.

1. Функциональные компоненты

Эта глава посвящена выделению функциональных компонентов, составляющих универсальный нейрокомпьютер [77, 88, 152, 297, 298]. Основные компоненты нейрокомпьютера выделяются по следующим признакам:

1. Относительная функциональная обособленность: каждый компонент имеет четкий набор функций. Его взаимодействие с другими компонентами может быть описано в виде небольшого числа запросов.

2. Возможность реализации большинства используемых алгоритмов.

3. Возможность взаимозамены различных реализаций любого компонента без изменения других компонентов.

Однако, прежде чем приступать к выделению компонент, опишем рассматриваемый набор нейронных сетей и процесс их обучения.

Кроме того, в данной главе описаны общие для всех компонентов типы данных. Дано полное описание запросов, выполняемых всеми компонентами.

1.1. Краткий обзор нейрокомпьютеров

Разнообразие нейрокомпьютеров можно классифицировать по разным признакам. Наиболее естественной является классификация по типу используемой нейронной сети. С точки зрения функционирования наиболее существенным является разделение на сети, функционирующие в непрерывном времени, и сети, функционирующие в дискретном времени. Наиболее известным представителем сетей, функционирующих в непрерывном времени являются сети Хопфилда [316]. Семейство нейронных сетей, функционирующих в дискретном времени, представлено шире – это сети Кохонена [130, 131], персептрон Розенблатта [147, 185], сети, обучаемые по методу двойственности (обратного распространения ошибки) [34, 35, 40, 42, 43, 47, 48, 53, 54, 58, 65, 69, 93] и др. В данной работе рассматриваются только сети, функционирующие в дискретном времени.

Другая возможная классификация – по типам решаемых задач. Можно выделить три основных типа задач.

1. Классификация без учителя или поиск закономерностей в данных. Наиболее известным представителем этого класса сетей является сеть Кохонена [130, 131], реализующая простейший вариант решения этой задачи. Наиболее общий вариант решения этой задачи известен как метод динамических ядер [229, 267].

2. Ассоциативная память. Наиболее известный представитель – сети Хопфилда [316]. Эта задача также позволяет строить обобщения. Наиболее общий вариант описан в [75, 77, 86].

3. Аппроксимация функций, заданных в конечном числе точек. К сетям, решающим эту задачу, относятся персептрон, и сети обратного распространения ошибки.

Отметим, что для каждой из перечисленных задач существуют другие, более традиционные методы решения (см. например, [1, 7, 17, 19, 22]).

Наиболее распространенными являются сети третьего класса. Именно для таких сетей в первую очередь и предназначена предлагаемая модель универсального нейрокомпьютера. Однако нейрокомпьютеры для решения двух других типов задач так же могут быть реализованы в рамках предложенной модели. При этом они используют не все компоненты универсального нейрокомпьютера. Так при реализации сетей ассоциативной памяти нет необходимости использовать компоненты оценка и интерпретатор ответа, а для сетей, обучающихся без учителя, не нужен компонент оценка, но необходим компонент учитель.

Среди сетей, аппроксимирующих функции, необходимо выделить еще два типа сетей – с дифференцируемой и пороговой характеристической функцией. Дифференцируемой будем называть сеть, каждый элемент которой реализует непрерывно дифференцируемую функцию. Вообще говоря, альтернативой дифференцируемой сети является недифференцируемая, а не пороговая, но на практике, как правило, все недифференцируемые сети являются пороговыми. Отметим, что для того, чтобы сеть была пороговой, достаточно вставить в нее один пороговый элемент.

Основное различие между дифференцируемыми и пороговыми сетями состоит в способе обучения. Для дифференцируемых сетей есть конструктивная процедура обучения, гарантирующая результат, если архитектура сети позволяет ей решит задачу (см. разд. «Оценка способности сети решить задачу») – метод двойственного обучения (обратного распространения ошибки). Следует заметить, что при использовании обучения по методу двойственности так же возникают сложности, типа локальных минимумов. Однако существует набор регулярных процедур, позволяющих с ними бороться (см. например [93]). Для обучения пороговых сетей используют правило Хебба или его модификации. Однако, для многослойных сетей с пороговыми элементами правило Хебба не гарантирует обучения. (В случае однослойных сетей – персептронов, доказана теорема о достижении результата в случае его принципиальной достижимости). С другой стороны, в работе [147] доказано, что многослойные сети с пороговыми нейронами можно заменить эквивалентными двухслойными сетями с не обучаемыми весами первого слоя. В работе [154] предложен подход, позволяющий свести обучение сетей с пороговыми нейронами к обучению дифференцируемых сетей с последующей трансформацией в сеть с пороговыми нейронами.

1.2. Выделение компонентов

Первым основным компонентом нейрокомпьютера является нейронная сеть. Метод двойственности в обучении нейронных сетей предполагает только одно условие на элементы – все элементы сети должны при прямом функционировании иметь характеристические функции из класса  (непрерывно дифференцируемые на области определения , которой, как правило, является вся числовая ось). Нейронная сеть является основным претендентом на аппаратную реализацию, поскольку обладает мелкозернистым параллелизмом и состоит из очень простых элементов.

Для обучения нейронной сети необходимо наличие задачника. Чаще всего, обучение производится не по всему задачнику, а по некоторой его части. Ту часть задачника, по которой в данный момент производится обучение, будем называть обучающей выборкой. Для многих задач обучающая выборка имеет большие размеры (от нескольких сот до нескольких десятков тысяч примеров). При обучении с использованием скоростных методов обучения (их скорость на три-четыре порядка превышает скорость обучения по классическому методу обратного распространения ошибки) приходится быстро сменять примеры. Таким образом, скорость обработки обучающей выборки может существенно влиять на скорость обучения нейронной сети. К сожалению, большинство разработчиков аппаратных средств не предусматривает средств для быстрой смены примеров. С другой стороны аппаратная реализация задачника нецелесообразна, поскольку в качестве задачника может выступать как база данных на универсальном компьютере, так и датчики, регистрирующие параметры некоторой системы.

При работе с обучающей выборкой удобно использовать привычный для пользователя формат данных. Впрочем, дело даже не в удобствах. В главе «Предобработчик» показано, что измеряемая величина далеко не всегда является подходящим сигналом для нейронной сети. Таким образом, между обучающей выборкой и нейросетью возникает дополнительный компонент нейрокомпьютера – предобработчик. Из литературных источников следует, что разработка эффективных предобработчиков для нейрокомпьютеров является новой, почти совсем не исследованной областью. Большинство разработчиков программного обеспечения для нейрокомпьютеров склонно возлагать функции предобработки входных данных на обучающую выборку или вообще перекладывают ее на пользователя. Это решение технологически неверно. Дело в том, что при постановке задачи для нейрокомпьютера трудно сразу угадать правильный способ предобработки. Для его подбора проводится серия экспериментов. В каждом из экспериментов используется одна и та же обучающая выборка и разные способы предобработки входных данных. Таким образом, выделен третий важный компонент нейрокомпьютера – предобработчик входных данных. В отличии от задачника, при аппаратной реализации нейрокомпьютера компонент предобработчик целесообразно также реализовывать аппаратно, поскольку вне зависимости от источника входных данных предобработка не меняется.

Заметим, что если привычный для человека способ представления входных данных непригоден для нейронной сети, то и формат ответов нейронной сети часто малопригоден для человека. Необходимо интерпретировать ответы нейронной сети. Интерпретация зависит от вида ответа. Так, если ответом нейронной сети является действительное число, то его, как правило, приходится масштабировать и сдвигать для попадания в нужный диапазон ответов. Если сеть используется как классификатор, то выбор интерпретаторов еще шире. Большое разнообразие интерпретаторов при невозможности решить раз и навсегда вопрос о преимуществах одного из них над другими приводит к необходимости выделения интерпретатора ответа нейронной сети в отдельный компонент нейрокомпьютера.

С интерпретатором ответа тесно связан еще один обязательный компонент нейрокомпьютера – оценка. Невнимание к этому компоненту вызвано практикой рассматривать метод обратного распространения ошибки в виде алгоритма. Доминирование такой точки зрения привело к тому, что, судя по публикациям, большинство исследователей даже не подозревает о том, что «уклонение от правильного ответа», подаваемое на вход сети при обратном функционировании, есть ни что иное, как производная функции оценки по выходному сигналу сети (если функция оценки является суммой квадратов уклонений). Возможно (и иногда очень полезно) конструировать другие оценки (см. главу «Оценка и интерпретатор ответа»). Группой НейроКомп в ходе численных экспериментов было выяснено, что для обучения сетей-классификаторов функция оценки вида суммы квадратов, пожалуй, наиболее плоха. Использование альтернативных функций оценки позволяет в несколько раз ускорить обучение нейронной сети.

Шестым необходимым компонентом нейрокомпьютера является учитель. Этот компонент может иметь множество реализаций. Обзор наиболее часто употребляемых и наиболее эффективных учителей приводится в главе «Учитель».

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

1.   Тестирование решения примера

1.1. Взять пример у задачника.

1.2. Предъявить его сети для решения.

1.3. Предъявить результат интерпретатору ответа.

2.   Оценивание решения примера

2.1. Взять пример у задачника.

2.2. Предъявить его сети для решения.

2.3. Предъявить результат оценке.

3.   Оценивание решения примера с вычислением градиента.

3.1. Взять пример у задачника.

3.2. Предъявить его сети для решения.

3.3. Предъявить результат оценке с вычислением производных.

3.4. Предъявить результат работы оценки сети для вычисления градиента.

4.   Оценивание и тестирование решения примера.

4.1. Взять пример у задачника.

4.2. Предъявить его сети для решения.

4.3. Предъявить результат оценке.

4.4. Предъявить результат интерпретатору ответа.

Все четыре варианта работы с сетью, задачником, интерпретатором ответа и оценкой легко объединить в один запрос, параметры которого позволяют указать последовательность действий. Таким образом, исполнитель исполняет всего один запрос – обработать пример. Однако выделение этого компонента позволяет исключить необходимость в прямых связях таких компонентов, как контрастер и учитель, с компонентами оценка и интерпретатор ответа, а их взаимодействие с компонентом сеть свести исключительно к запросам связанным с модификацией обучаемых параметров сети.

Последним компонентом, которого необходимо выделить, является контрастер нейронной сети. Этот компонент является надстройкой над учителем. Его назначение – сводить число связей сети до минимально необходимого или до «разумного» минимума (степень разумности минимума определяется пользователем). Кроме того, контрастер, как правило, позволяет свести множество величин весов связей к 2-4, реже к 8 выделенным пользователем значениям. Наиболее важным следствием применения процедуры контрастирования является получение логически прозрачных сетей – сетей, работу которых легко описать и понять на языке логики [80, 81].

Для координации работы всех компонентов нейрокомпьютера вводится макрокомпонента Нейрокомпьютер. Основная задача этого компонента – организация интерфейса с пользователем и координация действий всех остальных компонентов.

В литературе по нейроинформатике (см. например, [226, 227]) встречаются такие понятия как «соревновательные нейроны» и «обучение без учителя». Для определения места этих понятий, относящихся к сетям Кохонена [130, 131] рассмотрим более подробно работу нейрокомпьютера, реализующего сеть Кохонена. Сеть Кохонена состоит из изолированных нейронов (см. рис. 18 к главе 4). Работа нейрокомпьютера при решении примера состоит из следующих этапов:

1. Из задачника выбирается очередной пример

2. Выбранный пример предобрабатывается.

3. Полученные в результате предобработки данные подаются на вход сети. С выхода сети снимается вектор действительных чисел (работает компонент сеть).

4. Полученный выходной вектор интерпретируется максимальным интерпретатором (см. главу «Оценка и интерпретатор ответа»).

5. При необходимости доучивания вычисляется вектор поправок к выходным сигналам сети (работает компонент оценка).

6. Вычисленный вектор поправок подается на выход сети. На входах весов сети снимается вектор поправок к весам сети (работает компонент сеть).

7. После того, как этапы 1 – 6 проведены для всех примеров задачника проводится обучение сети (работает компонент учитель).

Таким образом в сети Кохонена нет «соревновательных элементов». То, что понимаю под этим термином – работа интерпретатора ответа. Название «обучение без учителя» – некорректная метафора, поскольку при обучении сети Кохонена проводится минимизация функции оценки (см. например, [93]), и производится она с использованием компонента учитель.

1.3. Запросы компонентов нейрокомпьютера

В этом разделе приводится список основных запросов, которые обеспечивают функционирование нейрокомпьютера. За редким исключением приводятся только запросы, которые генерируются компонентами нейрокомпьютера (некоторые из этих запросов могут поступать в нейрокомпьютер от пользователя). Здесь рассматривается только форма запроса и его смысл. Полный список запросов каждого компонента, детали их исполнения и форматы данных рассматриваются в соответствующих главах.

Рис 1. Схема запросов в нейрокомпьютере

На рис. 1. приведена схема запросов в нейрокомпьютере. При построении схемы предполагается, что на каждый запрос приходит ответ. Вид ответа описан при описании запросов. Стрелки, изображающие запросы, идут от объекта, инициирующего запрос, к объекту его исполняющему.

1.3.1. Запросы к задачнику

Запросы к задачнику позволяют последовательно перебирать все примеры обучающей выборки, обращаться непосредственно к любому примеру задачника и изменять обучающую выборку. Обучающая выборка выделяется путем «раскрашивания» примеров задачника в различные «цвета». Понятие цвета и способ работы с цветами описаны в разделе «Переменные типа цвет и операции с цветами».

Запросы последовательного перебора обучающей выборки:

«Инициировать выдачу примеров цвета К». По этому запросу происходит инициация выдачи примеров К-го цвета.

«Дать очередной пример». По этому запросу задачник возвращает предобработанные данные очередного примера и, при необходимости, правильные ответы, уровень достоверности и другие данные этого примера.

«Следующий пример». По этому запросу задачник переходит к следующему примеру обучающей выборки. Если такого примера нет, то возвращается признак отсутствия очередного примера.

Для непосредственного доступа к примерам задачника служит запрос «Дать пример номер N». Действия задачника в этом случае аналогичны выполнению запроса «Дать очередной пример».

Для изменения обучающей выборки служит запрос «Окрасить примеры в цвет К». Этот запрос используется редко, поскольку изменение обучающей выборки, как правило, осуществляется пользователем при редактировании задачника.

1.3.2. Запрос к предобработчику

Предобработчик сам никаких запросов не генерирует. Единственный запрос к предобработчику – «Предобработать пример» может быть выдан только задачником.

1.3.3. Запрос к исполнителю

«Обработать очередной пример». Вид ответа зависит от параметров запроса.

1.3.4. Запросы к учителю

«Начать обучение сети». По этому запросу учитель начинает процесс обучения сети.

«Прервать обучение сети». Этот запрос приводит к прекращению процесса обучения сети. Этот запрос требуется в случае необходимости остановить обучение сети до того, как будет удовлетворен критерий остановки обучения, предусмотренный в учителе.

«Провести N шагов обучения» – как правило, выдается контрастером, необходим для накопления показателей чувствительности.

1.3.5. Запрос к контрастеру

«Отконтрастировать сеть». Ответом является код завершения операции контрастирования.

1.3.6. Запрос к оценке

Оценка не генерирует никаких запросов. Она выполняет только один запрос – «Оценить пример». Результатом выполнения запроса является оценка примера и, при необходимости, вектор производных оценки по выходным сигналам сети.

1.3.7. Запрос к интерпретатору ответа

Интерпретатор ответа не генерирует никаких запросов. Он выполняет только один запрос – «Интерпретировать ответ». Ответом является результат интерпретации.

1.3.8. Запросы к сети

Сеть не генерирует никаких запросов. Набор исполняемых сетью запросов можно разбить на три группы.

Запрос, обеспечивающий тестирование.

«Провести прямое функционирование». На вход сети подаются данные примера. На выходе сети вычисляется ответ сети, подлежащий оцениванию или интерпретации.

Запросы, обеспечивающие обучение сети.

«Обнулить градиент». При исполнении этого запроса градиент оценки по обучаемым параметрам сети кладется равным нулю. Этот запрос необходим, поскольку при вычислении градиента по очередному примеру сеть добавляет его к ранее вычисленному градиенту по сумме других примеров.

«Вычислить градиент по примеру». Проводится обратное функционирование сети. Вычисленный градиент добавляется к ранее вычисленному градиенту по сумме других примеров.

«Изменить карту с шагами Н1 и H2». Генерируется учителем во время обучения.

Запрос, обеспечивающие контрастирование.

«Изменить карту по образцу». Генерируется контрастером при контрастировании сети.

Таким образом, выделено семь основных компонентов нейрокомпьютера, определены их функции и основные исполняемые ими запросы.

1.4. Запросы общие для всех компонентов

В этом разделе описаны запросы, выполняемых всеми компонентами, а также типы данных, используемые при описании запросов.

1.4.1. Стандарт типов данных

При описании запросов и структур данных необходимо использовать набор первичных типов данных. Поскольку в разных языках программирования типы данных называются по-разному, введем единый набор обозначений для них.

Таблица 1.

Типы данных для всех компонентов нейрокомпьютера

Тип

Длина (байт)

Значения

Описание

Color

2

Используется для задания цветов. Является совокупностью из 16 элементарных (битовых) флагов. См. раздел «Цвет и операции с цветами».

Real

4

от ±1.5 e- 45

до ±3.4 e 38

Действительное число. Величина из указанного диапазона.. В дальнейшем называется «действительное».

RealArray

4*N

Массив действительных чисел.

PRealArray

4

Используется для передачи массивов между компонентами. Имеет значение адреса массива действительных чисел.

Integer

2

От -32768

До 32767

Целое число из указанного диапазона. В дальнейшем называется «целое».

IntegerArray

2*N

Массив целых чисел.

PIntegerArray

4

Используется для передачи массивов между компонентами. Имеет значение адреса массива целых чисел.

Таблица 1.

Типы данных для всех компонентов нейрокомпьютера (Продолжение)

Тип

Длина (байт)

Значения

Описание

Long

4

От -2147483648

До 2147483647

Целое число из указанного диапазона. В дальнейшем называется «длинное целое».

LongArray

4*N

Массив длинных целых чисел.

PlongArray

4

Используется для передачи массивов между компонентами. Имеет значение адреса массива длинных целых чисел.

Logic

1

True, False

Логическая величина. Далее называется «логическая».

LogicArray

N

Массив логических переменных.

PLogicArray

4

Используется для передачи массивов между компонентами. Имеет значение адреса массива логических переменных.

FuncType

4

Адрес функции. Используется при необходимости передать функцию в качестве аргумента.

String

256

Строка символов.

PString

4

Адрес строки символов. Служит для передачи строк в запросах

Pointer

4

Не типизованный указатель (адрес). Этот тип совместим с любым типизованным указателям.

Числовые типы данных Integer, Long и Real предназначены для хранения различных чисел. Переменные числовых типов допускаются в языках описания всех компонентов нейрокомпьютера. При необходимости записать в один массив числовые переменные различного типа следует использовать функции приведения типов, описанные в разделе «Приведение типов»

Строка. Символьный тип данных предназначен для хранения комментариев, названий полей, имен сетей, оценок и другой текстовой информации. Все строковые переменные занимают 256 байт и могут включать в себя до 255 символов. Первый байт строки содержит длину строки. В переменных типа строка возможен доступ к любому символу как к элементу массива. При этом длина имеет индекс ноль, первый символ – 1 и т.д.

Указатель на строку. При передаче данных между компонентами сети и процедурами в пределах одного компонента удобно вместо строки передавать указатель на строку, поскольку указатель занимает всего четыре байта. Для этой цели служит тип указатель на строку.

Логический тип используется для хранения логических значений. Значение истина задается предопределенной константой True, значение ложь – False.

Массивы. В данном стандарте предусмотрены массивы четырех типов – логических, целочисленных, длинных целых и действительных переменных. Длины массивов определяются при описании, но все массивы переменных одного типа относятся к одному типу, в отличие от языков типа Паскаль. Использование функций приведения и преобразования типов позволяют получать из этих массивов структуры произвольной сложности. Элементы массивов всегда нумеруются с единицы.

Вне зависимости от типа массива нулевой элемент массива имеет тип Long и содержит длину массива в элементах. На рис. 2 приведена схема распределения памяти всех типов массивов, каждый из которых содержит шесть элементов. Все массивы, как правило, используется только в пределах одного компонента. При передаче массивов между компонентами или между процедурами в пределах одного компонента используются указатели на массивы.

Адрес функции. Этот тип используется для передачи функции в качестве аргумента. Переменная типа FuncType занимает четыре байта и является адресом функции. В зависимости от реализации по этому адресу может лежать либо начало машинного кода функции, либо начало текста функции. В случае передачи текста функции первые восемь байт по переданному адресу содержат слово «Function».

1.4.2. Переменные типа цвет и операции с цветами

Использование цветов позволяет гибко разбивать множества на подмножества. В нейрокомпьютере возникает необходимость в разбиении на подмножества (раскрашивании) задачника. В этом разделе описывается стандарт работы с переменными типа цвет. Ближайшей аналогией переменных типа цвет является тип данных Set в языке Паскаль.

1.4.2.1. Значение переменной типа цвет (Color)

Переменная типа цвет представляет собой двухбайтовое беззнаковое целое. Однако основное использование предполагает работу не как с целым числом, а как с совокупностью однобитных флагов. При записи на диск используется символьное представление двоичной записи числа с ведущими нулями и разбиением на четверки символом «.» (точка), предваряемая заглавной буквой «B» латинского алфавита, или символьное представление шестнадцатеричной записи числа с ведущими нулями, предваряемая заглавной буквой «H» латинского алфавита. В табл. 2 приведена нумерация флагов (бит) переменной типа Color, их шестнадцатеричное, десятичное и двоичное значение. При использовании в учителе или других компонентах может возникнуть необходимость в присвоении некоторым из флагов или их комбинаций имен. На такое именование не накладывается никаких ограничений, хотя возможно будет выработан стандарт и на названия часто используемых цветов (масок, совокупностей флагов).

Таблица 2

Нумерация флагов (бит) переменной типа Color

Номер

Шестнад-цатиричная запись

Деся-тичная запись

Двоичная запись

0

H0001

1

B.0000.0000.0000.0001

1

H0002

2

B.0000.0000.0000.0010

2

H0004

4

B.0000.0000.0000.0100

3

H0008

8

B.0000.0000.0000.1000

4

H0010

16

B.0000.0000.0001.0000

5

H0020

32

B.0000.0000.0010.0000

6

H0040

64

B.0000.0000.0100.0000

7

H0080

128

B.0000.0000.1000.0000

8

H0100

256

B.0000.0001.0000.0000

9

H0200

512

B.0000.0010.0000.0000

10

H0400

1024

B.0000.0100.0000.0000

11

H0800

2048

B.0000.1000.0000.0000

12

H1000

4096

B.0001.0000.0000.0000

13

H2000

8192

B.0010.0000.0000.0000

14

H4000

16384

B.0100.0000.0000.0000

15

H8000

32768

B.1000.0000.0000.0000

1.4.2.2. Операции с переменными типа цвет (Color)

В табл. 3 приведены операции с переменными типа Color. Первые пять операций могут использоваться только для сравнения переменных типа Color, а остальные четыре операции – для вычисления выражений типа Color.

В ряде запросов необходимо указать тип операции над цветом. Для передачи таких параметров используется переменная типа Integer. В качестве значений передается содержимое соответствующей ячейки столбца код табл. 3.

Таблица 3

Предопределенные константы операций с переменными типа Цвет (Color)

Код

Обозначение

Выражение

Тип результата

Пояснение

1

CEqual

A = B

Logic

Полное совпадение.

2

CIn

A And B = A

Logic

A содержится в В.

3

CInclude

A And B = B

Logic

А содержит В.

4

CExclude

A And B = 0

Logic

A и В взаимоисключающие.

5

CIntersect

A And B <> 0

Logic

А и В пересекаются.

6

COr

A Or B

Сolor

Побитное включающее или.

7

CAnd

A And B

Color

Побитное и.

8

CXor

A Xor B

Color

Побитное исключающее или

9

CNot

Not A

Color

Побитное отрицание

1.4.3. Предопределенные константы

При описании различных компонентов возникает необходимость в использовании некоторого набора стандартизированных констант. Стандартность набора констант особенно необходима при обмене данными между компонентами. Все константы, приведенные в табл. 4, описываются в тех разделах, где они используются. В табл. 4 для каждой константы указывается ее тип, значение и названия разделов, в которых она описывается.

Таблица 4

Предопределенные константы

Идентификатор

Тип

Значение

Шестнад.

Десятичн.

BackInSignals

Integer

H0005

5

Запросы к компоненту сеть

BackOutSignals

Integer

H0006

6

Запросы к компоненту сеть

BackParameters

Integer

H0007

7

Запросы к компоненту сеть

Binary

Integer

H0001

1

Запросы компонента интерпретатор ответа

BinaryPrep

Integer

H0000

0

Запросы компонента предобработчик

Таблица 4

Предопределенные константы (Продолжение)

Идентификатор

Тип

Значение

Раздел

Шестнад.

Десятичн.

BynaryCoded

Integer

H0003

3

Запросы компонента интерпретатор ответа

CAnd

Integer

H0007

7

Операции с переменными типа цвет (Color)

Cascad

Integer

H0002

2

Запросы к компоненту сеть

Cequal

Integer

H0001

1

Операции с переменными типа цвет (Color)

CExclude

Integer

H0004

4

Операции с переменными типа цвет (Color)

CicleFor

Integer

H0003

3

Запросы к компоненту сеть

CicleUntil

Integer

H0004

4

Запросы к компоненту сеть

CIn

Integer

H0002

2

Операции с переменными типа цвет (Color)

CInclude

Integer

H0003

3

Операции с переменными типа цвет (Color)

CIntersect

Integer

H0005

5

Операции с переменными типа цвет (Color)

CNot

Integer

H0009

9

Операции с переменными типа цвет (Color)

COr

Integer

H0006

6

Операции с переменными типа цвет (Color)

CXor

Integer

H0008

8

Операции с переменными типа цвет (Color)

Element

Integer

H0000

0

Запросы к компоненту сеть

Empty

Integer

H0000

0

Запросы компонента интерпретатор ответа

EmptyPrep

Integer

H0003

3

Запросы компонента предобработчик

False

Logic

H00

 

FuncPrep

Integer

H0005

5

Запросы компонента предобработчик

InSignalMask

Integer

H0003

3

Запросы к компоненту сеть

InSignals

Integer

H0000

0

Запросы к компоненту сеть

Layer

Integer

H0001

1

Запросы к компоненту сеть

Major

Integer

H0002

2

Запросы компонента интерпретатор ответа

ModPrep

Integer

H0004

4

Запросы компонента предобработчик

Таблица 4

Предопределенные константы (Продолжение)

Идентификатор

Тип

Значение

Раздел

Шестнад.

Десятичн.

Null

Pointer

H00000000

Нет

Ordered

Integer

H0002

2

Запросы компонента предобработчик

OutSignals

Integer

H0001

1

Запросы к компоненту сеть

Parameters

Integer

H0002

2

Запросы к компоненту сеть

ParamMask

Integer

H0004

4

Запросы к компоненту сеть

PositPrep

Integer

H0006

6

Запросы компонента предобработчик

tbAnswers

Integer

H0004

4

Язык описания задачника

tbCalcAnswers

Integer

H0006

6

Язык описания задачника

tbCalcReliability

Integer

H0007

7

Язык описания задачника

tbColor

Integer

H0001

1

Язык описания задачника

tbComment

Integer

H000A

10

Язык описания задачника

tbEstimation

Integer

H0009

9

Язык описания задачника

tbInput

Integer

H0002

2

Язык описания задачника

tbPrepared

Integer

H0003

3

Язык описания задачника

tbReliability

Integer

H0005

5

Язык описания задачника

tbWeight

Integer

H0008

8

Язык описания задачника

True

Logic

HFF

-1

UnknownLong

Integer

H0000

0

Неопределенные значения

UnknownReal

Real

нет

1E-40

Неопределенные значения

UnOrdered

Integer

H0001

1

Запросы компонента предобработчик

UserType

Integer

HFFFF

-1

Структурная единица, определенная пользователем.

Три предопределенные константы, приведенные в табл. 4, не описываются ни в одном разделе данной работы. Это константы общего пользования. Их значение:

True – значение истина для присваивания переменным логического типа.

False – значение ложь для присваивания переменным логического типа.

Null – пустой указатель. Используется для сравнения или присваивания переменным всех типов указателей.

1.4.4. Использование памяти

Ряд запросов, исполняемых различными компонентами, возвращают в качестве ответа указатели на массивы. В этих случаях действуют следующие правила:

1. Если компонент получил пустой указатель (Null), то он сам создает массив необходимой длины.

2. Если передан непустой указатель, но существующей длины массива недостаточно, то компонент освобождает память, занятую под переданный массив и создает новый массив необходимой длины.

3. Освобождение памяти после использования массива лежит на вызывающем компоненте.

Если одному из компонентов не хватает памяти для выполнения запроса, то этот компонент может передать макрокомпоненту нейрокомпьютер запрос на дополнительную память. В этом случае макрокомпонент нейрокомпьютер передает всем компонентам запрос FreeMemory. При исполнении данного запроса каждый компонент должен освободить всю память, не являющуюся абсолютно необходимой для работы. Например, компонент задачник может для быстроты обработки держать в памяти все обучающее множество. Однако абсолютно необходимой является память, достаточная для хранения в памяти одного примера.

Запрос на освобождение памяти исполняется каждым компонентом и не включен в описания запросов компонентов, приведенные в следующих главах.

1.4.5. Обработка ошибок

Схема обработки ошибок достаточно проста по своей идее - каждый новый обработчик ошибок может обрабатывать только часть ошибок, а обработку остальных может передать ранее установленному обработчику. Пользователь может организовать обработку ошибок и не прибегая к установке обработчика ошибок - обработчик ошибок по умолчанию почти во всех случаях устанавливает номер последней ошибки в переменную Error, которая может быть считана с помощью запроса GetError и обработана прямо в компоненте, выдавшем запрос.

Если обработчик ошибок устанавливает номер последней ошибки в переменной Error, то все запросы, поступившие после момента установки, завершаются неуспешно. Это состояние сбрасывается при вызове запроса «дать номер ошибки».

1.4.5.1. Процедура обработки ошибок

          Процедура обработки ошибок должна быть процедура с дальним типом адресации. Формат описания процедуры обработки ошибок

Pascal:

Procedure ErrorFunc( ErrorNumber : Long ); Far;

C:

void far ErrorFunc(Long ErrorNumber)

I. После обработки ошибок процедура может вызвать ранее установленный обработчик ошибок. Адрес ранее установленного обработчика ошибок процедура обработки ошибок получает в ходе следующей процедуры:

A. Вызов процедуры с нулевым номером ошибки означает, что в следующем вызове будет передан адрес старой процедуры обработки ошибок.

B.   Значение аргумента ErrorNumber при вызове, следующем непосредственно за вызовом с нулевым номером ошибки, должно интерпретироваться как адрес старой процедуры обработки ошибок.

Ниже приведено описание запросов, связанных с обработкой ошибок и исполняемых макрокомпонентом нейрокомпьютер.

1.4.5.2. Установить обработчик ошибок (OnError)

Описание запроса:

Pascal:

Function OnError( NewError : ErrorFunc ) : Logic;

C:

Logic OnError(ErrorFunc NewError)

Описание аргументов:

NewError - адрес новой процедуры обработки ошибок.

Назначение – устанавливает новый обработчик ошибок.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Вызов NewError с аргументом 0 - настройка на установку цепочки обработки ошибок.

3. Вызов NewError с аргументом ErrorManager (вместо длинного целого передается адрес старой процедуры обработки ошибок).

4. ErrorManager := NewError

1.4.5.3. Дать номер ошибки (GetError)

Описание запроса:

Pascal:

Function GetError : Integer;

C:

Integer GetError()

Назначение - возвращает номер последней необработанной ошибки и сбрасывает ее.

Описание исполнения.

1. GetError := Error

2. Error := 0

Списки ошибок, возникающих в различных компонентах, даны в разделах «Ошибки компоненты ...», в соответствующих главах. Все номера ошибок каждого компонента являются трехзначными числами и начинаются с номера компонента, указанного в колонке «Ошибка» табл. 5.

1.4.6. Запросы, однотипные для всех компонентов

Таблица 5

Префиксы компонентов

Префикс

Компонент

Запроса

Ошибки


ex

0

Исполнитель

tb

1

Задачник

pr

2

Предобработчик

nn

3

Сеть

es

4

Оценка

ai

5

Интерпретатор ответа

in

6

Учитель

cn

7

Контрастер

Ряд запросов обрабатывается всеми компонентами, кроме компонента исполнитель, носящего вспомогательный характер. Один из таких запросов – FreeMemory – был описан в разделе «Управление памятью», а два запроса, связанных с обработкой ошибок – в разделе «Обработка ошибок». В данном разделе приводятся описания остальных запросов, имеющих одинаковый смысл для всех компонентов. В отличие от ранее описанных запросов эти запросы опираются на структуру исполняющего компонента, поэтому к имени запроса добавляется префикс, задающий компонента. Список префиксов приведен в табл. 5. Единственным исключением из числа компонентов, исполняющих перечисленные в данном разделе запросы, является компонент исполнитель.

Все описываемые в данном разделе запросы можно разбить на четыре группы:

1. Установление текущего компонента.

2. Запросы работы со структурой компонента.

3. Запросы на получение или изменение параметров структурной единицы.

4. Запуск редактора компонента.

Все имена запросов начинаются с символов «xx», которые необходимо заменить на префикс из табл. 5 чтобы получить имя запроса для соответствующего компонента. При указании ошибок используется символ «n», который нужно заменить на соответствующий префикс ошибки из табл. 5.

Далее данном разделе компонентом также называются экземпляры компонента, а не только часть программы. Например, одна из загруженных нейронных сетей, а не только программный компонент сеть.

1.4.6.1. Запрос на установление текущего компонента

К этой группе запросов относится один запрос – xxSetCurrent – не исполняемый компонентом задачник.

Сделать текущей (xxSetCurrent)

Описание запроса:

Pascal:

Function xxSetCurrent( CompName : PString) : Logic;

C:

Logic xxSetCurrent(PString CompName)

Описание аргумента:

CompName – указатель на строку символов, содержащую имя компонента, которого надо сделать текущим.

Описание исполнения.

1. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

2. Указанный в аргументе CompName компонент переносится в начало списка.

1.4.6.2. Запросы, работающие со структурой компонента

К этой группе относятся запросы, позволяющие выяснить структуру компонента, прочитать ее или сохранить на диске.

Добавление нового экземпляра (xxAdd)

Описание запроса:

Pascal:

Function xxAdd( CompName : PString ) : Logic;

C:

Logic xxAdd(PString CompName)

Описание аргумента:

CompName – указатель на строку символов, содержащую имя файла компонента или адрес описания компонента.

Назначение – добавляет новый экземпляр компонента в список компонентов.

Описание исполнения.

1. Если в качестве аргумента CompName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя компонента и после пробела имя файла, содержащего компонента. В противном случае считается, что аргумент CompName содержит указатель на область памяти, содержащую описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то допускается включение в текст описания компонента ключевого слова Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

2. Экземпляр компонента считывается из файла или из памяти и добавляется первым в список компонентов (становится текущим).

3. Если считывание завершается по ошибке, то возникает ошибка n02 – ошибка считывания компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

Удаление экземпляра компонента (xxDelete)

Описание запроса:

Pascal:

Function xxDelete( CompName : PString) : Logic;

C:

Logic xxDelete(PString CompName)

Описание аргумента:

CompName – указатель на строку символов, содержащую полное имя компонента.

Назначение – удаляет указанного в параметре CompName компонента из списка компонентов.

Описание исполнения.

1. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

Заметим, что попытка удаления младшей структурной единицы приводит к удалению всего компонента содержащего данную структурную единицу.

Запись компонента (xxWrite)

Описание запроса:

Pascal:

Function xxWrite( CompName : PString; FileName : PString) : Logic;

C:

Logic xxWrite(PString CompName, PString FileName)

Описание аргументов:

CompName – указатель на строку символов, содержащую имя компонента.

FileName – имя файла или адрес памяти, куда надо записать компонента.

Назначение – сохраняет в файле или в памяти компонента, указанного в аргументе CompName .

Описание исполнения.

1. Если в качестве аргумента CompName дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является текущий компонент.

2. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Если в качестве аргумента FileName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя файла, для записи компонента. В противном случае FileName должен содержать пустой указатель. В этом случае запрос вернет в нем указатель на область памяти, куда будет помещено описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то в текст будет включено ключевое слово Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

4. Если во время сохранения компонентà возникнет ошибка, то генерируется ошибка n03 – ошибка сохранения компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

Вернуть имена структурных единиц (xxGetStructNames)

Описание запроса:

Pascal:

Function xxGetStructNames(CompName : PString; Var Names : PRealArray) : Logic;

C:

Logic xxGetStructNames(PString CompName, RealArray* Names)

Описание аргументов:

CompName – указатель на строку символов, содержащую имя компонента или полное имя его структурной единицы.

Names – массив указателей на имена структурных единиц.

Назначение – возвращает имена всех компонентов в списке компонентов или имена всех структурных единиц структурной единицы, указанной в аргументе CompName .

Описание исполнения.

1. Если в качестве аргумента CompName дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является соответствующий программный компонент. В качестве ответа в указателе Names возвращается массив, каждый элемент которого является указателем на не подлежащую изменению символьную строку, содержащую имя компонента из списка. После адреса имени последнего компонента следует пустой указатель. Выполнение запроса успешно завершается.

2. Если имя компонента, переданное в аргументе CompName, не найдено в списке компонентов, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Возвращается массив, каждый элемент которого является указателем на не подлежащую изменению символьную строку, содержащую псевдоним структурной единицы, являющейся частью структурной единицы, указанной в аргументе CompName. Имена структурных единиц перечисляются в порядке следования в разделе описания состава структурной единицы, имя которой указано в аргументе CompName. Если одна из структурных единиц задана в описании состава несколькими экземплярами, то имя каждого экземпляра возвращается отдельно. После указателя на имя последней структурной единицы следует пустой указатель.

Вернуть тип структурной единицы (xxGetType)

Описание запроса:

Pascal:

Function xxGetType(CompName , TypeName : PString; Var TypeId : Integer) : Logic;

C:

Logic xxGetType(PString CompName, PString TypeName, Integer TypeId)

Описание аргументов:

CompName – указатель на строку символов, содержащую полное имя структурной единицы.

TypeName – возвращает указатель на строку символов, содержащую имя структурной единицы, данное ей при описании.

TypeId – одна из предопределенных констант, соответствующая типу структурной единицы.

Назначение – возвращает имя и тип структурной единицы.

Описание исполнения.

1. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

2. В переменной TypeId возвращается тип структурной единицы. Значения предопределенных констант, соответствующих различным типам структурных единиц различных компонентов приведены в табл. 4 и в соответствующих разделах глав, содержащих описания компонентов.

3. Если структурная единица является стандартной, то указателю TypeName присваивается значение пустого указателя. Если структурная единица имеет пользовательский тип (значение аргумента TypeId равно -1), то указатель TypeName устанавливается на строку, содержащую имя, данное указанной в аргументе CompName структурной единице при ее описании.

1.4.6.3. Запросы на изменение параметров

К группе запросов на изменение параметров относятся три запроса: xxGetData – получить параметры структурной единицы. xxGetName – получить названия параметров и xxSetData – установить значения параметров структурной единицы.

Получить параметры (xxGetData)

Описание запроса:

Pascal:

Function xxGetData( CompName : PString; Var Param : PRealArray ) : Logic;

C:

Logic xxGetData(PString CompName, PRealArray* Param)

Описание аргументов:

CompName – указатель на строку символов, содержащую полное имя структурной единицы.

Param – адрес массива параметров.

Назначение – возвращает массив параметров структурной единицы, указанной в аргументе CompName .

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. В массив, адрес которого передан в аргументе Param, заносятся значения параметров. Параметры заносятся в массив в порядке описания в разделе описания статических переменных. Статические переменные, описанные вне описания структурных единиц, считаются параметрами компонента.

Получить имена параметров (xxGetName)

Описание запроса:

Pascal:

Function xxGetName( CompName : PString; Var Param : PRealArray ) : Logic;

C:

Logic xxGetName(PString CompName, PRealArray* Param)

Описание аргументов:

CompName – указатель на строку символов, содержащую полное имя структурной единицы.

Param – адрес массива указателей на названия параметров.

Назначение – возвращает массив указателей на названия параметров структурной единицы, указанной в аргументе CompName .

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. В массив, адрес которого передан в аргументе Param, заносятся адреса символьных строк, содержащих названия параметров.

Установить параметры (xxSetData)

Описание запроса:

Pascal:

Function xxSetData( CompName : PString; Param : PRealArray ) : Logic;

C:

Logic xxSetData(PString CompName, PRealArray Param)

Описание аргументов:

CompName – указатель на строку символов, содержащую полное имя структурной единицы.

Param – адрес массива параметров.

Назначение – заменяет значения параметров структурной единицы, указанной в аргументе CompName , на значения, переданные, в аргументе Param.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если список компонентов пуст или имя компонента, переданное в аргументе CompName, в этом списке не найдено, то возникает ошибка n01 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Параметры, значения которых хранятся в массиве, адрес которого передан в аргументе Param, передаются указанной в аргументе CompName структурной единице.

4. Если исполняющим запрос компонентом является интерпретатор ответа (aiSetData), то генерируется запрос SetEstIntParameters к компоненту оценка. Аргументы генерируемого запроса совпадают с аргументами исполняемого запроса.

1.4.6.4. Инициация редактора компоненты

К этой группе запросов относится запрос, который инициирует работу не рассматриваемых в данной работе компонентов – редакторов компонентов.

Редактировать компонента (xxEdit)

Описание запроса:

Pascal:

Procedure xxEdit(CompName : PString);

C:

void xxEdit(PString CompName )

Описание аргумента:

CompName – указатель на строку символов – имя файла или адрес памяти, содержащие описание редактируемого компонента.

Если в качестве аргумента CompName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя компонента и после пробела имя файла, содержащего описание компонента. В противном случае считается, что аргумент CompName содержит указатель на область памяти, содержащую описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то допускается включение в текст описания компонента ключевого слова Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

Если в качестве аргумента CompName передан пустой указатель или указатель на пустую строку, то редактор создает новый экземпляр компонента.

2. Задачник и обучающее множество

Эта глава посвящена одному из наиболее важных и обделенных вниманием компонентов нейрокомпьютера – задачнику. Важность этого компонента определяется тем, что при обучении сетей всех видов с использованием любых алгоритмов обучения сети необходимо предъявлять примеры, на которых она обучается решению задачи. Источником данных для сети является задачник. Кроме того, задачник содержит правильные ответы для сетей, обучаемых с учителем. Аппаратная реализация этого компонента в общем случае неэффективна.

В этой главе рассматриваются основные структуры и функции компонента задачник. Отметим, что задачник рассматривается только с точки зрения его использования нейронной сетью. Совершенно очевидно, что невозможно предусмотреть всех вариантов интерфейса между пользователем и задачником. Действительно, было бы странно, если бы в одном и том же интерфейсе обрабатывались задачники, содержащие только числовые поля, задачники, содержащие исключительно графическую информацию и задачники смешанного типа.

2.1. Структуры данных задачника

С точки зрения нейрокомпьютера задачник представляет собой прямоугольную таблицу, поля которой содержат информацию о входных данных примеров задачи, правильные ответы и другую информацию. На данный момент существует три основных способа хранения однотипных данных – базы данных, электронные таблицы, текстовые файлы. Основными критериями выбора являются удобство в использовании, компактность и универсальность. Поскольку задачник должен хранить однотипные данные и предоставлять их для обработки другим компонентам нейрокомпьютера, а не производить вычисления, то функционально задачник должен являться базой данных. Наиболее подходящим кажется формат табличных (реляционных) баз данных.

В современных операционных системах предусмотрены различные способы обмена данными между приложениями (устройства, передающие информацию с датчиков, так же будем считать приложениями). Наиболее универсальным является обмен в символьном формате. Вопрос конкретной реализации обмена выходит за рамки данной работы, поскольку это чисто технический вопрос. Вне зависимости от того, каким путем и из какого приложения данные попали в задачник, их представление должно быть одинаковым (принятым в данной реализации задачника). То есть, откуда бы не получал данные задачник, остальные компоненты нейрокомпьютера всегда получают данные от задачника в одном и том же виде. Этот вид зафиксирован в приложении при описании стандарта компонента задачник.

2.2. Поля задачника

Далее будем полагать, что задачник является реляционной базой данных из одной таблицы или набора параллельных таблиц. Каждому примеру соответствует одна запись базы данных. Каждому данному – одно поле. В данном разделе рассмотрены допустимые типы полей, с точки зрения типа хранящихся в них данных. В разд. «Состав данных задачника» все поля разбиваются по смысловой нагрузке. Все поля базы данных можно разбить на четыре типа – числовые поля, текстовые поля, перечислимые поля и поля типа рисунок.

Числовые поля. Поля числовых типов данных Integer, Long и Real (см. раздел «Стандарт типов данных в приложении) предназначены для хранения различных чисел. Поля числового типа могут нести любую смысловую нагрузку.

Перечислимые поля. Поля перечислимого типа служат для хранения качественных признаков – полей базы данных, содержащих, как правило, текстовую информацию, но имеющих малое число различных значений. Простейшим примером поля перечислимого типа является поле «пол» – это поле может принимать только два значения – «мужской» или «женский». Поле перечислимого типа не хранит соответствующего текстового значения, вместо него в поле содержится номер значения. Поля перечислимого типа могут быть только входными данными, комментариями или ответами.

Строки (текстовые поля). Поля текстового типа предназначены для хранения тестовой информации. Они могут быть только комментариями.

Рисунок. Поля типа рисунок предназначены для хранения графической информации. В данной работе не устанавливается способ хранения полей типа рисунок. В приложении оговаривается только способ хранения полей типа рисунок на диске для файлов задачника, созданного в нейрокомпьютере. При передаче рисунков предобработчику используется формат, согласованный для предобработчика и задачника.

2.3. Состав данных задачника

Компонент задачник является необходимой частью нейрокомпьютера вне зависимости от типа применяемых в нем нейронных сетей. Однако в зависимости от решаемой задачи содержимое задачника может меняться. Так, например, для решения задачи классификации без учителя используют нейросети, основанные на методе динамических ядер [229, 267] (наиболее известным частным случаем таких сетей являются сети Кохонена [130, 131]). Задачник для такой сети должен содержать только массивы входных данных и предобработанных входных данных. При использовании обучаемых сетей, основанных на принципе двойственности, к задачнику необходимо добавить массив ответов сети. Кроме того, некоторые исследователи хотят иметь возможность просмотреть ответы, выданные сетью, массив оценок примера, показатели значимости входных сигналов и, возможно, некоторые другие величины. Поэтому, стандартный задачник должен иметь возможность предоставить пользователю всю необходимую информацию.

2.3.1. Цвет примера и обучающая выборка

Довольно часто при обучении нейронных сетей возникает необходимость использовать в обучении не все примеры задачника, а только часть. Например, такая возможность необходима при использовании метода скользящего контроля для оценки качества обучения сети. Существует несколько способов реализации такой возможности. Кроме того, часто бывает полезно приписать примерам ряд признаков. Так, при просмотре задачника, пользователю полезно видеть степень обученности примера (например, отображать зеленым цветом примеры, которые решаются сетью идеально, желтым – те, которые сеть решает правильно, но не идеально, а красным – те, при решении которых сеть допускает ошибки).

Ту часть задачника, которая в данный момент используется в обучении нейронной сети, будем называть обучающей выборкой. Для выделения из задачника обучающей выборки предлагается использовать механизм «цветов». Если все примеры покрашены в некоторые цвета, то обучающую выборку можно задать, указав цвета примеров, которые необходимо использовать в обучении. В соответствии с предлагаемой схемой, каждый пример покрашен каким–то цветом, а при задании обучающей выборки можно задать комбинацию цветов. Схема работы с цветами детально рассмотрена в разделе «Переменные типа цвет и операции с цветами» приложения.

Выделенную с помощью механизма цветов часть задачника будем далее называть текущей выборкой. Обучающая выборка является частным случаем текущей выборки.

2.3.2. Входные данные

Входные данные – данные, необходимые для решения сетью примера. Входные данные являются массивом. Существует всего несколько видов входных данных. Каждый элемент массива входных данных может быть: числом; полем с ограниченным числом состояний; рисунком.

2.3.3. Комментарии

Пользователю, при работе с задачником, часто бывает необходимо иметь возможность идентифицировать примеры не только по номерам. Например, при работе с медицинскими базами данных полезно иметь поле, содержащее фамилию больного или номер истории болезни. Для этих целей в задачнике может потребоваться хранить массив комментариев, которые не могут быть использованы в обучении. Кроме того, при исключении какого либо входного сигнала из множества входных сигналов, он не исключается из задачника полностью, а переводится в комментарии.

2.3.4. Предобработанные данные

Предобработанные данные – это массив входных сигналов сети, полученный из входных данных после предобработки, выполняемой компонентом предобработчик. Хранение задачником этого массива необязательно. Каждый элемент массива предобработанных данных является действительным числом. Следует отметить, что любая нетривиальная предобработка, как правило, изменяет длину массива.

2.3.5. Правильные ответы

Правильные ответы – массив ответов, которые должна выдать обученная нейронная сеть при решении примера. Этот массив необходим при обучении сетей с учителем. При использовании других видов сетей хранение задачником этого массива необязательно. Элементами массива ответов могут быть как числа, так и поля с ограниченным набором состояний. В первом случае будем говорить о задаче аппроксимации функции, а во втором – о задаче классификации объектов.

2.3.6. Полученные ответы

Полученные ответы – массив ответов, выданных сетью при решении примера. Для задачника хранение этой части примера не обязательно.

2.3.7. Оценки

Оценки – массив оценок, полученных сетью за решение всех подзадач примера (число подзадач равно числу ответов примера). Хранение этого массива задачником не обязательно.

2.3.8. Вес примера

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

2.3.9. Достоверность ответа

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

2.3.10. Уверенность в ответе

При использовании некоторых видов оценки (см. главу «Оценка и интерпретатор ответа») интерпретатор ответа способен оценить уверенность сети в полученном ответе. Массив коэффициентов уверенности сети в ответах (для каждого ответа свой коэффициент уверенности) может оказаться полезным для пользователя. Каждый элемент массива коэффициентов уверенности в ответе является действительным числом от нуля до единицы.

Все перечисленные выше массивы можно разбить на четыре типа по структуре:

·   Входные данные. Таких массивов обычно два – массив описания полей данных (содержит описание полей данных: имя поля, его тип и возможно некоторую дополнительную информацию) и собственно массив данных. Причем каждый пример имеет свой массив данных, но массив описания полей данных один для всех примеров задачника. Эти массивы имеют одинаковое число элементов, и их элементы попарно соответствуют друг другу.

·   Массив ответов. При обучении с учителем, в задачнике есть, по крайней мере, два массива этого вида – массив описания полей ответов и массив правильных ответов. Кроме того, возможно хранение в задачнике массивов вычисленных ответов, достоверности ответов и уверенности в ответе. Массив описания полей ответов – один для всех примеров задачника. Все остальные массивы данного типа хранятся по одному экземпляру каждого массива на пример.

·   Массив комментариев. Таких массивов обычно только два – массив описания полей комментариев и массив комментариев. Массив описания полей комментариев – один на весь задачник, а массив комментариев – один на пример.

Рис. 1. Схема данных задачника.

На рис. 1 приведено схематическое устройство задачника. Такое представление данных позволяет гибко использовать память. Однако следует учесть, что часть полей может переходить из одного массива в другой. Например, при исключении одного входного данного из использования (см. главу «Контрастер»), соответствующее ему поле переходит из массива входных данных в массив комментариев.

2.4. Запросы к компоненту задачник

В этом разделе описаны все запросы, выполняемые компонентом задачник в виде процедур и функций. При описании используется синтаксис языков Object Pascal и С. В Паскаль варианте приведены заголовки функций и процедур. В С варианте – прототипы функций. Большинство запросов, реализуется в виде функций, сообщающих о корректности завершения операции.

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

Все запросы к компоненту задачник можно разбить на следующие группы.

1. Чтение и запись задачника.

2. Начало и конец сеанса.

3. Перемещение по примерам.

4. Определение, получение и изменение данных.

5. Окраска примеров.

6. Установление структуры Задачника.

7. Добавление и удаление примеров.

8. Обработка ошибок.

2.4.1. Чтение и запись задачника

К этой группе запросов относятся запросы, работающие со всем задачником в целом. Эти запросы считывают задачник, сохраняют задачник на диске или выгружают ранее считанный или созданный задачник.

2.4.1.1. Прочитать задачник (tbAdd)

Описание запроса:

Pascal:

Function tbAdd( CompName : PString ) : Logic;

C:

Logic tbAdd( PString CompName )

Описание аргумента:

CompName – указатель на строку символов, содержащую имя файла задачника.

Назначение – служит для считывания задачника.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в данный момент считан задачник, то генерируется запрос tbDelete. Если запрос tbDelete завершается неуспешно, то генерируется внутренняя ошибка 104 – попытка считывания задачника при открытых сеансах ранее считанного задачника. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Первые четыре символа строки CompName составляют слово File. Остальная часть строки содержит имя компонента и после пробела имя файла, содержащего компонент.

4. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 102 –  ошибка чтения задачника. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

2.4.1.2. Записать задачник (tbWrite)

Описание запроса:

Pascal:

Function tbWrite( CompName, FileName : PString) : Logic;

C:

Logic tbWrite(PString CompName, PString FileName)

Описание аргументов:

CompName – указатель на строку символов, содержащую имя задачника.

FileName – имя файла, куда надо записать компонента.

Назначение – сохраняет задачник в файле.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса отсутствует считанный задачник, то возникает ошибка 101 – запрос при отсутствии задачника, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Задачник записывается в файл FileName под именем CompName.

4. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 103 –  ошибка записи задачника. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

2.4.1.3. Закрыть задачник (tbDelete)

Описание запроса:

Pascal:

Function tbDelete : Logic;

C:

Logic tbDelete()

Назначение – удаляет из памяти ранее считанный задачник.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если есть открытые сеансы, то возникает ошибка 105 – закрытие задачника при открытых сеансах. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Задачник закрывается. Запрос успешно завершается.

2.4.2. Начало и конец сеанса

К этой группе запросов относятся два запроса, открывающие и закрывающие сеансы работы с задачником.

2.4.2.1. Начало сеанса (InitSession)

Описание запроса:

Pascal:

Function InitSession( NewColor : Color; Oper : Integer; Var Handle: Integer ) : Logic;

C:

Logic InitSession(Color NewColor, Integer Oper, Integer* Handle)

Описание аргументов:

NewColor – цвет для отбора примеров задачника в текущую выборку.

Oper – операция для отбора в текущую выборку. Должна быть одной из констант CEqual, CIn, CInclude, Cxclude, CIntersect

Handle – номер сеанса. Начальное значение не важно. В этом аргументе возвращается номер сеанса.

Назначение – начинает сеанс. Отбирает текущую выборку.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Oper является недопустимым, то возникает ошибка 106 – недопустимый код операции при открытии сеанса, управление передается обработчику ошибок. Сеанс не открывается. Возвращается значение ложь.

3. Создается новый сеанс (в одно-сеансовых задачниках просто инициируется сеанс). Номер сеанса заносится в аргумент Handle.

4. Значения аргументов NewColor и Oper сохраняются во внутренних переменных задачника

5. Указателю текущего примера присваивается состояние «до первого примера»

6. InitSession := Next(Handle) – результат выполнения запроса совпадает с результатом выполнения вызванного запроса «Следующий пример».

2.4.2.2. Конец сеанса (EndSession)

Описание запроса:

Pascal:

Procedure EndSession( Handle : Integer );

C:

void EndSession(Integer Handle)

Назначение – закрывает сеанс.

Описание аргументов:

Handle – номер сеанса.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Освобождается вся память, взятая для выполнения сеанса. После этого сеанс завершается.

2.4.3. Перемещение по примерам

В эту группу запросов входят запросы позволяющие управлять положением текущего указателя в текущей выборке.

2.4.3.1. В начало (Home)

Описание запроса:

Pascal:

Function Íîìå( Handle : Integer ) : Logic;

C:

Logic Íîìå(Integer Handle)

Описание аргументов:

Handle – номер сеанса.

Назначение – делает текущим первый пример текущей выборки.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Указателю на текущий пример присваивается значение «до первого примера»

4. Home := Next(Handle) – результат выполнения запроса совпадает с результатом выполнения вызванного запроса «Следующий»

2.4.3.2. В конец (End)

Описание запроса:

Pascal:

Function End( Handle : Integer ) : Logic;

C:

Logic End(Integer Handle)

Описание аргументов:

Handle – номер сеанса.

Назначение – делает текущим последний пример текущей выборки.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Указателю на текущий пример присваивается значение «после последнего примера»

4. Home := Prev(Handle) – результат выполнения запроса совпадает с результатом выполнения вызванного запроса «Предыдущий»

2.4.3.3. Следующий (Next)

Описание запроса:

Pascal:

Function Next( Handle : Integer ) : Logic;

C:

Logic Next(Integer Handle)

Описание аргументов:

Handle – номер сеанса.

Назначение – делает текущим следующий пример текущей выборки.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Если значение указателя равно «после последнего примера», то возникает ошибка 108 – переход за конечную границу текущей выборки, и управление передается обработчику ошибок. В случае возврата управления в запрос, происходит немедленный выход из запроса с возвращением значения ложь.

4. Если значение указателя текущего примера равно «до первого примера», то присваиваем указателю адрес первого примера задачника. Если адрес в переменной в задачнике нет примеров, то возникает ошибка 108 – переход за конечную границу текущей выборки, и управление передается обработчику ошибок. В случае возврата управления в запрос, происходит немедленный выход из запроса с возвращением значения ложь. В противном случае переходим к шагу 6

5. Указатель перемещается на следующий пример задачника. Если следующего примера задачника нет, то указателю присваивается значение «после последнего примера».

6. Переходим к шагу 5, если не верно условие:

((GetColor Oper NewColor) And Last,

где Oper и NewColor – аргументы запроса InitSession, которым был открыт данный сеанс.

7. Next := Not Last (Переход к следующему примеру завершился удачно, если указатель не установлен в значение «после последнего примера»).

2.4.3.4. Предыдущий (Prev)

Описание запроса:

Pascal:

Function Prev( Handle : Integer ): Logic;

C:

Logic Prev(Integer Handle)

Описание аргументов:

Handle – номер сеанса.

Назначение – делает текущим предыдущий пример текущей выборки.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Если значение указателя равно «до первого примера», то возникает ошибка 109 – переход за начальную границу текущей выборки, и управление передается обработчику ошибок. В случае возврата управления в запрос, происходит немедленный выход из запроса с возвращением значения ложь.

4. Если значение указателя равно «после последнего примера», то присваиваем указателю адрес последнего примера задачника. Если в задачнике нет примеров, то возникает ошибка 109 – переход за начальную границу текущей выборки, и управление передается обработчику ошибок. В случае возврата управления в запрос, происходит немедленный выход из запроса с возвращением значения ложь.

5. В противном случае шаг 7.

6. Указатель перемещается на предыдущий пример задачника. Если предыдущего примера задачника нет, то указателю присваивается значение «до первого примера».

7. Шаг 6 повторяется до тех пор, пока не выполнится условие:

((GetColor Oper NewColor) And  First

8. Next := Not Last (Переход к следующему примеру завершился удачно, если указатель не установлен в значение «после последнего примера»).

2.4.3.5. Конец (Last)

Описание запроса:

Pascal:

Function Last( Handle : Integer ) : Logic;

C:

Logic Last(Integer Handle)

Описание аргументов:

Handle – номер сеанса.

Назначение – возвращает значение истина, если текущим является состояние «после последнего примера», и ложь – в противном случае.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Возвращает значение истина, если текущим является состояние «после последнего примера», и ложь – в противном случае.

2.4.3.6. Начало (First)

Описание запроса:

Pascal:

Function First( Handle : Integer ): Logic;

C:

Logic First(Integer Handle)

Описание аргументов:

Handle – номер сеанса.

Назначение – возвращает значение истина, если текущим является состояние «перед первым примером», и ложь в противном случае.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Возвращает значение истина, если текущим является состояние «перед первым примером», и ложь в противном случае.

2.4.3.7. Пример номер (Example)

Описание запроса:

Pascal:

Function Example( Number : Long; Handle : Integer ) : Logic;

C:

Logic Example(Long Number, Integer Handle)

Описание аргументов:

Number – номер примера, который должен быть сделан текущим. Нумерация примеров ведется с единицы.

Handle – номер сеанса.

Назначение – делает текущим пример текущей выборки с указанным номером.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Указатель устанавливается в состояние «до первого примера».

4. Number раз выполняем запрос Next.

5. Example := Not Last (Если не установлено состояние «после последнего примера», то запрос выполнен успешно).

2.4.4. Определение, получение и изменение данных

К данной группе запросов относятся запросы позволяющие получать данные из задачника, заносить данные в задачник и сбросить предобработку (необходимо выполнить данный запрос после изменений в данных или предобработчике, если задачник хранит векторы предобработанных данных)

2.4.4.1. Дать пример (Get)

Описание запроса:

Pascal:

Function Get( Handle : Integer; Var Data : PRealArray; What : Integer ) : Logic;

C:

Logic Get(Integer Handle, PRealArray* Data, Integer What)

Описание аргументов:

Handle – номер сеанса;

Data – указатель на массив, в котором должны быть возвращены данныt;

What – одна из предопределенных констант tbColor, tbInput, tbPrepared, tbAnswers, tbReliability, tbCalcAnswers, tbCalcReliability, tbWeight, tbEstimation, tbComment

Назначение – возвращает указанную в запросе информацию.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Если аргумент What имеет недопустимое значение, то возникает ошибка 110 – неверный тип вектора в запросе Get. Управление передается обработчику ошибок. Выполнение запроса прекращается.

4. Если текущий указатель указывает на одно из состояний «до первого примера» или «после последнего примера», то возникает ошибка 111 – попытка чтения до или после текущей выборки. Управление передается обработчику ошибок. Запрос завершается неуспешно.

5. Если в аргументе What указан вектор предобработанных данных, но в текущем примере он отсутствует, то генерируется запрос предобработать данные. Если предобработка завершается успешно, то полученный вектор предобработанных данных включается в пример, в противном случае выполнение запроса прекращается. Возвращается значение ложь.

6. В элементы массива, на который указывает аргумент Data, копируются данные из того вектора данных текущего примера, который указан в аргументе What. Если требуемый вектор в задачнике отсутствует, то возникает ошибка 112 – данные отсутствуют и запрос завершается со значением ложь. В противном случае запрос успешно завершается.

2.4.4.2. Обновить данные (Put)

Описание запроса:

Pascal:

Function Put( Handle : Integer; Data : PRealArray; What : Integer ) : Logic;

Logic Put(Integer Handle, PRealArray Data, Integer What)

Описание аргументов:

Handle – номер сеанса

Data – указатель на массив, в котором переданы данные, которые должны быть занесены в задачник.

What – одна из предопределенных констант tbColor, tbInput, tbPrepared, tbAnswers, tbReliability, tbCalcAnswers, tbCalcReliability, tbWeight, tbEstimation, tbComment

Назначение – обновить данные текущего примера

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Если аргумент What имеет недопустимое значение, то возникает ошибка 113 – неверный тип вектора в запросе Put. Управление передается обработчику ошибок. Выполнение запроса прекращается.

4. Если текущий указатель указывает на одно из состояний «до первого примера» или «после последнего примера», то возникает ошибка 111 – попытка чтения до или после текущей выборки. Управление передается обработчику ошибок. Запрос завершается неуспешно.

5. Если устанавливается вектор входных данных, то для текущего примера должен быть освобожден вектор предобработанных данных.

6. В данные примера копируются значения, указанные в массиве Data. Запрос успешно завершается.

2.4.4.3. Сбросить предобработку (RemovePrepare)

Описание запроса:

Pascal:

Procedure RemovePrepare;

C:

void RemovePrepare()

Назначение – отмена предобработки всех ранее предобработанных примеров.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. У всех примеров задачника освобождаются вектора предобработанных данных.

2.4.5. Окраска примеров

В данный раздел помещены запросы для работы с цветами. Отметим, что цвет примера, возвращаемый запросом GetColor можно получить также с помощью запроса Get.

2.4.5.1. Дать цвет примера (GetColor)

Описание запроса:

Pascal:

Function GetColor( Handle : Integer ) : Color;

C:

Logic GetColor(Integer Handle)

Описание аргументов:

Handle – номер сеанса

Назначение – возвращает цвет текущего примера.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Если текущий указатель указывает на одно из состояний «до первого примера» или «после последнего примера», то возникает ошибка 111 – попытка чтения до или после текущей выборки. Управление передается обработчику ошибок. Запрос завершается неуспешно.

4. Возвращается цвет текущего примера.

2.4.5.2. Покрасить пример (PaintCurrent)

Описание запроса:

Pascal:

Function PaintCurrent( Handle : Integer; NewColor, ColorMask : Color; Oper : Integer) : Logic;

C:

Logic PaintCurrent(Integer Handle, Color NewColor, Color ColorMask, Integer Oper)

Описание аргументов:

Handle – номер сеанса.

NewColor – новый цвет для окраски примера.

ColorMask – маска цвета для окраски примера.

Oper – операция, используемая при окраске примера. Должна быть одной из констант COr, CAnd, CXor, CNot.

Назначение – изменяет цвет текущего примера.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если аргумент Handle не корректен возникает ошибка 107 – неверный номер сеанса. Управление передается обработчику ошибок. Выполнение запроса прекращается.

3. Если Oper не корректен, то возникает ошибка 114 – неверная операция окраски примера. Управление передается обработчику ошибок. Запрос завершается со значением ложь.

4. Новый цвет примера := (Старый цвет примера And ColorMask) Oper NewColor

2.4.6. Ошибки компонента задачника

В табл. 1 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом задачник, и действия стандартного обработчика ошибок.

Таблица 1.

Ошибки компонента задачник и действия стандартного обработчика ошибок.

Название ошибки

Стандартная обработка

101

Запрос при отсутствии задачника

Занесение номера в Error

102

Ошибка чтения задачника

Занесение номера в Error

103

Ошибка записи задачника

Занесение номера в Error

104

Попытка считывания задачника при открытых сеансах ранее считанного задачника

Занесение номера в Error

105

Закрытие задачника при открытых сеансах

Занесение номера в Error

106

Недопустимый код операции при открытии сеанса

Занесение номера в Error

107

Неверный номер сеанса

Занесение номера в Error

108

Переход за конечную границу текущей выборки

Игнорируется

109

Переход за начальную границу текущей выборки

Игнорируется

110

Неверный тип вектора в запросе Get

Занесение номера в Error

111

Попытка чтения до или после текущей выборки

Занесение номера в Error

112

Данные отсутствуют

Игнорируется

113

Неверный тип вектора в запросе Put

Занесение номера в Error

114

Неверная операция окраски примера

Занесение номера в Error


3. Предобработчик

Данная глава посвящена компоненту предобработчик [80, 150]. В ней рассматриваются различные аспекты предобработки входных данных для нейронных сетей. Существует множество различных видов нейронных сетей (см. главу «Описание нейронных сетей»). Однако, для большинства нейронных сетей характерно наличие такого интервала входных сигналов, в пределах которого сигналы различимы. Для различных нейронных сетей эти интервалы различны. Большинство работающих с нейронными сетями прекрасно осведомлены об этом их свойстве, но до сих пор не предпринималось никаких попыток как-либо формализовать или унифицировать подходы к предобработке входных сигналов. В данной главе дан один из возможных формализмов этой задачи. За рамками рассмотрения осталась предобработка графической информации. Наиболее мощные и интересные способы предобработки графической информации описаны в [67, 94, 276]. При аппаратной реализации нейрокомпьютера, компонент предобработчик также следует реализовывать аппаратно, поскольку вне зависимости от источника входных данных их надо обрабатывать одинаково. К тому же большинство предобработчиков допускают простую аппаратную реализацию.

В этой главе будут описаны различные виды входных сигналов и способы их предобработки. В качестве примера будут рассмотрены сети с сигмоидными нелинейными преобразователями. Однако, описываемые способы предобработки применимы для сетей с произвольными нелинейными преобразователями. Единственным исключением является раздел «Оценка способности сети решить задачу», который применим только для сетей с нелинейными преобразователями, непрерывно зависящими от своих аргументов.

Наиболее важным в данной являются следующее.

·   При предобработке качественных признаков не следует вносить недостоверную информацию.

·   Сформулирована мера сложности нейросетевой задачи.

·   Выборочная оценка константы Липшица и оценка константы Липшица нейронной сети позволяют легко оценить способность нейронной сети решить поставленную задачу. Эти легко реализуемые процедуры позволяют сэкономить время и силы.

·   Правильно выбранная предобработка упрощает нейросетевую задачу.

Материал данной главы основан на анализе различных методов обработки данных [4, 5, 143, 158, 160, 162, 187, 228, 232 – 235, 326, 332], различных типов данных [3, 6, 20, 139, 140, 158, 177, 184, 223] и специфике нейросетевой обработки данных.

3.1. Нейрон

Нейроны, используемые в большинстве нейронных сетей, имеют структуру, приведенную на рис. 1. На рис. 1 использованы следующие обозначения:

 – вектор входных сигналов нейрона;

 – вектор синаптических весов нейрона;

 – входной сумматор нейрона;

 – функциональный преобразователь;

– выходной сигнал нейрона.

 – выходной сигнал входного сумматора;

Обычно нейронные сети называют по виду функции . Хорошо известны и наиболее часто используются два вида сигмоидных сетей:

где c - параметр, называемый «характеристикой нейрона». Обе функции имеют похожие графики.

Каждому типу нейрона соответствует свой интервал приемлемых входных данных. Как правило, этот диапазон либо совпадает с диапазоном выдаваемых выходных сигналов (например для сигмоидных нейронов с функцией ), либо является объединением диапазона выдаваемых выходных сигналов и отрезка, симметричного ему относительно нуля (например, для сигмоидных нейронов с функцией ), Этот диапазон будем обозначать как

3.2. Различимость входных данных

Очевидно, что входные данные должны быть различимы. В данном разделе будут приведены соображения, исходя из которых, следует выбирать диапазон входных данных. Пусть одним из входных параметров нейронной сети является температура в градусах Кельвина. Если речь идет о температурах близких к нормальной, то входные сигналы изменяются от 250 до 300 градусов. Пусть сигнал подается прямо на нейрон (синаптический вес равен единице). Выходные сигналы нейронов с различными параметрами приведены в табл. 1.

Таблица 1

Входной

Нейрон типа

Нейрон типа

сигнал

250

1.0

1.0

1.0

1.0

0.99960

0.99800

0.99602

0.99206

275

1.0

1.0

1.0

1.0

0.99964

0.99819

0.99638

0.99278

300

1.0

1.0

1.0

1.0

0.99967

0.99834

0.99668

0.99338

Совершенно очевидно, что нейронная сеть просто неспособна научиться надежно различать эти сигналы (если вообще способна научиться их различать!). Если использовать нейроны с входными синапсами, не равными единице, то нейронная сеть сможет отмасштабировать входные сигналы так, чтобы они стали различимы, но при этом будет задействована только часть диапазона приемлемых входных данных - все входные сигналы будут иметь один знак. Кроме того, все подаваемые сигналы будут занимать лишь малую часть этого диапазона. Например, если мы отмасштабируем температуры так, чтобы 300 соответствовала величина суммарного входного сигнала равная 1 (величина входного синапса равна 1/300), то реально подаваемые сигналы займут лишь одну шестую часть интервала [0,1] и одну двенадцатую интервала [-1,1]. Получаемые при этом при этом величины выходных сигналов нейронов приведены в табл. 2.

Таблица 2

Входной

Нейрон типа

Нейрон типа

сигнал

250 (0.83)

0.52074

0.60229

0.69636

0.84024

0.89286

0.62500

0.45455

0.29412

275 (0.91)

0.52273

0.61183

0.71300

0.86057

0.90164

0.64706

0.47826

0.31429

300 (1.0)

0.52498

0.62246

0.73106

0.88080

0.90909

0.66667

0.50000

0.33333

Сигналы, приведенные в табл. 2 различаются намного сильнее соответствующих сигналов из табл. 1. Таким образом, необходимо заранее позаботиться о масштабировании и сдвиге сигналов, чтобы максимально полно использовать диапазон приемлемых входных сигналов. Опыт использования нейронных сетей с входными синапсами свидетельствует о том, что в подавляющем большинстве случаев предварительное масштабирование и сдвиг входных сигналов сильно облегчает обучение нейронных сетей. Если заранее произвести операции масштабирования и сдвига входных сигналов, то величины выходных сигналов нейронов даже при отсутствии входных синапсов будут различаться еще сильнее (см. табл. 3).

Таблица 3

Входной

Нейрон типа

Нейрон типа

Сигнал

250 (-1)

0.47502

0.37754

0.26894

0.11920

-0.9091

-0.6667

-0.5000

-0.3333

275 (0)

0.50000

0.50000

0.50000

0.50000

0.0000

0.0000

0.0000

0.0000

300 (1)

0.52498

0.62246

0.73106

0.88080

0.9091

0.6667

0.5000

0.3333

Величину диапазона различимых входных сигналов можно определять различными способами. На практике в качестве диапазона различимых входных сигналов обычно используется диапазон приемлемых входных данных, исходя из того соображения, что если данные из этого интервала хороши для промежуточных нейронов, то они хороши и для входных.

Другой способ определения различимости входных сигналов приведен в разделе «Оценка способности сети решить задачу».

3.3. Классификация компонентов входных данных

Информация поступает к нейронной сети в виде набора ответов на некоторый список вопросов. Можно выделить три основных типа ответов (вопросов).

1. Бинарный признак (возможен только один из ответов – истина или ложь).

2. Качественный признак (принимает конечное число значений).

3. Число.

Ответ типа качественный признак - это ответ с конечным числом состояний. Причем нельзя ввести осмысленное расстояние между состояниями. Примером качественного признака может служить состояние больного - тяжелый, средний, легкий. Действительно, нельзя сказать, что расстояние от легкого больного до среднего больше, меньше или равно расстоянию от среднего больного до тяжелого. Все качественные признаки можно в свою очередь разбить на три класса.

1. Упорядоченные признаки.

2. Неупорядоченные признаки.

3. Частично упорядоченные признаки.

Упорядоченным признаком называется такой признак, для любых двух состояний которого можно сказать, что одно из них предшествует другому. Тот факт, что состояние  предшествует состоянию , будем обозначать следующим образом – . Примером упорядоченного признака может служить состояние больного. Действительно, все состояния можно упорядочить по тяжести заболевания:

легкий больной < средний больной < тяжелый больной

Признак называют неупорядоченным, если никакие два состояния нельзя связать естественным в контексте задачи отношением порядка. Примером неупорядоченного признака может служить ответ на вопрос "Ваш любимый цвет?".

Признак называется частично упорядоченным, если для каждого состояния существует другое состояние, с которым оно связано отношением порядка. Примером частично упорядоченного признака является ответ на вопрос "Какой цвет Вы видите на экране монитора?", преследующий цель определение восприимчивости к интенсивностям основных цветов. Действительно, все множество из шестнадцати состояний разбивается на несколько цепочек:

 Черный < Синий < Голубой < Белый;

 Черный < Красный < Ярко красный < Белый;

 Черный < Зеленый < Ярко зеленый < Белый;

 Черный < Фиолетовый < Ярко фиолетовый < Белый

и т.д. Однако, между состояниями Синий и Красный отношения порядка нет.

Известно, что любой частично упорядоченный признак можно представить в виде комбинации нескольких упорядоченных и неупорядоченных признаков. Так, рассмотренный выше частично упорядоченный признак распадается на три упорядоченных признака: интенсивность синего, красного и зеленого цветов. Каждый из этих признаков является упорядоченным (цепочки порядка для этих признаков приведены в первых трех строчках рассмотрения примера). Каждое состояние исходного качественного признака описывается тройкой состояний полученных качественных признаков. Так, например, состояние Фиолетовый описывается в виде (Синий, Красный, Черный).

Исходя из вышесказанного, далее будет рассмотрено только кодирование упорядоченных и неупорядоченных признаков.

Впервые вопросы кодирования качественных признаков для нейронных сетей были рассмотрены в работах [76, 152].

3.4. Кодирование бинарных признаков

Бинарные признаки характеризуются наличием только двух состояний – истина и ложь. Однако даже такие простые данные могут иметь два разных смысла. Значение истина означает наличие у описываемого объекта какого-либо свойства. А ответ ложь может означать либо отсутствие этого свойства, либо наличие другого свойства. В зависимости от смысловой нагрузки значения ложь, и учитывая заданный диапазон, рекомендуемые способы кодирования бинарного признака приведены в табл. 4.

Таблица 4

Кодирование бинарного признака

Смысл значения ложь

Величина входного сигнала

Истина

Ложь

Отсутствие заданного свойства при

Отсутствие заданного свойства при

Наличие другого свойства

3.5. Кодирование неупорядоченных качественных признаков

Таблица 5.

Кодирование неупорядоченного качественного признака

Состояние

Вектор входных сигналов

Поскольку никакие два состояния неупорядоченного признака не связаны отношением порядка, то было бы неразумным кодировать их разными величинами одного входного сигнала нейронной сети. Поэтому, для кодирования качественных признаков рекомендуется использовать столько входных сигналов, сколько состояний у этого качественного признака. Каждый входной сигнал соответствует определенному состоянию. Так если набор всех состояний рассматриваемого признака обозначить через , то рекомендуемая таблица кодировки имеет вид, приведенный в табл. 5.

3.6. Кодирование упорядоченных качественных признаков

Таблица 6.

Кодирование упорядоченного качественного признака

Состояние

Вектор входных сигналов

Упорядоченные качественные признаки, в отличие от неупорядоченных, имеют отношение порядка между состояниями. Однако кодирование их разными значениями одного входного сигнала неразумно из-за того, что расстояние между состояниями не определено, а такое кодирование эти расстояния задает явным образом. Поэтому, упорядоченные качественные признаки рекомендуется кодировать в виде стольких входных сигналов, сколько состояний у признака. Но, в отличие от неупорядоченных признаков, накапливать число сигналов с максимальным значением. Для случая, когда все состояния обозначены через , рекомендуемая таблица кодировки приведена в табл. 6.

3.7. Числовые признаки

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

Содержательное значение признака. Если входными данными сети является угол между двумя направлениями, например, направление ветра, то ни в коем случае не следует подавать на вход сети значение угла (не важно в градусах или радианах). Такая подача приведет к необходимости "уяснения" сетью того факта, что 0 градусов и 360 градусов одно и тоже. Разумнее выглядит подача в качестве входных данных синуса и косинуса этого угла. Число входных сигналов сети увеличивается, но зато близкие значения признака кодируются близкими входными сигналами.

Точность измерения признака. Так в метеорологии используется всего восемь направлений ветра. Значит, при подаче входного сигнала сети необходимо подавать не угол, а всего лишь информацию о том, в какой из восьми секторов этот угол попадает. Но тогда имеет смысл рассматривать направление ветра не как числовой параметр, а как неупорядоченный качественный признак с восемью состояниями.

Расположение значений признака в интервале значений. Следует рассмотреть вопрос о равнозначности изменения значения признака на некоторую величину в разных частях интервала значений признака. Как правило, это связано с косвенными измерениями (вместо одной величины измеряется другая). Например, сила притяжения двух небесных тел при условии постоянства массы  однозначно характеризуется расстоянием между ними. Пусть рассматриваются расстояния от 1 до 100 метров. Легко понять, что при изменении расстояния с 1 до 2 метров, сила притяжения изменится в четыре раза, а при изменении с 99 до 100 метров – в 1.02 раза. Следовательно, вместо подачи расстояния следует подавать обратный квадрат расстояния .

3.8. Простейшая предобработка числовых признаков

Как уже отмечалось в разделе «Различимость входных данных» числовые сигналы рекомендуется масштабировать и сдвигать так, чтобы весь диапазон значений попадал в диапазон приемлемых входных сигналов. Эта предобработка проста и задается следующей формулой:

,                                                                                                                          (1)

где  - диапазон приемлемых входных сигналов,  – диапазон значений признака ,  – предобработанный сигнал, который будет подан на вход сети. Предобработку входного сигнала по формуле (1) будем называть простейшей предобработкой.

3.9. Оценка способности сети решить задачу

В данном разделе рассматриваются только сети, все элементы которых непрерывно зависят от своих аргументов (см. главу «Описание нейронных сетей»). Предполагается, что все входные данные предобработаны так, что все входные сигналы сети лежат в диапазоне приемлемых входных сигналов. Будем обозначать вектора входных сигналов через , а требуемые ответы сети через . Компоненты векторов будем обозначать нижним индексом, например, компоненты входного вектора через . Будем полагать, что в каждом примере ответ является вектором чисел из диапазона приемлемых сигналов. В случае обучения сети задаче классификации требуемый ответ зависит от вида используемого интерпретатора ответа (см. главу «Оценка и Интерпретатор ответа»).

Нейронная сеть вычисляет некоторую вектор-функцию  от входных сигналов. Эта функция зависит от параметров сети. Обучение сети состоит в подборе такого набора параметров сети, чтобы величина  была минимальной (в идеале равна нулю). Для того чтобы нейронная сеть могла хорошо приблизить заданную таблично функцию  необходимо, чтобы реализуемая сетью функция  при изменении входных сигналов с  на  могла изменить значение с  на . Очевидно, что наиболее трудным для сети должно быть приближение функции в точках, в которых при малом изменении входных сигналов происходит большое изменение значения функции. Таким образом, наибольшую сложность будет представлять приближение функции  в точках, в которых достигает максимума выражение . Для аналитически заданных функций величина  называется константой Липшица. Исходя из этих соображения можно дать следующее определение сложности задачи.

Сложность аппроксимации таблично заданной функции , которая в точках  принимает значения , задается выборочной оценкой константы Липшица, вычисляемой по следующей формуле:

                                                                                                                                  (2)

Оценка (2) является оценкой константы Липшица аппроксимируемой функции снизу.

Для того, чтобы оценить способность сети заданной конфигурации решить задачу, необходимо оценить константу Липшица сети и сравнить ее с выборочной оценкой (2). Константа Липшица сети вычисляется по следующей формуле:

                                                                                                                   (3)

В формулах (2) и (3) можно использовать произвольные нормы. Однако для нейронных сетей наиболее удобной является евклидова норма. Далее везде используется евклидова норма.

В следующем разделе описан способ вычисления оценки константы Липшица сети (3) сверху. Очевидно, что в случае  сеть принципиально не способна решить задачу аппроксимации функции .

3.9.1. Оценка константы Липшица сети

Оценку константы Липшица сети будем строить в соответствии с принципом иерархического устройства сети, описанным в главе «Описание нейронных сетей». При этом потребуются следующие правила.

1. Для композиции функций  константа Липшица оценивается как произведение констант Липшица:

 .                                                                                                                             (4)

2. Для вектор-функции  константа Липшица равна:

.                                                                                                                              (5)

3.9.2. Способ вычисления константы Липшица

Для непрерывных функций константа Липшица является максимумом производной в направлении  по всем точкам и всем направлениям. При этом вектор направления имеет единичную длину: . Напомним формулу производной функции  в направлении :

                                                                                                                                           (6)

3.9.3. Синапс

Обозначим входной сигнал синапса через , а синаптический вес через . Тогда выходной сигнал синапса равен . Поскольку синапс является функцией одной переменной, константа Липшица равна максимуму модуля производной – модулю синаптического веса:

                                                                                                                                                   (7).

3.9.4. Умножитель

Обозначим входные сигналы умножителя через . Тогда выходной сигнал умножителя равен . Используя (6) получаем . Выражение  является скалярным произведением векторов  и, учитывая единичную длину вектора , достигает максимума, когда эти векторы сонаправлены. То есть при векторе

 .

Используя это выражение, можно записать константу Липшица для умножителя:

 .                                                              (8)

Если входные сигналы умножителя принадлежат интервалу , то константа Липшица для умножителя может быть записана в следующем виде:

.                                                                                                                             (9)

3.9.5. Точка ветвления

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

3.9.6. Сумматор

Производная суммы по любому из слагаемых равна единице. В соответствии с (6) получаем:

,                                                                                                             (10)

поскольку максимум суммы при ограничении на сумму квадратов достигается при одинаковых слагаемых.

3.9.7. Нелинейный Паде преобразователь

Нелинейный Паде преобразователь или Паде элемент имеет два входных сигнала и один выходной. Обозначим входные сигналы через . Используя (6) можно записать константу Липшица в следующем виде:

.

Знаменатель выражения под знаком модуля не зависит от направления, а числитель можно преобразовать так же, как и для умножителя. После преобразования получаем:

                                                                                                                         (11)

3.9.8. Нелинейный сигмоидный преобразователь

Нелинейный сигмоидный преобразователь, как и любой другой нелинейный преобразователь, имеющий один входной сигнал , имеет константу Липшица равную максимуму модуля производной:

.                                                                                                (12)

3.9.9. Адаптивный сумматор

Для адаптивного сумматора на  входов оценка константы Липшица, получаемая через представление его в виде суперпозиции слоя синапсов и простого сумматора, вычисляется следующим образом. Используя формулу (7) для синапсов и правило (5) для вектор-функции получаем следующую оценку константы Липшица слоя синапсов:

.

Используя правило (4) для суперпозиции функций и оценку константы Липшица для простого сумматора (10) получаем:

.                                                                                                            (13)

Однако, если оценить константу Липшица адаптивного сумматора напрямую, то, используя (6) и тот факт, что при фиксированных длинах векторов скалярное произведение достигает максимума для сонаправленных векторов получаем:

.                                                                               (14)

3.9.10. Константа Липшица сигмоидной сети

Рассмотрим слоистую сигмоидную сеть со следующими свойствами:

1. Число входных сигналов – .

2. Число нейронов в -м слое – .

3. Каждый нейрон первого слоя получает все входные сигналы, а каждый нейрон любого другого слоя получает сигналы всех нейронов предыдущего слоя.

4. Все нейроны всех слоев имеют вид, приведенный на рис. 1 и имеют одинаковую характеристику.

5. Все синаптические веса ограничены по модулю единицей.

6. В сети  слоев.

В этом случае, учитывая формулы (4), (5), (12) и (14) константу Липшица -о слоя можно оценить следующей величиной:

.

Используя формулу (4) получаем оценку константы Липшица всей сети:

.

Если используется нейроны типа , то  и оценка константы Липшица сети равна:

Для нейронов типа , то  и оценка константы Липшица сети равна:

Обе формулы подтверждают экспериментально установленный факт, что чем круче характеристическая функция нейрона, тем более сложные функции (функции с большей константой Липшица) может аппроксимировать сеть с такими нейронами.

3.10. Предобработка, облегчающая обучение

При обучении нейронных сетей иногда возникают ситуации, когда дальнейшее обучение нейронной сети невозможно. В этом случае необходимо проанализировать причины. Возможно несколько видов анализа. Одной из возможных причин является высокая сложность задачи, определяемая как выборочная оценка константы Липшица.

Для упрощения задачи необходимо уменьшить выборочную оценку константы Липшица. Наиболее простой способ добиться этого – увеличить расстояние между входными сигналами. Рассмотрим пару примеров – , – таких, что . Определим среди координат векторов  и  координату, в которой достигает минимума величина , исключив из рассмотрения совпадающие координаты. Очевидно, что эта координата является «узким местом», определяющим сложность задачи. Следовательно, для уменьшения сложности задачи требуется увеличить расстояние между векторами  и , а наиболее перспективной координатой для этого является -я. Однако увеличение расстояние между  и  не всегда осмыслено. Дело в том, что все параметры, как правило, измеряются с конечной точностью. Поэтому, если величина  меньше чем точность измерения -го параметра, значения  и  можно считать совпадающими. Таким образом, для изменения масштаба надо выбирать тот из входных параметров, для которого значение  минимально, но превышает точность измерения этого параметра.

Таблица 7.

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

Значение

Первый сигнал

Второй сигнал

Предположим, что все входные параметры предобработаны в соответствии с формулой (1). Перенумеруем примеры обучающего множества так, чтобы были верны следующие неравенства: ,  где  – число примеров в обучающем множестве. При этом, возможно, придется исключить ряд пар параметр-ответ с совпадающими значениями параметра. Если в какой-либо из таких пар значения ответов различаются, то это снижает возможную полезность данной процедуры.

Наиболее простой путь – разбить диапазон -го параметра на два. Зададимся точкой . Будем кодировать -й параметр двумя входными сигналами в соответствии с табл. 7. При таком кодировании константа Липшица, очевидно, уменьшится. Вопрос о выборе точки  может решаться по-разному. Простейший путь – положить . Более сложный, но часто более эффективный – подбор  исходя из требования минимальности константы Липшица.

Приведенный выше способ уменьшения константы Липшица не единственный. В следующем разделе рассмотрен ряд способов предобработки, решающих ту же задачу.

3.11. Другие способы предобработки числовых признаков

В данном разделе будет рассмотрено три вида предобработки числовых признаков – модулярный, позиционный и функциональный. Основная идея этих методов предобработки состоит в том, чтобы сделать значимыми малые отличия больших величин. Действительно, пусть для ответа существенно изменение величины признака на единицу при значении признака порядка миллиона. Очевидно, что простейшая предобработка (1) сделает отличие в единицу неразличимым для нейронной сети при абсолютных значениях порядка миллиона.

Все эти виды предобработки обладают одним общим свойством – за счет кодирования входного признака несколькими сигналами они уменьшают сложность задачи (константу Липшица).

3.11.1. Модулярная предобработка

Зададимся некоторым набором положительных чисел . Определим сравнение по модулю для действительных чисел следующим образом:

,                                                                                                      (15)

где  – функция, вычисляющая целую часть величины  путем отбрасывания дробной части. Очевидно, что величина  лежит в интервале . Кодирование входного признака  при модулярной предобработке вектором  производится по следующей формуле:

.                                                                                                     (16)

Однако модулярная предобработка обладает одним отрицательным свойством – во всех случаях, когда , при целом , разрушается отношение предшествования чисел. В табл. 8 приведен пример векторов. Поэтому, модульная предобработка пригодна при предобработке тех признаков, у которых важна не абсолютная величина, а взаимоотношение этой величины с величинами . Примером такого признака может служить угол между векторами, если в качестве величин  выбрать .

Таблица 8.

Пример сигналов при модулярном вводе

5

2

0

5

5

10

1

0

3

10

15

0

0

1

3

3.11.2. Функциональная предобработка

Функциональная предобработка преследует единственную цель – снижение константы Липшица задачи. В разделе «Предобработка, облегчающая обучение», был приведен пример такой предобработки. Рассмотрим общий случай функциональной предобработки, отображающих входной признак  в -мерный вектор . Зададимся набором из  чисел, удовлетворяющих следующим условиям: . Пусть  – функция, определенная на интервале , а  – минимальное и максимальное значения функции  на этом интервале. Тогда -я координата вектора  вычисляется по следующей формуле:

                                                                                           (17)

Линейная предобработка. В линейной предобработке используется кусочно линейная функция:

                                                                                                                                  (18)

Таблица 9

Пример функциональной предобработки числового признака , при условии, что сигналы нейронов принадлежат интервалу . В сигмоидной предобработке использована , а в шапочной – . Были выбраны четыре точки.

Линейная предобработка

1.5

0.5

-0.5

-1

-1

3.5

1

1

0.5

-0.5

Сигмоидная предобработка

1.5

0.333

-0.333

-0.600

-0.714

3.5

0.714

 0.600

 0.333

-0.333

Шапочная предобработка

1.5

 0.600

 0.600

-0.385

-0.724

3.5

-0.724

-0.384

 0.600

 0.600

Графики функций  представлены на рис. 2а. Видно, что с увеличением значения признака  ни одна функция не убывает, а их сумма возрастает. В табл. 9 представлены значения этих функций для двух точек:  и .

Сигмоидная предобработка. В сигмоидной предобработке может использоваться любая сигмоидная функция. Если в качестве сигмоидной функции использовать функцию , приведенную в разделе «Нейрон» этой главы, то формула (17) примет следующий вид:

 .

Графики функций  представлены на рис. 2б. Видно, что с увеличением значения признака  ни одна функция не убывает, а их сумма возрастает. В табл. 9 представлены значения этих функций для двух точек .

Шапочная предобработка. Для шапочной предобработки используются любые функции, имеющие график в виде «шапочки». Например, функция . Графики функций  представлены на рис. 2в. Видно, что с увеличением значения признака  ни одна из функций , ни их сумма не ведут себя монотонно. В табл. 9 представлены значения этих функций для двух точек  .

 

3.11.3. Позиционная предобработка

Основная идея позиционной предобработки совпадает с принципом построения позиционных систем счисления. Зададимся положительной величиной  такой, что . Сдвинем признак  так, чтобы он принимал только неотрицательные значения. В качестве сигналов сети будем использовать результат простейшей предобработки -ичных цифр представления сдвинутого признака . Формулы вычисления цифр приведены ниже:

                                                                    (19)

где операция сравнения по модулю действительного числа определена в (15). Входные сигналы сети получаются из компонентов вектора  путем простейшей предобработки.

3.12. Составной предобработчик

Поскольку на вход нейронной сети обычно подается несколько входных сигналов, каждый из которых обрабатывается своим предобработчиком, то предобработчик должен быть составным. Представим предобработчик в виде совокупности независимых частных предобработчиков. Каждый частный предобработчик обрабатывает одно или несколько тесно связанных входных данных. Как уже отмечалось ранее, предобработчик может иметь один из четырех типов, приведенных в табл. 10. На входе предобработчик получает вектор входных данных (возможно, состоящий из одного элемента), а на выходе выдает вектор входных сигналов сети (так же возможно состоящий из одного элемента).

Таблица 10.

Типы предобработчиков

Тип

Описание

Number

Предобрабатывает числовые входные данные

Unordered

Предобрабатывает неупорядоченные качественные признаки

Ordered

Предобрабатывает упорядоченные качественные признаки

Binary

Обрабатывает бинарные признаки

Необходимость передачи предобработчику вектора входных данных и получения от него вектора входных сигналов связана с тем, что существуют предобработчики получающие несколько входных данных и выдающие несколько входных сигналов. Примером такого предобработчика может служить предобработчик, переводящий набор координат планеты из сферической в декартову.

Для качественных признаков принято кодирование длинными целыми числами. Первое значение равно 1, второе – 2 и т.д. Числовые признаки кодируются действительными числами.

3.13. Запросы к компоненту предобработчик

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

1. Предобработка.

2. Изменение параметров.

3. Работа со структурой.

4. Инициация редактора предобработчика.

5. Обработка ошибок.

Поскольку нейрокомпьютер может работать одновременно с несколькими сетями, то и компонент предобработчик должна иметь возможность одновременной работы с несколькими предобработчиками. Поэтому большинство запросов к предобработчику содержат явное указание имени предобработчика. Ниже приведено описание всех запросов к компоненту предобработчик. Каждый запрос является логической функцией, возвращающей значение истина, если запрос выполнен успешно, и ложь – при ошибочном завершении исполнения запроса.

В запросах второй и третьей группы при обращении к частным предобработчикам используется следующий синтаксис:

<Полное имя частного предобработчика> ::= <Имя предобработчика>.

<Псевдоним частного предобработчика> [[<Номер экземпляра>]]

При вызове ряда запросов используются предопределенные константы. Их значения приведены в табл. 11.

Таблица 11.

Значения предопределенных констант компонента предобработчик

Название

Значение

Значение

BinaryPrep

0

Стандартный предобработчик бинарных признаков

UnOrdered

1

Стандартный предобработчик неупорядоченных качественных признаков

Ordered

2

Стандартный предобработчик упорядоченных качественных признаков.

EmptyPrep

3

Стандартный простейший предобработчик

ModPrep

4

Стандартный модулярный предобработчик

FuncPrep

5

Стандартный функциональный предобработчик

PositPrep

6

Стандартный позиционный предобработчик

UserType

-1

Предобработчик, определенный пользователем.

3.13.1. Запрос на предобработку

Единственный запрос первой группы выполняет основную функцию компонента предобработчик – предобрабатывает входные данные, вычисляя вектор входных сигналов.

3.13.1.1. Предобработать вектор сигналов (Prepare)

Описание запроса:

Pascal:

Function Prepare(CompName : PString; Data : PRealArray; Var Signals : PRealArray) : Logic;

C:

Logic Prepare(PString CompName, PRealArray Data; PRealArray* Signals)

Описание аргумента:

CompName – указатель на строку символов, содержащую имя предобработчика.

Data – массив входных данных.

Signals – вычисляемый массив входных сигналов.

Назначение – предобрабатывает массив входных данных Data, вычисляя массив входных сигналов Signals используя предобработчик, указанный в параметре CompName.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента CompName дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является текущий предобработчик – первый в списке предобработчиков компонента предобработчик.

3. Если список предобработчиков компонента предобработчик пуст или имя предобработчика, переданное в аргументе CompName в этом списке не найдено, то возникает ошибка 201 – неверное имя предобработчика, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Производится предобработка предобработчиком, имя которого было указано в аргументе CompName.

5. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 204 - ошибка предобработки. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

3.13.2. Остальные запросы

Ниже приведен список запросов к компоненту предобработчик, исполнение которых описано в разделе «Запросы общие для всех компонентов»:

prSetCurrent – Сделать предобработчик текущим

prAdd – Добавление нового предобработчика

prDelete – Удаление предобработчика

prWrite – Запись предобработчика

prGetStructNames – Вернуть имена структурных единиц предобработчика

prGetType – Вернуть тип структурной единицы предобработчика

prGetData – Получить параметры предобработчика

prGetName – Получить имена параметров предобработчика

prSetData – Установить параметры предобработчика

prEdit – Редактировать предобработчик

OnError – Установить обработчик ошибок

GetError – Дать номер ошибки

FreeMemory – Освободить память

В запросе prGetType  в переменной TypeId возвращается значение одной из предопределенных констант, перечисленных в табл. 11.

3.13.3. Ошибки компонента предобработчик

В табл. 12 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом предобработчик, и действия стандартного обработчика ошибок.

 

Таблица 12.

Ошибки компонента предобработчик и действия стандартного обработчика ошибок.

Название ошибки

Стандартная обработка

201

Неверное имя предобработчика

Занесение номера в Error

202

Ошибка считывания предобработчика

Занесение номера в Error

203

Ошибка сохранения предобработчика

Занесение номера в Error

204

Ошибка предобработки

Занесение номера в Error

4. Описание нейронных сетей

В первой части этой главы описана система построения сетей из элементов. Описаны прямое и обратное функционирование сетей и составляющих их элементов. Приведены три метода построения двойственных сетей и обоснован выбор самодвойственных сетей. Во второй части приведены примеры различных парадигм нейронных сетей, описанные в соответствии с предложенной в первой части главы методикой.

Как уже говорилось в первой главе, на данный момент в нейросетевом сообществе принято описывать архитектуру нейронных сетей в неразрывном единстве с методами их обучения. Эта связь не является естественной. Так, в первой части этой главы будет рассматриваться только архитектура нейронных сетей. Во второй части будет продемонстрирована независимость ряда методов обучения нейронных сетей от их архитектуры. Однако, для удобства, во второй части главы архитектуры всех парадигм нейронных сетей будут описаны вместе с методами обучения.

Нейронные сети можно классифицировать по разным признакам. Для описания нейронных сетей в данной главе существенной является классификация по типу времени функционирования сетей. По этому признаку сети можно разбить на три класса.

1. Сети с непрерывным временем.

2. Сети с дискретным асинхронным временем.

3. Сети с дискретным временем, функционирующие синхронно.

В данной работе рассматриваются только сети третьего вида, то есть сети, в которых все элементы каждого слоя срабатывают одновременно и затем передают свои сигналы нейронам следующего слоя.

4.1. Конструирование нейронных сетей

Впервые последовательное описание конструирования нейронных сетей из элементов было предложено в книге А.Н. Горбаня [65]. Однако за прошедшее время предложенный А.Н. Горбанем способ конструирования претерпел ряд изменений.

При описании нейронных сетей принято оперировать такими терминами, как нейрон и слой. Однако, при сравнении работ разных авторов (например, [2. 25, 26, 30, 31, 33, 37, 45, 65, 66, 83, 122, 123, 126, 138, 145 – 147, 159, 182, 220, 221, 226, 227, 230, 231, 239, 248, 250, 264, 273 – 275, 280, 309, 312, 313, 338, 341, 345, 365, 367, 377]) выясняется, что если слоем все авторы называют приблизительно одинаковые структуры, то нейроны разных авторов совершенно различны. Таким образом, единообразное описание нейронных сетей на уровне нейронов невозможна. Однако, возможно построение единообразного описания на уровне составляющих нейроны элементов и процедур конструирования сложных сетей из простых.

4.1.1. Элементы нейронной сети


Рис. 1 Простейшие элементы сети

На рис. 1 приведены все элементы, необходимые для построения нейронных сетей. Естественно, что возможно расширение списка нелинейных преобразователей. Однако, это единственный вид элементов, который может дополняться. Вертикальными стрелками обозначены входы параметров (для синапса – синаптических весов или весов связей), а горизонтальными – входные сигналы элементов. С точки зрения функционирования элементов сети сигналы и входные параметры элементов равнозначны. Различие между этими двумя видами параметров относятся к способу их использования в обучении. Кроме того, удобно считать, что параметры каждого элемента являются его свойствами и хранятся при нем. Совокупность параметров всех элементов сети называют вектором параметров сети. Совокупность параметров всех синапсов называют вектором обучаемых параметров сети, картой весов связей или синаптической картой. Отметим, что необходимо различать входные сигналы элементов и входные сигналы сети. Они совпадают только для элементов входного слоя сети.

 

Рис. 2. Построение сети из простейших элементов. 1 - слой синапсов S4 (4 синапса в слое). 2 - каскад-нейрон N4 (4 входных сигнала). 3 - слой точек ветвления SB(2,6) (2 входных сигнала, 6 - выходных). 4 - слой нейронов SN(2,4,2) (2 нейрона, по 4 входных сигнала у каждого нейрона, 2 выходных сигнала). 5 - каскад точек ветвления и нейронов K(4,2,4,2) (4 входных сигнала, 2 нейрона по 4 входных сигнала у каждого нейрона, 2 выходных сигнала каскада). 6 - сеть NW(4,2,3,1) (4 входных сигнала сети, 2 нейрона во входном слое, 3 нейрона в скрытом слое, 1 нейрон в выходном слое).

Из приведенных на рис. 1 элементов можно построить практически любую нейронную сеть. В соответствии с утверждениями теорем, приведенных в работах [36, 37, 57, 64, 70, 286], этих элементов достаточно, чтобы сколь угодно точно приблизить любую непрерывную функцию. Вообще говоря, нет никаких правил, ограничивающих свободу творчества конструктора нейронных сетей. Однако, есть набор структурных единиц построения сетей, позволяющий стандартизовать процесс конструирования. Детальный анализ различных нейронных сетей позволил выделить следующие структурные единицы:

1   элемент – неделимая часть сети, для которой определены методы прямого и обратного функционирования;

2   каскад – сеть составленная из последовательно связанных слоев, каскадов, циклов или элементов;

3   слой – сеть составленная из параллельно работающих слоев, каскадов, циклов или элементов;

4   цикл – каскад выходные сигналы которого поступают на его вход.

Очевидно, что не все элементы являются неделимыми. В следующем разделе будет приведен ряд составных элементов.

Введение трех типов составных сетей связано с двумя причинами: использование циклов приводит к изменению правил остановки работы сети, описанных в разд. "Правила остановки работы сети"; разделение каскадов и слоев позволяет эффективно использовать ресурсы параллельных ЭВМ. Действительно, все сети, входящие в состав слоя, могут работать независимо друг от друга. Тем самым при конструировании сети автоматически закладывается база для использования параллельных ЭВМ.

На рис. 2 приведен пример поэтапного конструирования трехслойной сигмоидной сети.

4.1.2. Составные элементы

Название «составные элементы» противоречит определению элементов. Это противоречие объясняется соображениями удобства работы. Введение составных элементов преследует цель упрощения конструирования. Как правило, составные элементы являются каскадами простых элементов.

 

Рис. 3. а)Фрагмент сети с обычными сумматорами

б) Тот же фрагмент с квадратичными сумматорами из простых элементов.

в)Тот же фрагмент с квадратичными сумматорами с использованием составного элемента - квадратичного сумматора.

Хорошим примером полезности составных элементов может служить использование сумматоров. В ряде работ [35, 53, 107, 127, 294] интенсивно используются сети, нейроны которых содержат нелинейные входные сумматоры. Под нелинейным входным сумматором, чаще всего понимают квадратичные сумматоры – сумматоры, вычисляющие взвешенную сумму всех попарных произведений входных сигналов нейрона. Отличие сетей с квадратичными сумматорами заключается только в использовании этих сумматоров. На рис. 3а приведен фрагмент сети с линейными сумматорами. На рис. 3б – соответствующий ему фрагмент с квадратичными сумматорами, построенный с использованием элементов, приведенных на рис. 1. На (рис. 3в) – тот же фрагмент, построенный с использованием квадратичных сумматоров. При составлении сети с квадратичными сумматорами из простых элементов на пользователя ложится большой объем работ по проведению связей и организации вычисления попарных произведений. Кроме того, рис. 3в гораздо понятнее рис. 3б и содержит ту же информацию. Кроме того, пользователь может изменить тип сумматоров уже сконструированной сети, указав замену одного типа сумматора на другой. На рис. 4 приведены обозначения и схемы наиболее часто используемых составных элементов.

 

Рис. 4. Обозначения и схемы часто используемых составных элементов

Необходимо отметить еще одну разновидность сумматоров, полезную при работе по конструированию сети – неоднородные сумматоры. Неоднородный сумматор отличается от однородного наличием еще одного входного сигнала, равного единице. На рис. 4г приведены схема и обозначения для неоднородного адаптивного сумматора. В табл. 1 приведены значения, вычисляемые однородными и соответствующими им неоднородными сумматорами.

4.1.3. Функционирование сети

Таблица 1

Однородные и неоднородные сумматоры

Название

Однородный сумматор

Неоднородный сумматор

Обозначение

Значение

Обозначение

Значение

Обычный

S

S+

Адаптивный

A

A+

Квадратичный

Q

Q+

Прежде всего, необходимо разделить процессы обучения нейронной сети и использования обученной сети. При использовании обученной сети происходит только решение сетью определенной задачи. При этом синаптическая карта сети остается неизменной. Работу сети при решении задачи будем далее называть прямым функционированием.

При обучении нейронных сетей методом обратного распространения ошибки нейронная сеть (и каждый составляющий ее элемент) должна уметь выполнять обратное функционирование. Во второй части этой главы будет показано, что обратное функционирование позволяет обучать также и нейросети, традиционно считающиеся не обучаемыми, а формируемыми (например, сети Хопфилда [316]). Обратным функционированием называется процесс работы сети, когда на вход двойственной сети подаются определенные сигналы, которые далее распространяются по связям двойственной сети. При прохождении сигналов обратного функционирования через элемент, двойственный элементу с обучаемыми параметрами, вычисляются поправки к параметрам этого элемента. Если на вход сети, двойственной к сети с непрерывными элементами, подается производная некоторой функции F от выходных сигналов сети, то вычисляемые сетью поправки должны быть элементами градиента функции F по обучаемым параметрам сети. Двойственная сеть строится так, чтобы удовлетворять этому требованию.

4.1.4. Методы построения двойственных сетей

Пусть задана нейронная сеть, вычисляющая некоторую функцию (рис. 5а). Необходимо построить двойственную к ней сеть, вычисляющую градиент некоторой функции H от выходных сигналов сети. В книге А.Н. Горбаня «Обучение нейронных сетей» [65] предложен метод построения сети, двойственной к данной. Пример сети, построенной по методу А.Н. Горбаня, приведен на рис. 5б. Для работы такой сети необходимо, обеспечение работы элементов в трех режимах. Первый режим – обычное прямое функционирование (рис. 5а). Второй режим – нагруженное прямое функционирование (рис. 5б, верхняя цепочка). Третий режим – обратное функционирование.

При обычном прямом функционировании каждый элемент вычисляет выходную функцию от входных сигналов и параметров и выдает ее на выход в сеть для передачи далее.

При нагруженном прямом функционировании каждый элемент вычисляет выходную функцию от входных сигналов и параметров и выдает ее на выход в сеть для передачи далее. Кроме того, он вычисляет производные выходной функции по каждому входному сигналу и параметру и запоминает их (блоки под элементами в верхней цепочке на рис. 5б). При обратном функционировании элементы исходной сети выдают на специальные выходы ранее вычисленные производные (связи между верхней и нижней цепочками на рис. 5б), которые далее используются для вычисления градиентов по параметрам и входным сигналам сети двойственной сетью (нижняя цепочка на рис. 5б). Вообще говоря, для хорошей организации работы такой сети требуется одно из следующих устройств. Либо каждый элемент должен получать дополнительный сигнал выдачи запомненных сигналов (ранее вычисленных производных), либо к сети следует добавить элемент, вычисляющий функцию оценки.

Рис. 5 Схема сети (а), сети и двойственной сети по методу А.Н. Горбаня (б) и по унифицированному методу (в).

Первое решение требует дополнительных линий связи с каждым элементом, за исключением точек ветвления, что в существенно увеличивает (приблизительно в полтора раза) и без того большое число связей. Большое число связей, в свою очередь, увеличивает сложность и стоимость аппаратной реализации нейронной сети.

Второй подход – включение оценки как элемента в нейронную сеть – лишает структуру гибкости, поскольку для замены функции оценки потребуется изменять сеть. Кроме того, оценка будет достаточно сложным элементом. некоторые оценки включают в себя процедуру сортировки и другие сложные операции (см. главу «Оценка и интерпретатор ответа»).

Метод нагруженного функционирования позволяет вычислять не только градиент оценки, но и производные по входным параметрам и сигналам от произвольного функционала от градиента. Для этого строится дважды двойственная сеть. Для работы дважды двойственной сети необходимо, чтобы элементы выполняли дважды двойственное функционирование – вычисляли не только выходной сигнал и производные выходного сигнала по входным сигналам и параметрам, но и матрицу вторых производных выходного сигнала по входным сигналам и параметрам. Кроме того, построение дважды двойственной сети потребует дополнительных затрат от пользователя, поскольку процедура построения двойственной и дважды двойственной сети достаточно понятна, но описывается сложным алгоритмом. При этом построение дважды двойственной сети не является построением сети двойственной к двойственной.

Для унификации процедуры построения сети, двойственной к данной сети, автором разработан унифицированный метод двойственности. В этом методе каждому элементу исходной сети ставится в соответствие подсеть. На рис. 5в приведен пример двойственной сети, построенной по унифицированному методу. Каждый элемент, кроме точки ветвления и сумматора, заменяется на элемент, вычисляющий производную выходной функции исходного элемента по входному сигналу (параметру) и умножитель, умножающий сигнал обратного функционирования на вычисленную производную. Если элемент имеет несколько входов и параметров, то он заменяется на столько описанных выше подсетей, сколько у него входных сигналов и параметров. При этом сигнал обратного функционирования пропускается через точку ветвления.

Двойственная сеть, построенная по этому методу, требует включения в нее оценки как элемента. Достоинством этого метода является универсальность. Для построения дважды двойственной сети достаточно построить сеть двойственную к двойственной. Кроме того, построенная по этому методу сеть имеет меньшее время срабатывания.

Анализ этих двух методов с точки зрения аппаратной реализации, выявил в них следующие недостатки.

·   Для реализации обратного функционирования необходимо изменять архитектуру сети, причем в ходе обратного функционирования связи прямого функционирования не используются.

·   Необходимо включать в сеть оценку как один из элементов

Для устранения этих недостатков, автором предложен метод самодвойственных сетей. Этот метод не позволяет строить дважды двойственных сетей, что делает его менее мощным, чем два предыдущих. Однако большинство методов обучения не требует использования дважды двойственных сетей, что делает это ограничение не очень существенным. Идея самодвойственных сетей состоит в том, чтобы каждый элемент при прямом функционировании запоминал входные сигналы. А при обратном функционировании вычислял все необходимые производные, используя ранее запомненные сигналы, и умножал их на сигнал обратного функционирования.

Такая модификация делает элементы более сложными, чем в двух предыдущих методах. Однако этот метод дает следующие преимущества по отношению к методу нагруженного функционирования и унифицированному методу двойственности.

·   Для элементов не требуется дополнительного управления, поскольку получение сигнала прямого или обратного функционирования инициирует выполнение одной из двух функций.

·   Для выполнения обратного функционирования не требуется дополнительных элементов и линий связи между элементами.

·   Оценка является независимым от сети компонентом.

Наиболее существенным является второе преимущество, поскольку при аппаратной реализации нейронных сетей наиболее существенным ограничением является число связей. Так в приведенных на рис. 5 сетях задействовано для самодвойственной сети – 6 связей, для сети, построенной по методу нагруженного функционирования – 20 связей, а для сети, построенной по методу унифицированной двойственности – 27 связей. Следует заметить, что с ростом размеров сети данные пропорции будут примерно сохраняться.

Исходя из соображений экономичной и эффективной аппаратной реализации и функционального разделения компонентов далее в данной работе рассматриваются только самодвойственные сети.

4.1.5. Элементы самодвойственных сетей

Если при обратном функционировании самодвойственной сети на ее выход подать производные некоторой функции F по выходным сигналам сети, то в ходе обратного функционирования на входах параметров сети должны быть вычислены элементы градиента функции F по параметрам сети, а на входах сигналов – элементы градиента функции F по входным сигналам. Редуцируя это правило на отдельный элемент, получаем следующее требование к обратному функционированию элемента самодвойственной сети: Если при обратном функционировании элемента самодвойственной сети на его выход подать производные некоторой функции F по выходным сигналам элемента, то в ходе обратного функционирования на входах параметров элемента должны быть вычислены элементы градиента функции F по параметрам элемента, а на входах сигналов – элементы градиента функции F по входным сигналам элемента. Легко заметить, что данное требование автоматически обеспечивает подачу на выход элемента, предшествующего данному, производной функции F по выходным сигналам этого элемента.

Далее в этом разделе для каждого из элементов, приведенных на рис.1 определены правила обратного функционирования, в соответствии со сформулированными выше требованиями к элементам самодвойственной сети.

4.1.5.1. Синапс

У синапса два входа – вход сигнала и вход синаптического веса (рис. 6а). Обозначим входной сигнал синапса через , а синаптический вес через . Тогда выходной сигнал синапса равен . При обратном функционировании на выход синапса подается сигнал . На входе синапса должен быть получен сигнал обратного функционирования, равный , а на входе синаптического веса – элемент градиента, равный  (рис. 6б).

4.1.5.2. Умножитель

 Рис. 7. Прямое (а) и обратное (б) функционирование  умножителя

 Рис. 6. Прямое (а) и обратное (б) функционирование синапса

Умножитель имеет два входных сигнала и не имеет параметров. Обозначим входные сигнал синапса через . Тогда выходной сигнал умножителя равен  (рис. 7а). При обратном функционировании на выход умножителя подается сигнал . На входах сигналов  и  должны быть получены сигналы обратного функционирования, равные  и , соответственно (рис. 7б).

4.1.5.3. Точка ветвления

 Рис. 8. Прямое (а) и обратное (б) функционирование точки ветвления

В отличие от ранее рассмотренных элементов, точка ветвления имеет только один вход и несколько выходов. Обозначим входной сигнал через x, а выходные через , причем  (рис. 8а). При обратном функционировании на выходные связи точки ветвления подаются сигналы  (рис. 8б). На входной связи должен получаться сигнал, равный . Можно сказать, что точка ветвления при обратном функционировании переходит в сумматор, или, другими словами, сумматор является двойственным по отношению к точке ветвления.

4.1.5.4. Сумматор

Сумматор считает сумму входных сигналов. Обычный сумматор не имеет параметров. При описании прямого и обратного функционирования ограничимся описанием простого сумматора, поскольку функционирование адаптивного и квадратичного сумматора может быть получено как прямое и обратное функционирование сети в соответствии с их схемами, приведенными на рис. 3б и 3в. Обозначим входные сигналы сумматора через  (рис. 9а). Выходной сигнал равен . При обратном функционировании на выходную связь сумматора подается сигнал  (рис. 9б). На входных связях должны получаться сигналы, равные Из последней формулы следует, что все сигналы обратного функционирования, выдаваемые на входные связи сумматора, равны. Таким образом сумматор при обратном функционировании переходит в точку ветвления, или, другими словами, сумматор является двойственным по отношению к точке ветвления.

4.1.5.5. Нелинейный Паде преобразователь

 Рис. 10. Прямое (а) и обратное (б) функционирование нелинейного Паде

Нелинейный Паде преобразователь или Паде элемент имеет два входных сигнала и один выходной. Обозначим входные сигналы через . Тогда выходной сигнал Паде элемента равен  (рис. 10а). При обратном функционировании на выход Паде элемента подается сигнал . На входах сигналов  и  должны быть получены сигналы обратного функционирования, равные  и , соответственно (рис. 10б).

4.1.5.6. Нелинейный сигмоидный преобразователь

 Рис. 11. Прямое (а) и обратное (б) функционирование нелинейного сигмоидного преобразователя

Нелинейный сигмоидный преобразователь или сигмоидный элемент имеет один входной сигнал и один параметр. Сторонники чистого коннекционистского подхода [265] считают, что обучаться в ходе обучения нейронной сети могут только веса связей. С этой точки зрения параметр сигмоидного элемента является не обучаемым и, как следствие, для него нет необходимости вычислять соответствующий элемент градиента. Однако, часть исследователей полагает, что нужно обучать все параметры всех элементов сети. Исходя из этого, опишем вычисление этим элементом производной функции оценки по содержащемуся в нем параметру.

Обозначим входной сигнал через , параметр через , а вычисляемую этим преобразователем функцию через (рис. 11а). При обратном функционировании на выход сигмоидного элемента подается сигнал . На входе сигнала должен быть получен сигнал обратного функционирования, равный , а на входе параметра – элемент градиента, равный  (рис. 11б).

4.1.5.7. Произвольный непрерывный нелинейный преобразователь

Произвольный непрерывный нелинейный преобразователь имеет несколько входных сигналов, а реализуемая им функция зависит от нескольких параметров. Выходной сигнал такого элемента вычисляется как некоторая функция , где x – вектор входных сигналов, а a – вектор параметров. При обратном функционировании на выходную связь элемента подается сигнал обратного функционирования, равный . На входы сигналов выдаются сигналы обратного функционирования, равные , а на входах параметров вычисляются элементы градиента, равные .

4.1.5.8. Пороговый преобразователь

Пороговый преобразователь, реализующий функцию определения знака (рис. 12а), не является элементом с непрерывной функцией, и, следовательно, его обратное функционирование не может быть определено из требования вычисления градиента. Однако, при обучении сетей с пороговыми преобразователями полезно иметь возможность вычислять поправки к параметрам. Так как для порогового элемента нельзя определить однозначное поведение при обратном функционировании, предлагается доопределить его, исходя из соображений полезности при конструировании обучаемых сетей. Основным методом обучения сетей с пороговыми элементами является правило Хебба (подробно рассмотрено во второй части главы). Оно состоит из двух процедур, состоящих в изменении «весов связей между одновременно активными нейронами». Для этого правила пороговый элемент при обратном функционировании должен выдавать сигнал обратного функционирования, совпадающий с выданным им сигналом прямого функционирования (рис. 12б). Такой пороговый элемент будем называть зеркальным. При обучении сетей Хопфилда  [316], подробно рассмотренном во второй части главы, необходимо использовать «прозрачные» пороговые элементы, которые при обратном функционировании пропускают сигнал без изменения (рис. 12в).

 Рис. 12. Прямое (а) и обратное (б,в) функционирование порогового элемента.

б) “Зеркальный” пороговый элемент

в) “Прозрачный” пороговый элемент

4.1.6. Правила остановки работы сети

При использовании сетей прямого распространения (сетей без циклов) вопроса об остановке сети не возникает. Действительно, сигналы поступают на элементы первого (входного) слоя и, проходя по связям, доходят до элементов последнего слоя. После снятия сигналов с последнего слоя все элементы сети оказываются «обесточенными», то есть ни по одной связи сети не проходит ни одного ненулевого сигнала. Сложнее обстоит дело при использовании сетей с циклами. В случае общего положения, после подачи сигналов на входные элементы сети по связям между элементами, входящими в цикл, ненулевые сигналы будут циркулировать сколь угодно долго.

Существует два основных правила остановки работы сети с циклами. Первое правило состоит в остановке работы сети после указанного числа срабатываний каждого элемента. Циклы с таким правилом остановки будем называть ограниченными.

Второе правило остановки работы сети – сеть прекращает работу после установления равновесного распределения сигналов в цикле. Такие сети будем называть равновесными. Примером равновесной сети может служить сеть Хопфилда [316] (см. разд. "Сети Хопфилда").

4.1.7. Архитектуры сетей

Как уже отмечалось ранее, при конструировании сетей из элементов можно построить сеть любой архитектуры. Однако и при произвольном конструировании можно выделить наиболее общие признаки, существенно отличающие одну сеть от другой. Очевидно, что замена простого сумматора на адаптивный или даже на квадратичный не приведут к существенному изменению структуры сети, хотя число обучаемых параметров увеличится. Однако, введение в сеть цикла сильно изменяет как структуру сети, так и ее поведение. Таким образом можно все сети разбить на два сильно отличающихся класса: ациклические сети и сети с циклами. Среди сетей с циклами существует еще одно разделение, сильно влияющее на способ функционирования сети: равновесные сети с циклами и сети с ограниченными циклами.

 Рис. 13. Фрагмент
немонотонной сети

Большинство используемых сетей не позволяют определить, как повлияет изменение какого-либо внутреннего параметра сети на выходной сигнал. На рис. 13 приведен пример сети, в которой увеличение параметра  приводит к неоднозначному влиянию на сигнал : при отрицательных  произойдет уменьшение , а при положительных  – увеличение. Таким образом, выходной сигнал такой сети немонотонно зависит от параметра . Монотонные сети понятнее для анализа, а поведение монотонных систем хорошо изучено (см. например, [161]). Для получения монотонной зависимости выходных сигналов сети от параметров внутренних слоев (то есть всех слоев кроме входного) необходимо использовать специальную монотонную архитектуру нейронной сети. Принципиальная схема сетей монотонной архитектуры приведена на рис. 14.

 Рис. 14. Общая схема монотонной сети. Верхний ряд - возбуждающие блоки нейронов, нижний ряд - тормозящие. Буквой “Т” - помечены тормозящие связи, буквой “В” - возбуждающие

Основная идея построения монотонных сетей состоит в разделении каждого слоя сети на два – возбуждающий и тормозящий. При этом все связи в сети устроены так, что элементы возбуждающей части слоя возбуждают элементы возбуждающей части следующего слоя и тормозят тормозящие элементы следующего слоя. Аналогично, тормозящие элементы возбуждают тормозящие элементы и тормозят возбуждающие элементы следующего слоя. Названия «тормозящий» и «возбуждающий» относятся к влиянию элементов обеих частей на выходные элементы.

 Рис. 15. Немонотонная сеть с Паде элементами

Отметим, что для сетей с сигмоидными элементами требование монотонности означает, что веса всех связей должны быть неотрицательны. Для сетей с Паде элементами требование не отрицательности весов связей является необходимым условием бессбойной работы. Требование монотонности для сетей с Паде элементами приводит к изменению архитектуры сети, не накладывая никаких новых ограничений на параметры сети. На рис. 15 приведены пример немонотонной сети, а на рис. 16 монотонной сети с Паде элементами.

 Рис. 16. Монотонная сеть с Паде элементами. Жирными линиями обозначены возбуждающие  связи и элементы возбуждающей части сети

Особо отметим архитектуру еще одного класса сетей – сетей без весов связей. Эти сети, в противовес коннекционистским, не имеют обучаемых параметров связей. Любую сеть можно превратить в сеть без весов связей заменой всех синапсов на умножители. Легко заметить, что получится такая же сеть, только вместо весов связей будут использоваться сигналы. Таким образом в сетях без весов связей выходные сигналы одного слоя могут служить для следующего слоя как входными сигналами, так и весами связей. Заметим, что вся память таких сетей содержится в значениях параметров нелинейных преобразователей. Из разделов "Синапс" и "Умножитель" следует, что сети без весов связей способны вычислять градиент функции оценки и затрачивают на это ровно тоже время, что и аналогичная сеть с весами связей.

4.1.8. Модификация синаптической карты (обучение)

Кроме прямого и обратного функционирования, все элементы должны уметь выполнять еще одну операцию – модификацию параметров. Процедура модификации параметров состоит в добавлении к существующим параметрам вычисленных поправок (напомним, что для сетей с непрерывно дифференцируемыми элементами вектор поправок является градиентом некоторой функции от выходных сигналов). Если обозначить текущий параметр элемента через , а вычисленную поправку через , то новое значение параметра вычисляется по формуле . Параметры обучения  и  определяются компонентом учитель и передаются сети вместе с запросом на обучение. В некоторых случаях бывает полезно использовать более сложную процедуру модификации карты.

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

4.1.9. Контрастирование и нормализация сети

В последние годы широкое распространение получили различные методы контрастирования или скелетонизации нейронных сетей. В ходе процедуры контрастирования достигается высокая степень разреженности синаптической карты нейронной сети, так как большинство связей получают нулевые веса (см. например [100, 171, 307. 308]).

Очевидно, что при такой степени разреженности ненулевых параметров проводить вычисления так, как будто структура сети не изменилась, неэффективно. Возникает потребность в процедуре нормализации сети, то есть фактического удаления нулевых связей из сети, а не только из обучения. Процедура нормализации состоит из двух этапов:

1. Из сети удаляются все связи, имеющие нулевые веса и исключенные из обучения.

2. Из сети удаляются все подсети, выходные сигналы которых не используются другими подсетями в качестве входных сигналов и не являются выходными сигналами сети в целом.

В ходе нормализации возникает одна трудность: если при описании нейронной сети все нейроны одинаковы, и можно описать нейрон один раз, то после удаления отконтрастированных связей нейроны обычно имеют различную структуру. Компонент сеть должен отслеживать ситуации, когда два блока исходно одного и того же типа уже не могут быть представлены в виде этого блока с различными параметрами. В этих случаях компонент сеть порождает новый тип блока. Правила порождения имен блоков приведены в описании выполнения запроса на нормализацию сети.

4.2. Примеры сетей и алгоритмов их обучения

В этом разделе намеренно допущено отступление от общей методики – не смешивать разные компоненты. Это сделано для облегчения демонстрации построения нейронных сетей обратного распространения, позволяющих реализовать на них большинство известных алгоритмов обучения нейронных сетей.

4.2.1. Сети Хопфилда

Классическая сеть Хопфилда [316], функционирующая в дискретном времени, строится следующим образом. Пусть – набор эталонных образов . Каждый образ, включая и эталоны, имеет вид n-мерного вектора с координатами, равными нулю или единице. При предъявлении на вход сети образа x сеть вычисляет образ, наиболее похожий на x. В качестве меры близости образов выберем скалярное произведение соответствующих векторов. Вычисления проводятся по следующей формуле: . Эта процедура выполняется до тех пор, пока после очередной итерации не окажется, что . Вектор x, полученный в ходе последней итерации, считается ответом. Для нейросетевой реализации формула работы сети переписывается в следующем виде:

или

где .

На рис. 17 приведена схема сети Хопфилда [316] для распознавания четырехмерных образов. Обычно сети Хопфилда [316] относят к сетям с формируемой синаптической картой. Однако, используя разработанный в первой части главы набор элементов, можно построить обучаемую сеть. Для построения такой сети используем «прозрачные» пороговые элементы. Ниже приведен алгоритм обучения сети Хопфилда [316].

1. Положим все синаптические веса равными нулю.

2. Предъявим сети первый эталон  и проведем один такт функционирования вперед, то есть цикл будет работать не до равновесия, а один раз (см. рис. 17б).

3. Подадим на выход каждого нейрона соответствующую координату вектора  (см. рис. 17в). Поправка, вычисленная на j-ом синапсе i-го нейрона, равна произведению сигнала прямого функционирования на сигнал обратного функционирования. Поскольку при обратном функционировании пороговый элемент прозрачен, а сумматор переходит в точку ветвления, то поправка равна .

4.Далее проведем шаг обучения с параметрами обучения, равными единице. В результате получим .

Повторяя этот алгоритм, начиная со второго шага, для всех эталонов получим , что полностью совпадает с формулой формирования синаптической карты сети Хопфилда [316], приведенной в начале раздела.

Существует множество различных алгоритмов решения этой задачи. Рассмотрим наиболее эффективный из них.

1. Зададимся некоторым набором начальных точек .

2. Разобьем множество точек  на k классов по правилу .

1. По полученному разбиению вычислим новые точки  из условия минимальности .

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

Второй и третий шаги алгоритма будем повторять до тех пор, пока набор точек  не перестанет изменяться. После окончания обучения получаем нейронную сеть, способную для произвольной точки x вычислить квадраты евклидовых расстояний от этой точки до всех точек  и, тем самым, отнести ее к одному из k классов. Ответом является номер нейрона, выдавшего минимальный сигнал.

Теперь рассмотрим сетевую реализацию. Во первых, вычисление квадрата евклидова расстояния достаточно сложно реализовать в виде сети (рис. 18а). Однако заметим, что нет необходимости вычислять квадрат расстояния полностью. Действительно,

Отметим, что в последней формуле первое слагаемое не зависит от точки x, второе вычисляется адаптивным сумматором, а третье одинаково для всех сравниваемых величин. Таким образом, легко получить нейронную сеть, которая вычислит для каждого класса только первые два слагаемых (рис. 18б).

Второе соображение, позволяющее упростить обучение сети, состоит в отказе от разделения второго и третьего шагов алгоритма.

 Рис. 18. Сеть Кохонена. Прямое и обратное функционирование нейронов сети Кохонена

Алгоритм классификации.

1. На вход нейронной сети, состоящей из одного слоя нейронов, приведенных на рис. 18б, подается вектор x.

2. Номер нейрона, выдавшего минимальный ответ, является номером класса, к которому принадлежит вектор.

Алгоритм обучения.

1.   Полагаем поправки всех синапсов равными нулю.

2.   Для каждой точки множества выполняем следующую процедуру.

2.1. Предъявляем точку сети для классификации.

2.2. Пусть при классификации получен ответ – класс l. Тогда для обратного функционирования сети подается вектор , координаты которого определяются по следующему правилу:.

2.3. Вычисленные для данной точки поправки добавляются к ранее вычисленным.

3.   Для каждого нейрона производим следующую процедуру.

3.1. Если поправка, вычисленная последним синапсом равна 0, то нейрон удаляется из сети.

3.2. Полагаем параметр обучения равным величине, обратной к поправке, вычисленной последним синапсом.

3.3. Вычисляем сумму квадратов накопленных в первых n синапсах поправок и, разделив на -2, заносим в поправку последнего синапса.

3.4. Проводим шаг обучения с параметрами , .

4.   Если вновь вычисленные синаптические веса отличаются от полученных на предыдущем шаге, то переходим к первому шагу алгоритма.

В пояснении нуждается только второй и третий шаги алгоритма. Из рис. 18в видно, что вычисленные на шаге 2.2 алгоритма поправки будут равны нулю для всех нейронов, кроме нейрона, выдавшего минимальный сигнал. У нейрона, выдавшего минимальный сигнал, первые n поправок будут равны координатам распознававшейся точки x, а поправка последнего синапса равна единице. После завершения второго шага алгоритма поправка последнего синапса i-о нейрона будет равна числу точек, отнесенных к i-му классу, а поправки остальных синапсов этого нейрона равны сумме соответствующих координат всех точек i-о класса. Для получения правильных весов остается только разделить все поправки первых n синапсов на поправку последнего синапса, положить последний синапс равным сумме квадратов полученных величин, а остальные синапсы – полученным для них поправкам, умноженным на -2. Именно это и происходит при выполнении третьего шага алгоритма.

4.2.3. Персептрон Розенблатта

Персептрон Розенблатта [147, 185] является исторически первой обучаемой нейронной сетью. Существует несколько версий персептрона. Рассмотрим классический персептрон – сеть с пороговыми нейронами и входными сигналами, равными нулю или единице. Опираясь на результаты, изложенные в работе [147] можно ввести следующие ограничения на структуру сети.

1. Все синаптические веса могут быть целыми числами.

2. Многослойный персептрон по своим возможностям эквивалентен двухслойному. Все нейроны имеют синапс, на который подается постоянный единичный сигнал. Вес этого синапса далее будем называть порогом. Каждый нейрон первого слоя имеет единичные синаптические веса на всех связях, ведущих от входных сигналов, и его порог равен числу входных сигналов сумматора, уменьшенному на два и взятому со знаком минус.

Таким образом, можно ограничиться рассмотрением только двухслойных персептронов с не обучаемым первым слоем. Заметим, что для построения полного первого слоя пришлось бы использовать  нейронов, где n – число входных сигналов персептрона. На рис. 19а приведена схема полного персептрона для трехмерного вектора входных сигналов. Поскольку построение такой сети при достаточно большом n невозможно, то обычно используют некоторое подмножество нейронов первого слоя. К сожалению, только полностью решив задачу можно точно указать необходимое подмножество. Обычно используемое подмножество выбирается исследователем из каких-то содержательных соображений или случайно.

 Рис. 19. Персептрон Розенблатта. Прямое и обратное функционирование второго слоя персептрона
Розенблатта.

Классический алгоритм обучения персептрона является частным случаем правила Хебба. Поскольку веса связей первого слоя персептрона являются не обучаемыми, веса нейрона второго слоя в дальнейшем будем называть просто весами. Будем считать, что при предъявлении примера первого класса персептрон должен выдать на выходе нулевой сигнал, а при предъявлении примера второго класса – единичный. Ниже приведено описание алгоритма обучения персептрона.

1.   Полагаем все веса равными нулю.

2. Проводим цикл предъявления примеров. Для каждого примера выполняется следующая процедура.

2.1.Если сеть выдала правильный ответ, то переходим к шагу 2.4.

2.2.Если на выходе персептрона ожидалась единица, а был получен ноль, то веса связей, по которым прошел единичный сигнал, уменьшаем на единицу.

2.3.Если на выходе персептрона ожидался ноль, а была получена единица, то веса связей, по которым прошел единичный сигнал, увеличиваем на единицу.

2.4.Переходим к следующему примеру. Если достигнут конец обучающего множества, то переходим к шагу 3, иначе возвращаемся на шаг 2.1.

3. Если в ходе выполнения второго шага алгоритма хоть один раз выполнялся шаг 2.2 или 2.3 и не произошло зацикливания, то переходим к шагу 2. В противном случае обучение завершено.

В этом алгоритме не предусмотрен механизм отслеживания зацикливания обучения. Этот механизм можно реализовывать по разному. Наиболее экономный в смысле использования дополнительной памяти имеет следующий вид.

1. k=1; m=0. Запоминаем веса связей.

2. После цикла предъявлений образов сравниваем веса связей с запомненными. Если текущие веса совпали с запомненными, то произошло зацикливание. В противном случае переходим к шагу 3.

3.   m=m+1. Если m<k, то переходим ко второму шагу.

4. k=2k; m=0. Запоминаем веса связей и переходим к шагу 2.

Поскольку длина цикла конечна, то при достаточно большом k зацикливание будет обнаружено.

Для использования в обучении сети обратного функционирования, необходимо переписать второй шаг алгоритма обучения в следующем виде.

2.   Проводим цикл предъявления примеров. Для каждого примера выполняется следующая процедура.

2.1.      Если сеть выдала правильный ответ, то переходим к шагу 2.5.

2.2.      Если на выходе персептрона ожидалась единица, а был получен ноль, то на выход сети при обратном функционировании подаем .

2.3.      Если на выходе персептрона ожидался ноль, а была получена единица, то на выход сети при обратном функционировании подаем .

2.4.      Проводим шаг обучения с единичными параметрами.

2.5.      Переходим к следующему примеру. Если достигнут конец обучающего множества, то переходим к шагу 3, иначе возвращаемся на шаг 2.1.

На рис. 19в приведена схема обратного функционирования нейрона второго слоя персептрона. Учитывая, что величины входных сигналов этого нейрона равны нулю или единице, получаем эквивалентность модифицированного алгоритма исходному. Отметим также, что при обучении персептрона впервые встретились не обучаемые параметры – веса связей первого слоя.

4.3. Язык описания нейронных сетей

В данном разделе описан язык описания нейронных сетей.

4.3.1. Структура компонента

Рассмотрим более подробно структуры данных сети. Как уже было описано в первой части главы, сеть строится иерархически от простых подсетей к сложным. Простейшими подсетями являются элементы. Подсеть каждого уровня имеет свое имя и тип. Существуют следующие типы подсетей: элемент, каскад, слой, цикл с фиксированным числом тактов функционирования и цикл, функционирующий до тех пор, пока не выполнится некоторое условие. Последние четыре типа подсетей будем называть блоками. Имена подсетей определяются при конструировании. В разделе «Имена структурных единиц компонентов» приведены правила построения полного и однозначного имен подсети. В качестве примера рассмотрим сеть, конструирование которой проиллюстрировано на рис. 2. В описании сети NW однозначное имя первого нейрона второго слоя имеет вид K[2].SN.N[1]. При описании слоя однозначное имя первого нейрона записывается как N[1]. В квадратных скобках указываются номер экземпляра подсети, входящей в непосредственно содержащую ее структуру в нескольких экземплярах.

4.3.2. Сигналы и параметры

При использовании контрастирования для изменения структуры сети и значений обучаемых параметров другим компонентам бывает необходим прямой доступ к сигналам и параметрам сети в целом или отдельных ее подсетей. Для адресации входных и выходных сигналов используются имена InSignals и OutSignals, соответственно. Таким образом, для получения массива входных сигналов второго слоя сети, приведенной на рис. 2, необходимо запросить массив NW.K[2].InSignals, а для получения выходного сигнала всей сети можно воспользоваться любым из следующего списка имен:

·   NW.OutSignals;

·   NW.N.OutSignals.

Для получения конкретного сигнала из массива сигналов необходимо в конце в квадратных скобках указать номер сигнала. Например, для получения третьего входного сигнала второго слоя сети нужно указать следующее имя – NW.K[2].InSignals[3].

Для получения доступа к параметрам нужно указать имя подсети, к чьим параметрам нужен доступ и через точку ключевое слово Parameters. При необходимости получить конкретный параметр, его номер в квадратных скобках записывается после ключевого слова Parameters.

4.3.3. Обучаемые и не обучаемые параметры и сигналы

При обучении параметров и сигналов (использование обучения сигналов описано во введении) возникает необходимость обучать только часть из них. Так, например, при описании обучения персептрона во второй части этой главы было отмечено, что обучать необходимо только  веса связей второго слоя. Для реализации этой возможности используются два массива логических переменных – маска обучаемых параметров и маска обучаемых входных сигналов.

4.3.4. Дополнительные переменные

При описании структуры сетей необходимо учитывать следующую дополнительные переменные, доступные в методах Forw и Back. Для каждой сети при прямом функционировании определен следующий набор переменных:

·   InSignals[K] – массив из K действительных чисел, содержащих входные сигналы прямого функционирования.

·   OutSignals[N] – массив из N действительных чисел, в которые заносятся выходные сигналы прямого функционирования.

·   Parameters[M] – массив из M действительных чисел, содержащих параметры сети.

При выполнении обратного функционирования сети доступны еще три массива:

·   Back.InSignals[K] – массив из K действительных чисел, параллельный массиву InSignals, в который заносятся выходные сигналы обратного функционирования.

·   Back.OutSignals[N] – массив из N действительных чисел,  параллельный массиву OutSignals, содержащий входные сигналы обратного функционирования.

·   Back.Parameters[M] – массив из M действительных чисел, параллельный массиву Parameters, в который заносятся вычисленные при обратном функционировании поправки к параметрам сети.

При обучении (модификации параметров или входных сигналов) доступны все переменные обратного функционирования и еще два массива:

·   InSignalMask[K] – массив из K логических переменных, параллельный массиву InSignals, содержащий маску обучаемости входных сигналов.

·   ParamMask[M] – массив из M логических переменных, параллельный массиву Parameters, содержащий маску обучаемости параметров.

4.3.5. Приведение и преобразование типов

Есть два пути использовать переменную одного типа как переменную другого типа. Первый путь состоит в преобразовании значения к заданному типу. Так, для преобразования целочисленной переменной к действительному типу, достаточно просто присвоить переменной действительного типа целочисленное значение. С обратным преобразованием сложнее, поскольку не ясно что делать с дробной частью. В табл. 2 приведены все типы, которые можно преобразовать присваиванием переменной другого типа. В табл. 3 приведены все функции преобразования типов.

Таблица 2

Преобразование типов прямым присваиванием
переменной значения выражения

Тип

переменной

Тип

выражения

Пояснение

Real

Real, Integer, Long

Значение преобразуется к плавающему виду. При преобразовании значения выражения типа Long возможна потеря точности.

Long

Integer, Long

При преобразовании типа Integer, действуют следующие правила. Значение переменной помещается в два младших байта. Если значение выражения больше либо равно нолю, то старшие байты равны H0000, в противном случае старшие байты равны HFFFF.

Integer

Integer, Long

При преобразовании выражения типа Long значение двух старших байт отбрасывается.

 

Таблица 3

Функции преобразования типов

Имя функции

Тип

аргумента

Тип

результата

Описание

Real

Real, Integer, Long

Real

Аналогично прямому присваиванию

Integer

Integer, Long

Integer

Аналогично прямому присваиванию

Long

Integer, Long

Long

Аналогично прямому присваиванию

Str

Real, Integer, Long

String

Представляет числовой аргумент в виде символьной строки в десятичном виде

Round

Real

Long

Округляет действительное значение до ближайшего длинного целого. Если значение действительного выражения выходит за диапазон длинного целого, то результат равен нулю.

Truncate

Real

Long

Преобразует действительное значение в длинное целое путем отбрасывания дробной части. Если значение действительного выражения выходит за диапазон длинного целого, то результат равен нулю.

LVal

String

Long

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

RVal

String

Real

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

StrColor

Color

String

Преобразует внутреннее представление переменной типа Color в соответствии с разд. «Значение переменной типа цвет»

ValColor

String

Color

Преобразует символьное представление переменной типа Color во внутреннее.

Color

Integer

Color

Интерпретирует целое число как значение типа Color.

При вычислении числовых выражений действуют следующие правила преобразования типов:

1. Выражения вычисляются слева на право.

2. Если два операнда имеют один тип, то результат имеет тот же тип.

3. Если аргументы имеют разные типы, то выражение имеет старший из двух типов. Список числовых типов по убыванию старшинства: Real, Long, Integer.

4. Результат операции деления действительных чисел (операция «/») всегда имеет тип Real, вне зависимости от типов аргументов.

В отличие от преобразования типов приведение типов позволяет по-разному интерпретировать одну область памяти. Функция приведения типа применима только к переменным или элементам массива (преобразование типов применимо и к выражениям). Рекомендуется использовать приведение типов только для типов, имеющих одинаковую длину. Например, Integer и Color или Real и Long. Список функций приведения типов приведен в табл. 4.

Таблица 4

Функции приведения типов

Название

Тип

результата

Описание

TReal

Real

Четыре байта, адресуемые приводимой переменной, интерпретируются как действительное число.

Tinteger

Integer

Два байта, адресуемые приводимой переменной, интерпретируются как целое число.

TLong

Long

Четыре байта, адресуемые приводимой переменной, интерпретируются как длинное целое.

TRealArray

RealArray

Область памяти, адресуемая приводимой переменной, интерпретируются как массив действительных чисел.

TPRealArray

PRealArray

Четыре байта, адресуемые приводимой переменной, интерпретируются как указатель на массив действительных чисел.

Таблица 4

Функции приведения типов (Продолжение)

Название

Тип

результата

Описание

TIntegerArray

IntegerArray

Область памяти, адресуемая приводимой переменной, интерпретируются как массив целых чисел.

TPIntegerArray

PIntegerArray

Четыре байта, адресуемые приводимой переменной, интерпретируются как указатель на массив целых чисел.

TLongArray

LongArray

Область памяти, адресуемая приводимой переменной, интерпретируются как массив длинных целых.

TPLongArray

PLongArray

Четыре байта, адресуемые приводимой переменной, интерпретируются как указатель на массив длинных целых.

TLogic

Logic

Адресуемый приводимой переменной байт интерпретируются как логическая переменная.

TLogicArray

LogicArray

Область памяти, адресуемая приводимой переменной, интерпретируются как массив логических переменных.

TPLogicArray

LogicArray

Четыре байта, адресуемые приводимой переменной, интерпретируются как указатель на массив логических переменных.

TColor

Color

Два байта, адресуемые приводимой переменной, интерпретируются как переменная типа цвет.

TFuncType

FuncType

Четыре байта, адресуемые приводимой переменной, интерпретируются как адрес функции.

TPointer

Pointer

Четыре байта, адресуемые приводимой переменной, интерпретируются как адрес.

Таблица 4

Функции приведения типов (Продолжение)

Название

Тип

результата

Описание

TString

String

256 байт области памяти, адресуемой приводимой переменной, интерпретируются как строка символов.

TPString

PString

Четыре байта, адресуемые приводимой переменной, интерпретируются как указатель на строку символов.

TVisual

Visual

Четыре байта, адресуемые приводимой переменной, интерпретируются как отображаемый элемент.

Следующие примеры иллюстрируют использование преобразования и приведения типов:

При вычислении следующих четырех выражений, получаются различные результаты

4096 * 4096 = 0

Поскольку константа 4096 имеет тип Integer, а 4096 * 4096 = 16777216 = 256 * 65536 , то есть младшие два байта результата равны нулю.

Long(4096 * 4096) = 0

Поскольку оба сомножителя имеет тип Integer, то и выражение имеет тип Integer. Следовательно, результат умножения равен нулю, который затем преобразуется к типу Long.

Long(4096) * 4096 = 16777216

Поскольку первый сомножитель имеет тип длинное целое, то и выражение имеет тип длинное целое.

4096.0 * 4096 = 1.677722E+7

Поскольку первый сомножитель имеет тип Real, то и выражение имеет тип Real. Из-за недостатка точности произошла потеря седьмого знака.

В следующем примере, используя приведение типов, в массив действительных чисел A размером в 66 элементов складываются: действительное число в первый элемент массива; длинное целое во второй элемент массива и символьную строку в элементы с 3 по 66.

A[1] = 1.677722E+7

TLong(A[2]) = 16777216

TString(A[3]) = ‘Пример приведения типов’

Необходимо отметить, что элементы массива A, начиная со второго, после выполнения приведенного выше фрагмента программы не рекомендуется использовать как действительные числа, поскольку элемент A[2] содержит значение 2.350988Е-38, а элемент A[5] – значение -4.577438Е-18. Значение элементов, начиная с A[8] (символьная строка ‘Пример приведения типов’ содержит 23 символа и занимает 24 байта, то есть шесть элементов массива) вообще не зависят от приведенного фрагмента программы и содержат «мусор», который там находился ранее.

В списке типов определены только одномерные массивы. Однако, при необходимости, возможно использование двумерных массивов. Для этого в одномерный массив A необходимо поместить указатели на одномерные массивы. При этом I,J-й элемент двумерного массива записывается в виде:

TPRealArray(A[I])^[J]

В этом примере использована функция приведения типов TPRealArray, указывающая, что I-й элемент массива A нужно интерпретировать как указатель на одномерный массив действительных чисел, и операция «^» указывающая, что вместо указателя на массив TPRealArray(A[I]) используется массив, на который он указывает.

Таким образом, использование функций приведения типов позволяет из одномерных массивов строить структуры произвольной сложности. В языках программирования, таких как C и Паскаль, существует возможность строить пользовательские типы данных. При разработке стандарта эти возможности были исключены, поскольку использование пользовательских типов, облегчая написание программ, сильно затрудняет разработку компилятора или интерпретатора, а при использовании этого языка для описания компонентов нейрокомпьютера необходимость в пользовательских типах данных возникает чрезвычайно редко. Например, при описании примеров всех компонентов, приведенных в данной работе, такая необходимость ни разу не возникла.

4.3.6. Операции

В данном разделе приведены все операции, которые могут быть использованы при построении выражений различного типа. В табл. 5 приведены операции, которые допустимы в целочисленных выражениях (выражениях типа Integer или Long). В табл. 6 – список, дополняющий список операций из табл. 5 до полного списка операций, допустимых в выражениях действительного типа. В табл. 7 – операции, допустимые при построении логических выражений. В табл. 8 –для выражений типа символьная строка. В главе 1 в табл. 3 – для выражений типа Color. Если операндом может быть любой числовой тип, то вместо перечисления всех числовых типов (Integer, Real, Long) указывается слово «числовой»

Таблица 5

Операции, допустимые в целочисленных выражениях

Приоритет

Обозна-

чение

Тип 1-го

операнда

Тип 2-го

операнда

Тип

результата

Название операции

1

*

Integer

Integer

Integer

Умножение

1

*

Long

Integer

Long

Умножение

1

*

Integer

Long

Long

Умножение

1

*

Long

Long

Long

Умножение

1

Div

Integer

Integer

Integer

Целочисленное деление

1

Div

Integer

Long

Long

Целочисленное деление

1

Div

Long

Integer

Long

Целочисленное деление

1

Div

Long

Long

Long

Целочисленное деление

1

Mod

Integer

Integer

Integer

Остаток от деления

1

Mod

Long

Integer

Long

Остаток от деления

1

Mod

Integer

Long

Long

Остаток от деления

Таблица 5

Операции, допустимые в целочисленных выражениях (Продолжение)

Приоритет

Обозна-

чение

Тип 1-го

операнда

Тип 2-го

операнда

Тип

результата

Название операции

 

1

Mod

Long

Long

Long

Остаток от деления

 

2

+

Integer

Integer

Integer

Сложение

2

+

Integer

Long

Long

Сложение

2

Long

Integer

Long

Сложение

2

+

Long

Long

Long

Сложение

2

Integer

Integer

Integer

Вычитание

2

Integer

Long

Long

Вычитание

2

Long

Integer

Long

Вычитание

2

Integer

Long

Long

Вычитание

2

Long

Integer

Long

Вычитание

2

Long

Long

Long

Вычитание

3

And

Integer

Integer

Integer

Побитное И

3

And

Long

Long

Long

Побитное И

3

Or

Integer

Integer

Integer

Побитное включающее ИЛИ

3

Or

Long

Long

Long

Побитное включающее ИЛИ

3

Xor

Integer

Integer

Integer

Побитное исключающее ИЛИ

3

Xor

Long

Long

Long

Побитное исключающее ИЛИ

3

Not

Integer

Integer

Integer

Побитное отрицание

3

Not

Long

Long

Long

Побитное отрицание

Таблица 6

Операции, дополняющие список операций из табл. 5 до полного списка операций, допустимых в выражениях действительного типа.

Приоритет

Обозначение

Тип 1-го

операнда

Тип 2-го

операнда

Тип

Результата

Название операции

1

*

Real

числовой

Real

Умножение

1

/

числовой

числовой

Real

Деление

1

RMod

числовой

числовой

Real

Остаток от деления

2

+

Real

числовой

Real

Сложение

2

Real

числовой

Real

Вычитание

 

Таблица 7

Операции, допустимые при построении логических выражений

Прио-

ритет.

Обозна-

чение

Тип 1-го

операнда

Тип 2-го

операнда

Тип

результата

Название операции

1

числовой

числовой

Logic

Больше

1

числовой

числовой

Logic

Меньше

1

>=

числовой

числовой

Logic

Больше или равно

1

<=

числовой

числовой

Logic

Меньше или равно

1

=

числовой

числовой

Logic

Равно

1

<> 

числовой

числовой

Logic

Не равно

2

And

Logic

Logic

Logic

Логическое И

2

Or

Logic

Logic

Logic

Логическое включающее ИЛИ

2

Xor

Logic

Logic

Logic

Логическое исключающее ИЛИ

2

Not

Logic

Logic

Logic

Логическое отрицание

Таблица 8

Операции для выражений типа символьная строка

Прио-

ритет

Обозна-

чение

Тип 1-го

операнда

Тип 2-го

операнда

Тип

результата

Название операции

1

+

String

String

String

Конкатенация (сцепка) строк.

Во всех таблицах операции размещаются по убыванию приоритета. Для каждой операции указаны допустимые типы операндов, и тип результата, в зависимости от типов операндов.

В табл. 6 приводится необычная операция RMod – остаток от деления действительных чисел. Результат этой функции равен разности между первым операндом и вторым операндом, умноженным на целую часть отношения первого операнда ко второму.

Кроме операций, приведенных в табл. 3 главы 1 и табл. 5–8, определены две взаимно обратные операции для работы с адресами и указателями:

^ – ставится после переменной типа указатель. Означает, что вместо указателя в выражении используется переменная или массив, на который указывает этот указатель. Не допускается после переменных типа Pointer.

@ – ставится перед именем переменной любого типа. Означает, что в выражении участвует не переменная, а адрес переменной. Используется при присвоении адресов переменных или массивов переменным типа указатель.

4.3.7. Язык описания нейронных сетей

Язык описания нейронных сетей предназначен для хранения сетей на диске. Следует отметить, что в отличии от таких компонентов, как предобработчик входных сигналов, оценка или задачник описание даже простой сети имеет большой размер. С другой стороны, многие подсети являются стандартными для большинства сетей. Для компонента сеть нет смысла вводить небольшой набор стандартных элементов и подсетей, поскольку этот набор может легко расширяться. Более эффективным является выделение часто употребляемых подсетей в отдельные библиотеки, подключаемые к описаниям конкретных сетей. В приведенных в этой главе примерах описания нейронных сетей выделен ряд библиотек.

4.3.7.1. Ключевые слова языка

В табл. 9 приведен список ключевых слов языка описания нейронных сетей. Кроме того, к ключевым словам относятся типы данных, приведенные в табл. 1 главы 1; обозначения операций, приведенные в табл. 3 главы 1, 5, 6, 7, 8; названия функций преобразования (табл. 3) и приведения типов (табл. 4); идентификаторы предопределенных констант, приведенные в табл. 4 главы 1; имена элементарных функций, приведенных в табл. 10 и обозначения функций управления памятью из раздела «функции управления памятью».


Таблица 9.

Ключевые слова языка описания нейронных сетей.

Ключевое слово

Краткое описание

Back

Метод, осуществляющий обратное функционирование подсети. Префикс сигналов обратного функционирования.

Begin

Начало описания тела процедуры, или операторных скобок.

Block

Тип аргумента подсети. Означает, что аргумент является подсетью.

By

Часть оператора цикла с шагом. Предшествует шагу цикла.

Cascad

Тип подсети – каскад.

Connections

Начало блока описания связей подсети.

Contents

Начало блока описания состава подсети.

DefaultType

Тип параметров по умолчанию.

Do

Завершающая часть операторов цикла.

Element

Тип подсети – элемент.

Else

Часть условного оператора. Предшествует оператору, выполняемому, если условие ложно.

End

Конец описания тела процедуры или операторных скобок.

For

Заголовок оператора цикла с шагом.

Forw

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

Function

Заголовок описания функции.

Global

Начло блока описания глобальных переменных.

GoTo

Начало оператора перехода.

If

Начало условного оператора.

Include

Предшествует имени файла, целиком вставляемого в это место описания.

InSignalMask

Имя, по которому адресуются маски обучаемости входных сигналов подсети.

InSignals

Имя, по которому адресуются входные сигналы подсети; начало блока описания входных сигналов.

Таблица 9.

Ключевые слова языка описания нейронных сетей (Продолжение)

Ключевое слово

Краткое описание

Label

Начало описания меток

Layer

Тип подсети – слой.

Loop

Тип подсети – цикл, выполняемый указанное число раз.

MainNet

Начало описания главной сети

Name

Предшествует имени статической переменной.

NetLib

Начало описания библиотеки подсетей.

NetWork

Начало описания сети

NumberOf

Функция (запрос). Возвращает число параметров или сигналов в подсети.

OutSignals

Имя, по которому адресуются выходные сигналы подсети; начало блока описания выходных сигналов.

ParamDef

Заголовок определения типа параметров.

Parameters

Имя, по которому адресуются параметры подсети; начало блока описания параметров.

ParamMask

Имя, по которому адресуются маски обучаемости параметров подсети.

ParamType

Заголовок описания типа параметров.

SetParameters

Признак раздела установления значений параметров.

Static

Начло блока описания статических переменных.

Then

Часть условного оператора, предшествующая оператору, выполняемому, если условие истинно.

To

Часть оператора цикла с шагом. Предшествует верхней границе цикла.

Var

Начло блока описания переменных.

While

Заголовок оператора цикла по условию.

Until

Тип подсети – цикл, выполняемый до тех пор пока не выполнится условие.

Used

Начало списка подключаемых библиотек подсетей

Таблица 10

Элементарные функции, допустимые в языке описания нейронных сетей

Имя

Значение

Имя

Значение

Sin

Синус

Cos

Косинус

Tan

Тангенс

Atan

Арктангенс

Sh

Гиперболический синус

Ch

Гиперболический косинус

Th

Гиперболический тангенс

Lg

Логарифм двоичный

Ln

Exp

Экспонента

Sqrt

Квадратный корень

Sqr

Квадрат

Abs

Абсолюеное значение

Sign

Знак аргумента (0 – минус)

4.3.7.2. Передача аргументов функциям

Во всех языках описания компонентов все параметры передаются по ссылке (передается не значение аргумента, а его адрес). Если в качестве фактического аргумента указано выражение, то значение выражения помещается интерпретатором (или компилятором) во временную переменную, имеющую тип, совпадающий с типом формального аргумента, а адрес временной переменной передается в качестве фактического аргумента.

4.3.7.3. Имена структурных единиц

Компонент нейронная сеть имеет иерархическую структуру. Часть запросов может быть адресована не всему компоненту, а его структурной единице любого уровня. Для точного указания адресата запроса используется полное имя структурной единицы, которое строится по следующему правилу:

1. Имя компонента является полным именем компонента.

2. Полное имя младшей структурной единицы строится путем добавления справа к имени старшей структурной единицы точки, псевдонима младшей структурной единицы и номера экземпляра младшей структурной единицы, если младших структурных единиц с таким псевдонимом несколько.

Иногда при построении описания компонента требуется однозначное имя структурной единицы. В качестве однозначного имени можно использовать полное имя, но такой подход лишает возможности вставлять подготовленные структурные единицы в структуры более высокого уровня. Для этого вводится понятие однозначного имени структурной единицы: в описании структурной единицы A однозначным именем структурной единицы B, являющейся частью структурной единицы A, является полное имя структурной единицы B, из которого исключено полное имя структурной единицы A.

4.3.7.4. Способ описания синтаксических конструкций

Для описания синтаксиса языков описаний компонентов используется расширенная Бэкусова нормальная форма. Описание синтаксиса языка с помощью БНФ состоит в расшифровке понятий от более сложных к более простым. Каждое предложение БНФ состоит из двух частей, разделенных символами «::=» (два двоеточия, за которыми следует знак равенства). Наиболее подходящим названием для этого разделителя является слово «является» в отличие от «равно» или «присвоить» в языках программирования. Слева от разделителя находится объясняемое понятие, справа – конструкция разъясняющая это понятие. Например, предложение

<Имя переменной> ::= <Идентификатор>

означает, что объясняемое понятие – <Имя переменной> является идентификатором. Заметим, что порядок предложений в БНФ описания синтаксиса языка не имеет значения. Однако традиционно сложилось так, что БНФ начинают с наиболее сложных понятий.

При описании синтаксиса языка с помощью БНФ используются следующие понятия и обозначения.

Нетерминальным символом называется понятие, которое должно быть раскрыто в пределах данной БНФ. Нетерминальным символом является произвольный набор символов, заключенный в угловые скобки, например <Имя>. Нетерминальный символ раскрыт, если в пределах БНФ встретилось предложение, в котором этот нетерминальный символ стоит в левой части.

Терминальным символом называется понятие, которое не требует раскрытия. Примерами терминальных символов являются буквы, цифры и ключевые слова описываемого языка. Терминальные символы не заключаются в угловые скобки и набраны курсивом, например Имя.

Подмножеством терминальных символов является набор ключевых слов языка. Для удобства ключевые слова набраны полужирным шрифтом, например, Имя.

В прямых квадратных скобках приводятся необязательные части синтаксических конструкций. Например предложение

<Целое число> ::= [–] <Положительное целое число>

означает, что целым числом является положительное целое число (знак минус, стоящий в квадратных скобках, опущен как необязательный) или положительное целое число, перед которым стоит знак минус (знак минус, стоящий в квадратных скобках, задействован). Отметим, что квадратные скобки, набранные курсивом, являются терминальными символами.

Набор из нескольких синтаксических конструкций, разделенных символом «½» и заключенных в прямые фигурные скобки задают конструкцию выбора одной и только одной из перечисленных в фигурных скобках конструкций. Например, предложение

<Буква> ::= { A ½ B ½ C ½ D ½ E ½ F ½ G ½ H ½ I ½ J ½ K ½ L ½ M ½ N ½ O ½ P ½

   Q ½ R ½ S ½ T ½ U ½ V ½ W ½ X ½ Y ½ Z}

означает, что понятие буква является одной из заглавных букв латинского алфавита. Отметим, что фигурные скобки, набранные курсивом, являются терминальными символами.

В целях сокращения описания в тех случаях, когда БНФ описание понятия сложно, а неформальное описание просто и однозначно, в БНФ описание включаются фрагменты неформального описания таких понятий.

Кроме того в данную модификацию БНФ включены нетерминальные символы с параметрами. В теле нетерминального символа параметры набраны полужирным курсивом. В качестве примера приведем набор предложений, описывающих формальные аргументы:

<Список формальных аргументов> ::= <Формальный аргумент> [; <Список формальных аргументов>]

<Формальный аргумент> ::= <Список имен аргументов> : <Скалярный тип>

<Список имен аргументов> ::= <Имя аргумента> [,<Список имен аргументов>]

<Имя аргумента> ::= <Идентификатор>

<Аргумент типа Тип> – одно из следующих понятий:

имя аргумента, который при описании формальных аргументов имел тип Тип

имя элемента аргумента-массива, если элементы массива имеют тип Тип

результат приведения произвольного аргумента или элемента аргумента-массива к типу Тип.

В этом фрагменте содержится предложение, раскрывающее понятие <Аргумент типа Тип>, являющееся нетерминальным символом с параметром. Из последнего предложения легко понять, что представляет собой понятие <Аргумент типа Тип>. Для описания этого понятия в соответствии с требованиями стандартной БНФ пришлось бы описывать отдельно следующие понятия: <Аргумент типа Long>, <Аргумент типа Real>, <Аргумент типа Integer>, <Аргумент типа Color>, <Аргумент типа Logic>, <Аргумент типа String>, <Аргумент типа PRealArray>, <Аргумент типа PIntegerArray>, <Аргумент типа PLongArray>, <Аргумент типа PLogicArray>, <Аргумент типа PString>, <Аргумент типа Visual>, <Аргумент типа Pointer>, <Аргумент типа FuncType>. Кроме того, пришлось бы отказаться от простой и понятной конструкции описания формальных аргументов. Ниже приведена часть конструкции описания формальных аргументов, которую пришлось бы включить в БНФ. В данном фрагменте приведена расшифровка только одного понятия – <Аргумент типа Long>. Остальные нераскрытые понятия описываются аналогично. Понятия <Идентификатор> и <Номер элемента> считаются раскрытыми ранее.

<Список формальных аргументов> ::= <Формальный аргумент> [; <Список формальных аргументов>]

<Формальный аргумент> ::= {<Формальный аргумент типа Long> ½ <Формальный аргумент типа Real> ½ <Формальный аргумент типа Integer> ½ <Формальный аргумент типа Color> ½ <Формальный аргумент типа Logic> ½ <Формальный аргумент типа String> ½ <Формальный аргумент типа PRealArray> ½ <Формальный аргумент типа PIntegerArray> ½ <Формальный аргумент типа PLongArray> ½ <Формальный аргумент типа PLogicArray> ½ <Формальный аргумент типа PString> ½ <Формальный аргумент типа Visual> ½ <Формальный аргумент типа Pointer> ½ <Формальный аргумент типа FuncType>}

<Формальный аргумент типа Long> ::= <Список имен аргументов типа Long> : Long;

<Список имен аргументов типа Long> ::= <Имя аргумента типа Long> [,<Список имен аргументов типа Long>]

<Имя аргумента типа Long> ::= <Идентификатор>

<Аргумент типа Long> ::= {<Имя аргумента типа Long> ½ <Имя аргумента типа PLongArray>^[<Номер элемента>] ½ TLong(<Имя произвольного аргумента>)}

<Имя произвольного аргумента> ::= <Имя аргумента типа Long>, <Имя аргумента типа Real>, <Имя аргумента типа Integer>, <Имя аргумента типа Color>, <Имя аргумента типа Logic>, <Имя аргумента типа String>, <Имя аргумента типа PRealArray>, <Имя аргумента типа PIntegerArray>, <Имя аргумента типа PLongArray>, <Имя аргумента типа PLogicArray>, <Имя аргумента типа PString>, <Имя аргумента типа Visual>, <Имя аргумента типа Pointer>, <Имя аргумента типа FuncType>

Третье четвертое и пятое предложения данного фрагмента пришлось бы повторить для каждого из остальных тринадцати типов аргументов. Поскольку приведенные в книге БНФ описания языков призваны задать и объяснить синтаксис языка, а не служить исходным кодом компилятора компиляторов, автор счел возможным отступить от канонов БНФ, тем более, что для профессионала в области языков программирования не составит большого труда заменить неформальные конструкции на точные формальные фрагменты.

4.3.7.5. Описание общих синтаксических конструкций

В данном разделе приведено описание общего подмножества языков описания компонентов. В некоторых случаях, когда БНФ описание понятия сложно, а неформальное описание просто и однозначно, в БНФ описание включаются фрагменты неформального описания таких понятий.

Список синтаксических конструкций общего назначения:

<Идентификатор> ::= <Буква> [<Символьная строка>]

<Буква> ::= {a ½ b ½ c ½ d ½ e ½ f ½ g ½ h ½ i ½ j ½ k ½ l ½ m ½ n ½ o ½ p ½ q ½ r ½ s ½ t ½ u ½ v ½ w ½ x ½ y ½ z ½ A ½ B ½ C ½ D ½ E ½ F ½ G ½ H ½ I ½ J ½ K ½ L ½ M ½ N ½ O ½ P ½ Q ½ R ½ S ½ T ½ U ½ V ½ W ½ X ½ Y ½ Z}

<Символьная строка> ::= {<Буква> ½ <Цифра> ½ _ } [<Символьная стока>]

<Цифра> ::= {0 ½ 1 ½ 2 ½ 3 ½ 4 ½ 5 ½ 6 ½ 7 ½ 8 ½ 9}

<Число> ::= {<Целое число> ½ <Действительное число>}

<Целое число> ::= [–] <Положительное целое число>

<Положительное целое число> ::= <Цифра> [<Положительное целое число>]

<Действительное число> ::= <Целое число>[.<Положительное целое число>] [e<Целое число>]

<Целочисленная константа> ::= {<Предопределенная константа типа Integer> ½ <Предопределенная константа типа Long> ½ <Целое число>}

<Цветовая константа> ::= H <Шестнадцатеричная цифра> <Шестнадцатеричная цифра> <Шестнадцатеричная цифра> <Шестнадцатеричная цифра>

<Шестнадцатеричная цифра> ::= {0 ½ 1 ½ 2 ½ 3 ½ 4 ½ 5 ½ 6 ½ 7 ½ 8 ½ 9 ½ A ½ B ½ C ½ D ½ E ½ F }

<Строковая константа> ::= “<Строка произвольных символов>”

<Логическая константа> ::= {True ½ False}

<Строка произвольных символов> – Последовательность произвольных символов из набора ANSI. В этой последовательности допускаются символы национальных алфавитов. При необходиости включить в эту конструкцию символ кавычек, он должен быть удвоен.

<Скалярный тип> ::= {Long ½ Real ½ Integer ½ Color ½ Logic ½ String ½ PRealArray ½ PIntegerArray ½ PLongArray ½ PLogicArray ½ PString ½ Visual ½ Pointer ½ FuncType}

<Тип массива> ::= { RealArray ½ IntegerArray ½ LongArray ½ LogicArray}

<Константа типа Тип> – константа имеющая тип Тип.

Список синтаксических конструкций для формальных аргументов:

<Список формальных аргументов> ::= <Формальный аргумент> [; <Список формальных аргументов>]

<Формальный аргумент> ::= <Список имен аргументов> : <Скалярный тип>

<Список имен аргументов> ::= <Имя аргумента> [,<Список имен аргументов>]

<Имя аргумента> ::= <Идентификатор>

<Аргумент типа Тип> – одно из следующих понятий:

имя аргумента, который при описании формальных аргументов имел тип Тип

имя элемента аргумента-массива, если элементы массива имеют тип Тип

результат приведения произвольного аргумента или элемента аргумента-массива к типу Тип.

Синтаксические конструкции описания переменных:

<Описание переменных> ::= Var <Список описаний однотипных переменных>

<Список описаний однотипных переменных> ::= <Тип переменной> <Список переменных>; [<Список описаний однотипных переменных>]

<Список переменных> ::= <Имя переменной> [, <Список переменных>]

<Имя переменной> ::= <Идентификатор>

<Тип переменной> ::= {<Скалярный тип> ½ <Тип массива>[<Целочисленное константное выражение>]}

<Переменная типа Тип> – одно из следующих понятий:

имя переменной, которая при описании переменных имела тип Тип

имя элемента массива, если элементы массива имеют тип Тип

результат приведения произвольной переменной или элемента массива к типу Тип.

Синтаксические конструкции описания статических переменных

Статические переменные, как правило, служат для описания параметров компонентов нейрокомпьютера. Использование в именах переменных только символов латинского алфавита и цифр делает идентификаторы универсальными, но неудобными для всех пользователей, кроме англо-говорящих. Для удобства всех остальных пользователей в описании статических переменных предусмотрена возможность использовать дополнительные имена для статических переменных. Однако эти имена служат только для построения интерфейса и не могут быть использованы в описании тела соответствующего компонента. Кроме того, статической переменной можно при описании задать значение по умолчанию.

<Описание статических переменных> ::= Static <Список описаний статических
переменных>

<Список описаний статических переменных> ::= <Описание статической переменной>; [<Список описаний статических переменных>]

<Описание статической переменной> ::= <Тип переменной> <Имя переменной> [Name <Имя статической переменной>] [Default <Значение по умолчанию>]

<Имя статической переменной> ::= <Строковая константа>

<Значение по умолчанию> ::= <Константное выражение типа <Тип переменной>>

Синтаксические конструкции описания функций

<Описание функций> ::= <Описание функции> [<Описание функций>]

<Описание функции> ::= <Заголовок функции> <Описание переменных> <Описание меток> <Тело функции>

<Заголовок функции> ::= Function <Имя функции>[(<Список формальных аргументов>)] : <Скалярный тип>;

<Описание меток> ::= Label <Список меток>;

<Список меток> ::= <Имя метки> [, <Список меток>]

<Имя метки> ::= <Идентификатор>

<Тело функции> ::= Begin <Составной оператор> End;

<Составной оператор> ::= [<Имя метки>:] <Оператор> [; <Составной оператор>]

<Оператор> ::= {<Оператор присваивания> ½ <Оператор ветвления> ½ <Оператор цикла> ½ <Оператор перехода> ½ <Операторные скобки>}

<Оператор присваивания> ::= <Допустимое имя переменной> = <Выражение>

<Оператор ветвления> ::= If <Логическое выражение> Then <Оператор> [Else <Оператор>]

<Оператор цикла> ::= { <Цикл For> ½ <Цикл While> }

<Цикл For> ::= For <Имя переменной> = <Целочисленное выражение> To <Целочисленное выражение> [By <Целочисленное выражение>] Do <Оператор>

<Цикл While> ::= While <Логическое выражение> Do <Оператор>

<Оператор перехода> ::= GoTo <Имя метки>

<Операторные скобки> ::= Begin <Составной оператор> End

<Функция типа Тип> – функция, возвращающая величину типа Тип.

<Допустимое имя переменной> – допустимой переменной являются все переменные, описанные в данной функции или в данном процедурном блоке, глобальные переменные данного компонента. Для возвращения значения функции, в левой части оператора присваивания должно стоять имя функции.

Синтаксические конструкции описания выражений:

<Выражение> ::= { <Выражение типа Long> ½ <Выражение типа Real> ½ <Выражение типа Integer> ½ <Выражение типа Color> ½ <Выражение типа Logic> ½ <Выражение типа String> ½ <Выражение типа Pointer>}

<Целочисленное выражение> ::= { <Выражение типа Long> ½ <Выражение типа Integer>}

<Выражение типа Тип> ::= [<Префиксная операция типа Тип>] <Операнд типа Тип> [<Операция типа Тип> <Операнд типа Тип>]

<Операция типа Long> ::= {+ ½ ½ * ½ Div ½ Mod ½ And ½ Or ½ Xor}

<Операция типа Real>::= {+ ½ ½ * ½ / ½ RMod }

<Операция типа Integer> ::= {+ ½ ½ * ½ Div ½ Mod ½ And ½ Or ½ Xor}

<Операция типа Color> ::= {COr ½ CAnd ½ CXor}

<Операция типа Logic> ::= {And ½ Or ½ Xor}

<Операция типа String> ::= +

<Префиксная операция типа Long> ::= { ½ Not }

<Префиксная операция типа Real>::=

<Префиксная операция типа Integer> ::= { ½ Not }

<Префиксная операция типа Color> ::= CNot

<Префиксная операция типа Logic> ::= Not

<Операнд типа Logic> ::= ::= {<Результат сравнения> ½ <Выражение типа Logic> ½ (<Выражение типа Logic>) ½ <Константа типа Logic> ½ <Переменная типа Logic> ½ <Аргумент типа Logic> ½ <Вызов функции типа Logic>}

<Результат сравнения типов Long, Integer, Real> ::= (<Выражение типа Long, Integer, Real> {> ½ < ½ >= ½ <= ½ = ½ <>} <Выражение типа Long, Integer, Real> )

<Результат сравнения типа Color> ::= (<Выражение типа Color> {CEqual ½ CIn ½ CInclude ½ CExclude ½ CIntersect} <Выражение типа Color> )

<Результат сравнения типа String> ::= (<Выражение типа String> {= ½ <>} <Выражение типа String> )

<Операнд типа Тип> ::= {<Выражение типа Тип> ½ (<Выражение типа Тип>) ½ <Константа типа Тип> ½ <Переменная типа Тип> ½ <Аргумент типа Тип> ½ <Вызов функции типа Тип>}

<Вызов функции типа Тип> ::= <Имя функции типа Тип> [(<Список фактических аргументов>)]

<Список фактических аргументов> ::= <Выражение> [,<Список фактических аргументов>]

<Константное выражение типа Тип> – <Выражение типа Тип> в операндах которого не могут фигурировать переменные и функции, описанные пользователем.

<Числовое выражение> ::= { <Выражение типа Long> ½ <Выражение типа Real> ½ <Выражение типа Integer>}

Синтаксические конструкции задания значений статическим переменным

Эта конструкция служит для задания значений параметрам (статическим переменным) компонентов. Для компонента сеть она может встречаться не только при описании главной сети, но и при описании любой составной подсети. В специальных выражениях типа Тип могут участвовать только стандартные функции и аргументы той структурной единицы, в которой находится блок задания значений статическим переменным. При этом специальное выражение, задающее значение параметра должно иметь тип, совместимый с типом статической переменной, которой присваивается это значение.

<Установление параметров Структурной единицы> ::= <Однозначное имя Структурной единицы> [[[<Переменная цикла>:] <Начальный номер> [..<Конечный номер> [:<Шаг>] ]]] SetParameters <Список значений параметров>

<Переменная цикла> ::= <Идентификатор>

<Начальный номер> ::= <Константное выражение типа Long>

<Конечный номер> ::= <Константное выражение типа Long>

<Шаг> ::= <Константное выражение типа Long>

<Список значений параметров> ::= <Значение параметра> [,<Список значений параметров>]

<Значение параметра> ::= <Специальное выражение типа Тип>

<Специальное выражение типа Тип> ::= [<Префиксная операция типа Тип>] <Специальный операнд типа Тип> [<Операция типа Тип> <Специальный операнд типа Тип>]

<Специальный операнд типа Тип > ::= {<Специальное выражение типа Тип > ½ <Константа типа Тип> ½ <Переменная цикла> ½ (<Специальное выражение типа Тип > ½ <Аргумент типа Тип> ½ <Вызов функции типа Тип>)}

Синтаксические конструкции описания распределения сигналов или параметров:

Данная конструкция имеет четыре аргумента, имеющих следующий смысл:

Данное – сигнал или параметр.

Объект – предобработчик, интерпретатор, оценка, сеть.

Подобъект – частный предобработчик, частный интерпретатор, частная оценка, подсеть.

<Идентификатор данных> – одно из ключевых слов Signals, Parameters, Data, InSignals, OutSignals.

<Описание распределения Данных, Объекта, Подобъекта, <Идентификатор данных>> ::= Connections <Описание групп соответствий Данных>

<Описание групп соответствий Данных> ::= <Описание группы соответствий Данных> [;<Описание групп соответствий Данных>]

<Описание группы соответствий Данных> ::= <Блок сигналов Подобъекта> <=> {<Блок сигналов Объекта> ½ <Блок сигналов Подобъекта>}

<Блок сигналов Подобъекта> ::= <Описатель сигналов Подобъекта> [;<Блок сигналов Подобъекта>]

<Описатель сигналов Подобъекта> ::= { For <Переменная цикла> = <Начальный номер> To <Конечный номер> [Step <Шаг>] Do <Блок сигналов Подобъекта> End ½ <Список Данных Подобъекта>}

<Переменная цикла> ::= <Идентификатор>

<Список Данных Подобъекта> ::= <Данное Подобъекта>[; <Список Данных Подобъекта>]

<Данное Подобъекта> ::= <Псевдоним>[[<Номер экземпляра>]].<Идентификатор данных> [[<Номер Данного>]]

<Номер экземпляра> ::= {<Специальное выражение типа Long> ½ [+:]<Начальный номер> [..<Конечный номер> [:<Шаг>]]}

<Номер Данного> {<Специальное выражение типа Long> ½ [+:]<Начальный номер> [..<Конечный номер> [:<Шаг>]]}

<Блок Данных Объекта> ::= <Описатель Данных Объекта> [; <Блок Данных Объекта>]

<Описатель Данных Объекта> ::= { For <Переменная цикла> = <Начальный номер> To <Конечный номер> [Step <Шаг>] Do <Блок Данных Объекта> End ½ <Список Данных Объекта> }

<Список Данных Объекта> ::= <Данное Объекта>[; <Список Данных Объекта>]

<Данное Объекта> ::= <Идентификатор данных> [[<Номер Данного>]]

4.3.7.6. Комментарии

Для понятности описаний компонентов в них необходимо включать комментарии. Комментарием является любая строка (или несколько строк) символов, заключенных в фигурные скобки. Комментарий может находиться в любом месте описания компонента. При интерпретации или компиляции описания комментарии игнорируются (исключаются из текста).

4.3.7.7. Область действия переменных

Все идентификаторы состоят из произвольных комбинаций латинских букв, цифр и подчерков. Первым символом имени обязательно является буква. Использование букв только латинского алфавита связано с тем, что коды, используемые большинством компьютеров, имеют одинаковую кодировку для букв латинского алфавита, тогда как для букв национальных алфавитов других стран кодировка различна не только от компьютера к компьютеру но и от одной операционной системы к другой.

Заглавные и прописные буквы не различаются ни в именах, ни в ключевых словах.

Все переменные (описанные в блоках Var и Static) являются локальными и доступны только в пределах той функции или процедурного блока, в котором они описаны. Статические переменные сохраняют свое значение между вызовами функций или процедурных блоков, тогда как переменные, описанные в блоках Var, не сохраняют.

Переменная Error является глобальной для всех компонентов. Глобальной является также переменная ErrorManager. Однако не рекомендуется использование этих переменных путем прямого обращения к ним. Для получения значения переменной Error служит запрос GetError, исполняемый макрокомпонентом нейрокомпьютер.

4.3.7.8. Основные операторы

Оператор присваивания состоит из двух частей, разделенных знаком “=“. В левой части оператора присваивания могут участвовать имена любых переменных. В выражении, стоящем в правой части оператора присваивания могут участвовать любые переменные, аргументы процедурного блока и константы. В случае несоответствия типа выражения в правой части и типа переменной в левой части оператора присваивания производится приведение типа. Все выражения вычисляются слева на право с учетом старшинства операций.

Оператор ветвления. Оператор ветвления состоит из трех частей, каждая из которых начинается соответствующим ключевым словом. Первая часть – условие, начинается с ключевого слова If и содержит логическое выражение. В зависимости от значения вычисленного логического выражения выполняется Then часть (истина) или Else часть (ложь). Третья (Else) часть оператора может быть опущена. Каждая из выполняемых частей состоит из ключевого слова и оператора. При необходимости выполнить несколько операторов, необходимо использовать операторные скобки Begin End.

Цикл For имеет следующий вид:

For Переменная_цикла = Начальное_значение To Конечное_значение [By Шаг] Do <Оператор>

Переменная цикла должна быть одного из целочисленных типов. В ходе выполнения оператора она пробегает значения от Начальное_значение до Конечное_значение с шагом Шаг. Если описание шага опущено, то шаг равен единице. При каждом значении переменной цикла из диапазона выполняется оператор, являющийся телом цикла. Если в теле цикла необходимо выполнить несколько операторов, то необходимо воспользоваться операторными скобками. Допускается любое число вложенных циклов. Выполнение цикла в зависимости от соотношения между значениями Начальное_значение, Конечное_значение и Шаг приведено в табл. 11.

Таблица 11.

Способ выполнения цикла в зависимости от значений параметров цикла.

Конечное значение

Шаг

Способ выполнения

>Начального значения

>0

Цикл выполняется пока переменная цикла

£ Конечного значения

<Начального значения

>0

Тело цикла не выполняется

=Начальному значению

¹0

Тело цикла выполняется один раз

>Начального значения

<0

Тело цикла не выполняется

<Начального значения

<0

Цикл выполняется пока переменная цикла

³ Конечного значения

 

=0

Тело цикла не выполняется

Цикл While. Тело цикла выполняется до тех пор, пока верно логическое выражение. Проверка истинности логического выражения производится перед выполнением тела цикла. Если тело цикла должно содержать более одного оператора, то необходимо использовать операторные скобки.

4.3.7.9. Описание распределения сигналов

Раздел описания распределения сигналов начинается с ключевого слова Connections. За ключевым словом Connections следует одна или несколько групп соответствий. Каждая группа соответствий состоит из правой и левой частей, разделенных символами «<=>» и описывает соответствие имен сигналов (параметров) различных структурных единиц. Каждая часть группы соответствий представляет собой список сигналов (параметров) или интервалов сигналов (параметров), разделенных между собой символом «;». Указанные в левой и правой частях сигналы (параметры) отождествляются. Если при указании сигнала (параметра) не указано имя подобъекта, то это сигнал (параметр) описываемого объекта. Использование интервала сигналов (параметров) в правой или левой части группы соответствий равносильно перечислению сигналов (параметров), с номерами, входящими в интервал, начиная с начального номера c шагом, указанным после символа «:». Если шаг не указан, то он полагается равным единице. Число сигналов в правой и левой частях группы соответствий должно совпадать. Если интервал пуст (например [2..1:1]), то описываемая им группа сигналов считается отсутствующей и пропускается. При использовании в описании соответствий явных циклов, во всех выражениях внутри цикла возможно использование переменной цикла. При этом подразумевается следующий порядок перечисления: Сначала изменяется номер в самом правом интервале, далее во втором справа, и т.д. В последнюю очередь изменяются значения переменных цикла явных циклов в порядке их вложенности (переменная самого внутреннего цикла меняется первой и т.д.). Рассмотрим следующий пример описания группы соответствий блока, содержащего две сети Net с 3 входами каждая. Ниже приведено две различных структуры связей по несколько эквивалентных вариантов описания.

Случай 1. Естественный порядок связей.

Вариант 1.

InSignals[1] <=> Net[1].InSignals[1]

InSignals[2] <=> Net[1].InSignals[2]

InSignals[3] <=> Net[1].InSignals[3]

InSignals[4] <=> Net[2].InSignals[1]

InSignals[5] <=> Net[2].InSignals[2]

InSignals[6] <=> Net[2].InSignals[3]

Вариант 2.

InSignals[1..6] <=> Net[1..2].InSignals[1..3]

Вариант 3.

InSignals[1]; InSignals[2]; InSignals[3]; InSignals[4]; InSignals[5];

InSignals[6] <=> For I=1 To 3 Do For J=1 To 2

Do Net[J].InSignals[I] End End

Случай 2. Другой порядок связей.

Вариант 1.

InSignals[1] <=> Net[2].InSignals[3]

InSignals[2] <=> Net[1].InSignals[3]

InSignals[3] <=> Net[2].InSignals[2]

InSignals[4] <=> Net[1].InSignals[2]

InSignals[5] <=> Net[2].InSignals[1]

InSignals[6] <=> Net[1].InSignals[1]

Вариант 2.

InSignals[1..6] <=> For I=3 To 1 Step -1 Do Net[2..1:-1].InSignals[I] End

Вариант 3.

InSignals[6..1:-2]; InSignals[5..1:-2]<=>

For I=1 To 3 Do For J=1 To 2 Do Net[J].InSignals[I] End End

4.3.7.10. Функции управления памятью

Для создания массивов и освобождения занимаемой ими памяти используются следующие функции:

Создание массива.

Function NewArray( Type : Integer; Size : Long ) : PRealArray;

Таблица 12.

Предопределенные константы типов элементов массивов

Иденти-

Фикатор

Значение

Описание

MRealArray

4

Размер элемента – 4 байта

MIntegerArray

2

Размер элемента – 2 байта

mLongArray

4

Размер элемента – 4 байта

mLogicArray

1

Размер элемента – 1 байт

Описание аргументов:

Type – задает размер элемента массива и является одной из предопределенных констант, приведенных в табл. 12.

Size – число элементов в массиве.

Описание исполнения.

1. Если аргумент Type не совпадает ни с одной из предопределенных констант, приведенных в табл. 12, то возвращается значение Null, исполнение функции завершается.

2. Создается массив, занимающий Size*Type+4 байта.

3. Адрес массива возвращается как результат.

Освобождение массива.

Function FreeArray( Type : Integer; Array : PRealArray ) : Logic;

Описание аргументов:

Type – задает размер элемента массива и является одной из предопределенных констант, приведенных в табл. 12.

Array – адрес массива. Память, занимаемая этим массивом, должна быть освобождена.

Описание исполнения.

1. Если аргумент Type не совпадает ни с одной из предопределенных констант, приведенных в табл. 12, то возвращается значение False, исполнение функции завершается.

2. Освобождается память размером TReal(Array[0])*Type+4 байта.

3. Аргументу Array присваивается значение Null

Пересоздание массива.

Function ReCreateArray( Type : Integer; Array : PRealArray; Size : Long ) : Logic;

Описание аргументов:

Type – задает размер элемента массива и является одной из предопределенных констант, приведенных в табл. 12.

Array – адрес массива.

Size – число элементов в массиве.

Описание исполнения.

1. Если аргумент Type не совпадает ни с одной из предопределенных констант, приведенных в табл. 12, то возвращается значение False, исполнение функции завершается.

2. Если аргумент Array не равен Null, и TReal(Array[0]) равен Size, то возвращается значение True, выполнение функции завершается.

3. Если аргумент Array не равен Null, и TReal(Array[0]) не равен Size, то освобождается память размером TReal(Array[0])*Type+4 байта. Аргументу Array присваивается значение Null

4. Аргументу Array присваивается значение NewArray(Type,Size), возвращается значение True, исполнение функции завершается.

4.3.7.11. БНФ языка описания сетей

В данном разделе приведена БНФ языка описания сетей.

<Описание библиотеки подсетей> ::= <Заголовок библиотеки> <Описание подсетей> <Конец описания библиотеки>

<Заголовок библиотеки> ::= NetLib <Имя библиотеки> [Used <Список имен библиотек>]

<Имя библиотеки> ::= <Идентификатор>

<Список имен библиотек> ::= <Имя используемой библиотеки> [,<Список имен библиотек>]

<Имя используемой библиотеки> ::= <Идентификатор>

<Описание подсетей> ::= <Описание подсети> [<Описание подсетей>]

<Описание подсети> ::= {<Описание элемента> ½ <Описание блока> ½ <Описание функций>}

<Описание элемента> ::= <Заголовок описания элемента> <Описание сигналов и параметров> [<Описание типов параметров>] [<Определение типов параметров>] [<Описание статических переменных>] [<Установление значений статических переменных>] <Описание методов> <Конец описания элемента>

<Заголовок описания элемента> ::= Element <Имя элемента> [(<Список формальных аргументов>)]

<Имя элемента> ::= <Идентификатор>

<Описание сигналов и параметров> ::= <Описание входных сигналов> <Описание выходных сигналов> [<Описание параметров>]

<Описание входных сигналов> ::= InSignals <Константное выражение типа Long>

<Описание выходных сигналов> ::= OutSignals <Константное выражение типа Long>

<Описание параметров> ::= Parameters <Константное выражение типа Long>

<Описание типов параметров> ::= <Описание типа параметров> [<Описание типов параметров>]

<Описание типа параметров> ::= ParamType <Имя типа параметра> <Список>

<Имя типа параметра> ::= <Идентификатор>

<Список> ::= {Parameters[<Начальный номер> [..<Конечный номер> [<Шаг>]]] ½ InSignals[<Начальный номер> [..<Конечный номер> [<Шаг>]]]} [;<Список>]

<Определение типов параметров> ::= <Определение типа параметра> [<Определение типов параметров>]

<Определение типа параметра> ::= ParamDef <Имя типа параметра> <Минимальное значение> <Максимальное значение>

<Минимальное значение> ::= <Константное выражение типа Real>

<Максимальное значение> ::= <Константное выражение типа Real>

<Установление значений статических переменных> ::= <Установление параметров Подсети> [;<Установление значений статических переменных>]

<Описание методов> ::= <Описание функционирования вперед> <Описание функционирования назад>

<Описание функционирования вперед> ::= Forw [<Описание переменных>] <Тело метода>

<Тело метода> ::= Begin <Составной оператор> End

<Описание функционирования назад> ::= Back [<Описание переменных>] <Тело метода>

<Конец описания элемента> ::= End <Имя элемента>

<Описание блока> ::= <Заголовок описания блока> <Описание состава> <Описание сигналов и параметров> [<Описание статических переменных>] [<Установление значений статических переменных>] <Описание связей> [<Определение типов параметров>] <Конец описания блока>

<Заголовок описания блока> ::= {<Описание каскада> ½ <Описание слоя> ½ <Описание цикла с фиксированным числом шагов> ½ <Описание цикла по условию>}

<Описание каскада> ::= Cascad <Имя блока> [(<Список формальных аргументов блока>)]

<Имя блока> ::= <Идентификатор>

<Список формальных аргументов блока> ::= {<Список формальных аргументов> ½ <Аргумент – подсеть>} [;<Список формальных аргументов блока>]

<Аргумент – подсеть>::= <Список имен аргументов – подсетей> : Block

<Список имен аргументов – подсетей> ::= <Имя аргумента – подсети> [,<Список имен аргументов – подсетей>]

<Имя аргумента – подсети> ::= <Идентификатор>

<Описание слоя> ::= Layer <Имя блока> [(<Список формальных аргументов блока>)]

<Описание цикла с фиксированным числом шагов> ::= Loop <Имя блока> [(<Список формальных аргументов блока>)] <Число повторов цикла>

<Число повторов цикла> ::= <Константное выражение типа Long>

<Описание цикла по условию> ::= Until <Имя блока> [(<Список формальных аргументов блока>)] : <Выражение типа Logic>

<Описание состава> ::= Contents <Список имен подсетей>

<Список имен подсетей> ::= <Имя подсети> [,<Список имен подсетей>]

<Имя подсети> ::= <Псевдоним>: {<Имя ранее описанной подсети> [(<Список фактических аргументов блока>)] [[<Число экземпляров>]] ½ <Имя аргумента – подсети> [[<Число экземпляров >]]}

<Псевдоним> ::= <Идентификатор>

<Число экземпляров > ::= <Константное выражение типа Long>

<Имя ранее описанной подсети> ::= <Идентификатор>

<Список фактических аргументов блока> ::= <Фактический аргумент блока> [,<Список фактических аргументов блока>]

<Фактический аргумент блока> ::= {<Фактический аргумент> ½ <Имя аргумента – подсети>}

<Описание связей> ::= {<Описание распределения Входных сигналов, Блока, Подсети, InSignals > ½ <Описание распределения Выходных сигналов, Блока, Подсети, OutSignals > ½ <Описание распределения Параметров, Блока, Подсети, Parameters >}

<Конец описания блока>::= End <Имя блока>

<Конец описания библиотеки> ::= End NetLib

<Описание сети> ::= <Заголовок описания сети> <Описание подсетей> <Описание главной сети> <Массивы параметров и масок сети> <Конец описания сети>

<Заголовок описания сети> ::= NetWork <Имя сети> [Used <Список имен библиотек>]

<Имя сети> ::= <Идентификатор>

<Описание главной сети> ::= MainNet <Имя ранее описанной подсети> [(<Список фактических аргументов блока>)]

<Массивы параметров и масок сети> ::= <Массив параметров> <Массив маски обучаемости параметров>

<Массив параметров> ::= Parameters <Значения параметров>;

<Значения параметров> ::= <Действительное число> [, <Значения параметров>]

<Массив маски обучаемости параметров> ::= ParamMask <Значения маски>;

<Значения маски> ::= <Константа типа Logic> [,<Значения маски>]

<Конец описания сети> ::= End NetWork

4.3.7.12. Описание языка описания сетей

В этом разделе приводится детальное описание языка описания сетей, дополняющее БНФ, приведенную в предыдущем разделе и описание общих конструкций, приведенное в разделе «Общий стандарт».

Описание и область действия переменных

Вспомогательные переменные могут потребоваться при описании прямого и обратного функционирования элементов. Переменная действует только в пределах той процедуры, в которой она описана. Кроме явно описанных переменных, в методе Forw доступны также сигналы прямого функционирования и параметры элемента, а в методе Back – входные и выходные сигналы прямого функционирования, выходные сигналы обратного функционирования, параметры элемента и градиент по параметрам элемента. Во всех методах доступны аргументы элемента.

Статические переменные, описываемые после ключевого слова Static, уникальны для каждого экземпляра элемента или блока, и доступны только в пределах элемента или блока. Эти переменные могут потребоваться для вычисления условий в цикле типа Until. Возможно использование таких переменных в элементах, например, для хранения предыдущего состояния элемента. Кроме того, в статической переменной можно хранить значения не обучаемых параметров.

Методы Forw и Back для блоков

Методы Forw и Back для блоков не описываются в языке описания сетей. Это связано с тем, что при выполнении метода Forw блоком происходит вызов метода Forw составляющих блок подсетей (для элементов – метода Forw) в порядке их описания в разделе описания состава блока. При выполнении метода Back происходит вызов методов Back составляющих блок подсетей в порядке обратном порядку их описания в разделе описания состава блока.

Описание элементов

Описание элемента состоит из следующих основных разделов: заголовка элемента, описания сигналов и параметров, описания статических переменных и описания методов. Заголовок элемента имеет следующий синтаксис:

Element Имя_Элемента (Аргументы элемента)

Аргументы элемента являются необязательной частью заголовка. В следующем разделе приведены описания нескольких элементов. Отметим, что сигмоидный элемент описан двумя способами: с принципиально не обучаемой (S_NotTrain) и с обучаемой (S_Train) характеристикой.

Раздел описания сигналов и параметров следует сразу после заголовка элемента и состоит из указания числа входных и выходных сигналов и числа параметров элемента. Если у элемента отсутствуют параметры, то указание числа параметров можно опустить. В следующем разделе приведены элементы как имеющие параметры (S_Train, Adaptiv_Sum, Square_Sum), так и элементы без параметров (Sum, S_NotTrain, Branch). Концом раздела описания сигналов и параметров служит одно из ключевых слов ParamType, ParamDef, Forw или Back.

Описание типов параметров является необязательной частью описания элемента и начинается с ключевого слова ParamType. Если раздел описания типов параметров отсутствует, то все параметры этого элемента считаются параметрами типа DefaultType. Если в сети должны присутствовать параметры разных типов (например с разными ограничениями на минимальное и максимальное значение) необходимо описать типы параметров. Концом этого раздела служит одно из ключевых слов ParamDef, Forw или Back.

Раздел описания методов состоит из описания двух методов: Forw и Back. Описание метода состоит из заголовка, раздела описания переменных и тела метода. Заголовок имеет вид ключевого слова Forw или Back для соответствующего метода. Раздел описания переменных состоит из ключевого слова Var, за которым следуют описания однотипных переменных, каждое из которых заканчивается символом «;». Необходимо понимать, что описание заголовков методов это не описание заголовка (прототипа) функции, выполняющей тело метода. Ниже приведен синтаксис заголовков методов Forw и Back на момент вызова:

Pascal:

Procedure Forw( InSignals, OutSignals, Parameters : PRealArray);

Procedure Back(InSignals, OutSignals, Parameters, Back.InSignals,

Back.OutSignals, Back.Parameters : PRealArray);

C

void Forw(PRealArray InSignals, PRealArray OutSignals, PRealArray Parameters)

void Back(PRealArray InSignals, PRealArray OutSignals, PRealArray Parameters,

PRealArray Back.InSignals, PRealArray Back.OutSignals, PRealArray

Back.Parameters)

В методе Forw в левой части оператора присваивания могут фигурировать имена любых переменных и элементов предопределенного массива выходных сигналов (OutSignals). В выражении, стоящем в правой части оператора присваивания могут участвовать любые переменные, аргументы элемента и элементы предопределенных массивов входных сигналов (InSignals) и параметров (Parameters).

В методе Back в левой части оператора присваивания могут фигурировать имена любых переменных, элементов предопределенных массивов входных сигналов обратного функционирования (Back.InSignals) и параметров (Back.Parameters). В выражении, стоящем в правой части оператора присваивания, могут участвовать любые переменные, аргументы элемента и элементы предопределенных массивов входных (InSignals) и выходных (OutSignals) сигналов и параметров (Parameters).Отметим важную особенность вычисления поправок к параметрам. Поскольку один и тот же параметр может использоваться несколькими элементами, при вычислении поправки к параметру вычисленное значение нужно не присваивать соответствующему элементу массива Back.Parameters, а добавлять. При этом в теле метода элементы массива Back.Parameters не могут фигурировать в правой части оператора присваивания. Эта особенность вычисления поправок к параметрам обрабатывается компонентом сеть.

Описание элемента завершается ключевым словом End за которым следует имя элемента.

Пример описания элементов

NetBibl Elements;                                      {Библиотека элементов}

Element Synaps                                                  {Обычный синапс}

         InSignals 1                                                         {Один входной сигнал}

         OutSignals 1                                                      {Один выходной сигнал}

         Parameters 1                                                     {Один параметр – вес связи}

         Forw                                                                            {Начало описания прямого функционирования}

         Begin

{Выходной сигнал – произведение входного сигнала на параметр}

                   OutSignals[1] = InSignals[1] * Parameters[1]

         End                                                                                       {Конец описания прямого функционирования}

         Back                                                                            {Начало описания обратного функционирования }

         Begin

{Поправка к входному сигналу – произведение поправки к выходному сигналу на параметр}

                   Back.InSignals[1] = Back.OutSignals[1] * Parameters[1];

{Поправка к параметру – сумма ранее вычисленной поправки к параметру на произведение поправки к обратному сигналу на входной сигнал}

                   Back.Parameters[1] = Back.Parameters[1] + Back.OutSignals[1] *

 InSignals[1]

         End                                                                                       {Конец описания обратного функционирования}

End Synaps                                                                           {Конец описания синапса}

Element Branch(N : Long)               {Точка ветвления на N выходных сигналов}

         InSignals 1                                                         {Один входной сигнал}

         OutSignals N                                                      {N выходных сигналов}

         Forw                                                                            {Начало описания прямого функционирования}

                   Var Long I;                                                        {I – длинное целое – индекс}

         Begin

                   For I=1 To N Do                             {На каждый из N выходных сигналов передаем }

                            OutSignals[I] = InSignals[1]                              {входной сигнал}

         End                                                                                       {Конец описания прямого функционирования}

         Back                                                                            {Начало описания обратного функционирования }

                   Var                                                                              {Описание локальных переменных}

                            Long I;                                                      {I – длинное целое – индекс}

                            Real R;                                                      {R – действительное – для накопления суммы}

         Begin

                   R = 0;

                   For I=1 To N Do                             {Поправка ко входному сигналу равна сумме }

                            R = R + Back.OutSignals[I];                             {поправок выходных сигналов}

                   Back. InSignals[1] = R

         End                                                                                       {Конец описания обратного функционирования}

End Branch                                                                  {Конец описания точки ветвления}

Element Sum(N Long)                     {Простой сумматор на N входов}

         InSignals N                                                                  {N входных сигналов}

         OutSignals 1                                                      {Один выходной сигнал}

         Forw                                                                            {Начало описания прямого функционирования}

                   Var                                                                              {Описание локальных переменных}

                            Long I;                                                      {I – длинное целое – индекс}

                            Real R;                                                      {R – действительное – для накопления суммы}

         Begin

                   R = 0;

                   For I=1 To N Do                             {Выходной сигнал равен сумме входных}

                            R = R + InSignals[I];

                   OutSignals[1] = R

         End                                                                                       {Конец описания прямого функционирования}

         Back                                                                            {Начало описания обратного функционирования}

                   Var Long I;                                               {I – длинное целое – индекс}

         Begin

                   For I=1 To N Do                             {Поправка к каждому входному сигналу равна }

                            Back.InSignals[I] = Back.OutSignals[1] { поправке выходного сигнала}

         End                                                                                       {Конец описания обратного функционирования}

End Sum                                                                                {Конец описания простого сумматора}

Element Mul                                                                {Умножитель}

         InSignals 2                                                         {Два входных сигнала}

         OutSignals 1                                                      {Один выходной сигнал}

         Forw                                                                            {Начало описания прямого функционирования }

         Begin

                                                                  {Выходной сигнал равен произведению входных сигналов}

                   OutSignals[1] = InSignals[1] * InSignals[2]

         End                                                                                       {Конец описания прямого функционирования}

         Back                                                                            {Начало описания обратного функционирования }

         Begin

{Поправка к каждому входному сигналу равна произведению поправки выходного сигнала на другой входной сигнал}

                   Back.InSignals[1] = Back.OutSignals[1] * InSignals[2];

                   Back.InSignals[2] = Back.OutSignals[1] * InSignals[1]

         End                                                                              {Конец описания обратного функционирования}

End Mul                                                                       {Конец описания умножителя}

Element S_Train                                       {Обучаемый гиперболический сигмоидный элемент}

         InSignals 1                                                {Один входной сигнал}

         OutSignals 1                                             {Один выходной сигнал}

         Parameters 1                                            {Один параметр – характеристика}

         Forw                                                                  {Начало описания прямого функционирования}

         Begin

{Выходной сигнал равен отношению входного сигнала к сумме параметра и абсолютной величины входного сигнала}

                   OutSignals[1] = InSignals[1] / (Parameters[1] + Abs(InSignals[1])

         End                                                                                       {Конец описания прямого функционирования}

         Back                                                                            {Начало описания обратного функционирования}

                   Var Real R;                                               {R – действительное}

         Begin

{R – вспомогательная величина для вычисления поправок, равная отношению поправки выходного сигнала к квадрату суммы параметра и абсолютной величины входного сигнала}

                   R = Back.OutSignals[1] / Sqr(Parameters[1] + Abs(InSignals[1]);

{Поправка к входному сигналу равна произведению вспомогательной величины на параметр}

                   Back.InSignals[1] = R * Parameters[1];

{Поправка к параметру равна сумме ранее вычисленной величины поправки и произведения вспомогательной величины на входной сигнал}

                   Back.Parameters[1] = Back.Parameters[1] + R * InSignals[1]

         End                                                                                       {Конец описания обратного функционирования}

End S_Train                                                                 {Конец описания обучаемого гиперболического

                                                                                                                          сигмоидного элемента}

{Не обучаемый гиперболический сигмоидный элемент Char – характеристика}

Element S_NotTrain( Char : Real)

         InSignals 1                                                         {Один входной сигнал}

         OutSignals 1                                                      {Один выходной сигнал}

         Forw                                                                            {Начало описания прямого функционирования}

         Begin

{Выходной сигнал равен отношению входного сигнала к сумме характеристики и абсолютной величины входного сигнала}

                   OutSignals[1] = InSignals[1] / (Char + Abs(InSignals[1])

         End                                                                                        {Конец описания прямого функционирования}

         Back                                                                            {Начало описания обратного функционирования}

         Begin

{Поправка к входному сигналу равна отношению произведения поправки выходного сигнала на характеристику к квадрату суммы характеристики и абсолютной величины входного сигнала}

                   Back.InSignals[1] = Back.OutSignals[1] * Char /

                                                                                              Sqr(Char + Abs(InSignals[1]);

         End                                                                              {Конец описания обратного функционирования}

End S_NotTrain            {Конец описания гиперболического сигмоидного элемента}

Element Pade(Char : Real)     {Паде преобразователь Char  – характеристика}

         InSignals 2                                                {Два входных сигнала}

         OutSignals 1                                             {Один выходной сигнал}

         Forw                                                                  {Начало описания прямого функционирования}

         Begin

{Выходной сигнал равен отношению первого входного сигнала к сумме характеристики и второго входного сигнала}

                   OutSignals[1] = InSignals[1] / (Char+ InSignals[2])

         End                                                                              {Конец описания прямого функционирования}

         Back                                                                   {Начало описания обратного функционирования}

                   Var Real R;                                     {R – действительное}

         Begin

{Вспомогательная величина равна поправке к первому входному сигналу – отношению поправки выходного сигнала к сумме характеристики и второго входного сигнала}

                   R = Back.OutSignals[1] / (Char + InSignals[2]);

                   Back.InSignals[1] = R;

{Поправка ко второму входному сигналу равна минус отношению произведения первого входного сигнала на поправку выходного сигнала к квадрату суммы характеристики и второго входного сигнала}

                   Back.InSignals[2] =  -R * OutSignals[1];

         End                                                                              {Конец описания обратного функционирования}

End Pade                                                                      {Конец описания Паде преобразователя}

Element Sign_Mirror                        {Зеркальный пороговый элемент}

         InSignals 1                                                {Один входной сигнал}

         OutSignals 1                                             {Один выходной сигнал}

         Forw                                                                  {Начало описания прямого функционирования }

         Begin

{Выходной сигнал равен 1, если входной сигнал больше нуля, и нулю в противном случае }

                   If InSignals[1] > 0 Then OutSignals[1] = 1

                                                                                              Else OutSignals[1] = 0

         End                                                                              {Конец описания прямого функционирования}

         Back                                                                   {Начало описания обратного функционирования}

         Begin

{Поправка к входному сигналу равна выходному сигналу}

                   Back.InSignals[1] = OutSignals[1];

         End                                                                              {Конец описания обратного функционирования}

End Sign_Mirror                                        {Конец описания зеркального порогового элемента}

Element Sign_ Easy                         {Прозрачный  пороговый элемент}

         InSignals 1                                                {Один входной сигнал}

         OutSignals 1                                             {Один выходной сигнал}

         Forw                                                                  {Начало описания прямого функционирования }

         Begin

{Выходной сигнал равен 1, если входной сигнал больше нуля, и нулю в противном случае }

                   If InSignals[1] > 0 Then OutSignals[1] = 1

                                                                                      Else OutSignals[1] = 0

         End                                                                              {Конец описания прямого функционирования}

         Back                                                                   {Начало описания обратного функционирования}

         Begin

                                      {Поправка к входному сигналу равна поправке к выходному сигналу}

                   Back.InSignals[1] = Back.OutSignals[1];

         End                                                                              {Конец описания обратного функционирования}

End Sign_Easy                                          {Конец описания прозрачного порогового элемента}

Element Adaptiv_Sum( N : Long)              {Адаптивный сумматор на N входов}

         InSignals N                                                        {N входных сигналов}

         OutSignals 1                                             {Один выходной сигнал}

         Parameters N                                           {N параметров – весов связей}

         Forw                                                                  {Начало описания прямого функционирования}

                   Var                                                                     {Описание локальных переменных}

                            Long I;                                             {I – длинное целое – индекс}

                            Real R;                                            {R – действительное – для накопления суммы}

         Begin

                   R = 0;                                                                  {Выходной сигнал равен скалярному }

                   For I=1 To N Do                    {произведению массива входных сигналов}

                            R = R + InSignals[I] * Parameters[I];      {на массив параметров}

                   OutSignals[1] = R

         End                                                                              {Конец описания обратного функционирования}

         Back                                                                   {Начало описания обратного функционирования}

                   Var Long I;                                      {I – длинное целое – индекс}

         Begin

                   For I=1 To N Do Begin

{Поправка к I-у входному сигналу равна сумме ранее вычисленной поправки и произведения поправки выходного сигнала на I-й параметр}

                            Back.InSignals[I] = Back.OutSignals[1] * Parameters[I];

{Поправка к I-у параметру равна произведению поправки выходного сигнала на I-й входной сигнал}

                            Back. Parameters[I] = Back. Parameters[I] +

                                                                                                       Back.OutSignals[1] * InSignals[I]

                   End

         End                                                                              {Конец описания обратного функционирования}

End Adaptiv_Sum                                      {Конец описания адаптивного сумматора}

{Адаптивный неоднородный сумматор на N входов}

Element Adaptiv_Sum_Plus ( N : Long)

         InSignals N                                                        {N входных сигналов}

         OutSignals 1                                             {Один выходной сигнал}

         Parameters N+1                              {N+1 параметр – веса связей}

         Forw                                                                  {Начало описания прямого функционирования}

                   Var                                                                     {Описание локальных переменных}

                            Long I;                                             {I – длинное целое – индекс}

                            Real R;                                            {R – действительное – для накопления суммы}

         Begin

                   R = Parameters[N+1];  {Выходной сигнал равен сумме N+1 параметра}

                   For I=1 To N Do                             {и скалярного произведения массива входных}

                            R = R + InSignals[I] * Parameters[I];      {сигналов на массив параметров}

                   OutSignals[1] = R

         End                                                                              {Конец описания прямого функционирования}

         Back                                                                   {Начало описания обратного функционирования }

                   Var Long I;                                      {I – длинное целое – индекс }

         Begin

                   For I=1 To N Do Begin

{Поправка к I-у входному сигналу равна произведению поправки выходного сигнала на I-й параметр}

                            Back.InSignals[I] = Back.OutSignals[1] * Parameters[I];

{Поправка к I-у параметру равна сумме ранее вычисленной поправки и произведения поправки выходного сигнала на I-й входной сигнал}

                            Back. Parameters[I] = Back. Parameters[I] + Back.OutSignals[1] *

                                                                                                                          InSignals[I]

                   End;

{Поправка к (N+1)-у параметру равна сумме ранее вычисленной поправки и попраки к выходному сигналу}

                   Back.Parameters[N+1] = Back.Parameters[N+1] + Back.OutSignals[1]

         End                                                                              {Конец описания обратного функционирования}

End Adaptiv_Sum_Plus

{Конец описания неоднородного адаптивного сумматора}

Element Square_Sum( N : Long)      {Квадратичный сумматор на N входов}

         InSignals N                                                        {N входных сигналов}

         OutSignals 1                                             {Один выходной сигнал}

         Parameters (Sqr(N) + N) Div 2                {N(N+1)/2 параметров – весов связей}

         Forw                                                                  {Начало описания прямого функционирования}

                   Var                                                                     {Описание локальных переменных}

                            Long I,J,K;                             {I,J,K – переменные типа длинное целое }

                            Real R;                                            {R – действительное – для накопления суммы}

         Begin

                   K = 1;                                                                  {K – номер обрабатываемого параметра}

                   R = 0;

                   For I = 1 To N Do                  {I,J – номера входных сигналов}

                            For J = I To N Do Begin

                                      R = R + InSignals[I] * InSignals[J] * Parameters[K];

                                      K = K + 1

                            End;

{Выходной сигнал равен сумме всех попарных произведений входных сигналов, умноженных на соответствующие параметры}

                   OutSignals[1] = R

         End                                                                              {Конец описания прямого функционирования}

         Back                                                                   {Начало описания обратного функционирования }

                   Var                                                                     {Описание локальных переменных}

                            Long I, J, K;                           {I,J,K – переменные типа длинное целое }

                            Real R;                                            {R – действительное}

                            Vector W;                              {Массив для накопления промежуточных величин}

         Begin

                   For I = 1 To N Do

                            W[I] = 0;

                   K = 1;                                                                  {K – номер обрабатываемого параметра}

                   For I = 1 To N Do

                            For J = I To N Do Begin

{Поправка к параметру равна сумме ранее вычисленной поправки и произведения поправки к входному сигналу на произведение сигналов, прошедших через этот параметр при прямом функционировании}

                                      Back.Parameters[K] = Back.Parameters[K] +

                                               Back.OutSignals[1] * InSignals[I] * InSignals[J];

                                      R = Back.OutSignals[1] * Parameters[K];

                                      W[I] = W[I] + R * InSignals[J];

                                      W[J] = W[J] + R * InSignals[I];

                                      K = K + 1

                            End;

                   For I = 1 To N Do

{Поправка к входному сигналу равна произведению поправки к выходному сигналу на сумму всех параметров, через которые этот сигнал проходил при прямом функционировании, умноженных на другие входные сигналы, так же прошедшие через эти параметры при прямом функционировании}

                            Back.InSignals[1] = W[I]

         End                                                                              {Конец описания прямого функционирования}

End Square_Sum                              {Конец описания квадратичного сумматора}

{Неоднородный квадратичный сумматор на N входов}

Element Square_Sum_Plus( N : Long)      

         InSignals N                                                        {N входных сигналов}

         OutSignals 1                                             {Один выходной сигнал}

         Parameters (Sqr(N) + 3 * N) Div 2 + 1              {N(N+3)/2+1 весов связей}

         Forw                                                                  {Начало описания прямого функционирования}

                   Var                                                                     {Описание локальных переменных}

                            Long I, J, K;                           {I,J,K – переменные типа длинное целое }

                            Real R;                                            {R – действительное – для накопления суммы}

         Begin

                  K = 2 * N+1;                                    {K – номер обрабатываемого параметра}

                   R = Parameters[Sqr(N) + 3 * N) Div 2 + 1];

                   For I = 1 To N Do Begin

                            R = R + InSignals[I] * Parameters[I] +

                                                        Sqr(InSignals[I]) * Parameters[N + I];

                            For J = I + 1 To N Do Begin

                                      R = R + InSignals[I] * InSignals[J] * Parameters[K];

                                      K = K + 1

                            End

                   End

{Выходной сигнал равен сумме всех попарных произведений входных сигналов, умноженных на соответствующие параметры, плюс сумме всех входных сигналов умноженных на соответствующие параметры, плюс последний параметр}

                   OutSignals[1] = R

         End                                                                              {Конец описания прямого функционирования}

         Back                                                                   {Начало описания обратного функционирования }

                   Var                                                                     {Описание локальных переменных}

                            Long I, J, K;                           {I,J,K – переменные типа длинное целое }

                            Real R;                                            {R – действительное – для накопления суммы}

                            Vector W;                              {Массив для накопления промежуточных величин}

         Begin

                   For I = 1 To N Do

                            W[I] = 0;

                   K = 2 * N + 1;                         {K – номер обрабатываемого параметра}

                   For I = 1 To N Do Begin

                            Back.Parameters[I] = Back.Parameters[I] +

                                                                                                                 Back.OutSignals[1] * InSignals[I];

                            Back.Parameters[N + I] = Back.Parameters[N + I] +

                                                                                                                 Back.OutSignals[1] * Sqr(InSignals[I]);

                            W[I] = W[I] + Back.OutSignals[1] * (Parameters[I] +

                                                                                     2 * Parameters[N + I] * InSignals[I])

                            For J = I + 1 To N Do Begin

                                      Back.Parameters[K] = Back.Parameters[K] +

                                                                  Back.OutSignals[1] * InSignals[I] * InSignals[J];

                                      R = Back.OutSignals[1] * Parameters[K];

                                      W[I] = W[I] + R * InSignals[J];

                                      W[J] = W[J] + R * InSignals[I];

                                      K = K + 1

                            End

                   End;

                   For I = 1 To N Do

                            Back.InSignals[1] = W[I]

         End                                                                              {Конец описания обратного функционирования}

End Square_Sum_Plus {Конец описания адаптивного квадратичного сумматора}

End NetBibl                                                       {Конец библиотеки}

Описание блоков

Описание блока состоит из пяти основных разделов: заголовка описания блока, описания сигналов и параметров, описания состава, описания связей и конца описания блока. Существует два типа блоков – каскад и слой (Layer). Различие между этими двумя типами блоков состоит в том, что подсети, входящие в состав слоя, функционируют параллельно и независимо друг от друга, тогда как составляющие каскад подсети функционируют последовательно, причем каждая следующая подсеть использует результаты работы предыдущих подсетей. В свою очередь существует три вида каскадов – простой каскад (Cascad), цикл с фиксированным числом шагов (Loop) цикл по условию (Until). Различие между тремя видами каскадов очевидно – простой каскад функционирует один раз, цикл Loop функционирует указанное в описании число раз, а цикл Until функционирует до тех пор, пока не выполнится указанное в описании условие. В условии, указываемом в заголовке цикла Until, возможно использование сравнений массивов или интервалов массивов сигналов. Например, запись

InSignals=OutSignals

эквивалентна следующей записи

InSignals[1..N]=OutSignals[1..N]

которая эквивалентна вычислению следующей логической функции:

Function Equal(InSignals, OutSignals : RealArray) : Logic;

    Var Long I;

             Logic L

    Begin

             L = True

             For I = 1 To N Do

                      L = L And (InSignals[I] = OutSignals[I]);

             Equal = L

    End

Раздел описания состава следует сразу после заголовка блока за разделом описания сигналов и параметров и начинается с ключевого слова Contents, за которым следуют имена подсетей (блоков или элементов) со списками фактических аргументов, разделенные запятыми. Все имена подсетей должны предваряться псевдонимами. В дальнейшем указание псевдонима полностью эквивалентно указанию имени подсети со списком фактических аргументов или без, в зависимости от контекста. Признаком конца раздела описания состава подсети служит имя подсети за списком фактических аргументов которого не следует запятая.

Раздел описания сигналов и параметров следует за разделом описания состава и состоит из указания числа входных и выходных сигналов и числа параметров блока. В константных выражениях, указывающих число входных и выходных сигналов и параметров можно использовать дополнительно функцию NumberOf с двумя параметрами. Первым параметром является одно из ключевых слов InSignals, OutSignals, Parameters, а вторым – имя подсети со списком фактических аргументов. Функция NumberOf возвращает число входных или выходных сигналов или параметров (в зависимости от первого аргумента) в подсети, указанной во втором аргументе. Использование этой функции необходимо в случае использования блоком аргументов-подсетей. Концом раздела описания сигналов и параметров служит одно из ключевых слов ParamDef, Static или Connections.

Раздел определения типов параметров является необязательным разделом в описании блока и начинается с ключевого слова ParamDef. В каждой строке этого раздела можно задать минимальную и максимальную границы изменения одного типа параметров. Если в описании сети встречаются параметры неопределенного типа, то этот тип считается совпадающим с типом DefaultType. Описание типа не обязано предшествовать описанию параметров этого типа. Так, например, определение типа параметров может находиться в описании главной сети. Концом этого раздела служит одно из ключевых слов Connections.

Раздел описания связей следует за разделом описания сигналов и параметров и начинается с ключевого слова Connections. В разделе «Описание распределения сигналов» детально описано распределение связей.

Раздел конца описания блока состоит из ключевого слова End, за которым следует имя блока.

Пример описания блоков

При описании блоков используются элементы, описанные в библиотеке Elements, приведенной в разд. «Пример описания элементов».

NetBibl SubNets Used Elements;

{Библиотека подсетей, использующая библиотеку Elements}

{Сигмоидный нейрон с произвольным сумматором на N входов}

Cascad NSigm(aSum : Block; N : Long; Char : Real)

{В состав каскада входит произвольный сумматор на N входов и сигмоидный нейрон с необучаемой характеристикой}

         Contents aSum(N), S_NotTrain(Char)

         InSignals NumberOf(InSignals, aSum(N))

         OutSignals 1                                                                {Один выходной сигнал}

{Число параметров определяет сумматор}

         Parameters NumberOf(Parameters, aSum(N))

         Connections

                            {Входные сигналы нейрона – входные сигналы сумматора}

                   InSignals[1.. NumberOf(InSignals, aSum(N))] <=>

                            aSum.InSignals[1.. NumberOf(InSignals, aSum(N))]

                            {Выход сумматора – вход преобразователя}

                   aSum.OutSignals <=> S_NotTrain.InSignals

                   OutSignals <=> S_NotTrain.OutSignals

                            {Параметры нейрона – параметры сумматора}

                   Parameters[1.. NumberOf(Parameters, aSum(N))] <=>

                            aSum.Parameters[1.. NumberOf(Parameters, aSum(N))]

End            {Конец описания сигмоидного нейрона с произвольным сумматором}

                   {Слой сигмоидных нейронов с произвольными сумматорами на N входов}

Layer Lay1(aSum : Block; N,M : Long; Char : Real)

         Contents Sigm: NSigm(aSum,N,Char)[M]  {В состав слоя входит M нейронов}

{Число входных сигналов определяется как взятое M раз число входных сигналов нейронов. Вместо имени нейрона используем псевдоним}

         InSignals M * NumberOf(InSignals, Sigm)

         OutSignals M                                                              {Один выходной сигнал на нейрон}

         Parameters M * NumberOf(Parameters, Sigm)

{Число параметров определяется как взятое M раз число параметров нейронов}

         Connections

{Первые NumberOf(InSignals, NSigm(aSum,N,Char)) сигналов первому нейрону, и т.д.}

                   InSignals[1..M * NumberOf(InSignals, Sigm)] <=>

                            Sigm[1..M].InSignals[1.. NumberOf(InSignals, Sigm)]

                                      {Выходные сигналы нейронов - выходные сигналы сети}

                   OutSignals[1..M] <=> Sigm[1..M].OutSignals

                                      {Параметры слоя – параметры нейронов}

                   Parameters[1..M * NumberOf(Parameters, Sigm)] <=>

                            Sigm[1..M].Parameters[1.. NumberOf(Parameters, Sigm)]

End   {Конец описания слоя сигмоидных нейронов с произвольным сумматором}

{Слой точек ветвления}

Layer BLay( N,M : Long)

         Contents Branch(N)[M]          {В состав слоя входит M точек ветвления}

         InSignals M                                                        {По одному входному сигналу на точку ветвления}

         OutSignals M * N                                     {N выходных сигналов у каждой точки ветвления}

         Connections

{По одному входу на точку ветвления}

                   InSignals[1..M] <=> Branch[1..M].InSignals

{Выходные сигналы в порядке первый с каждой точки ветвления, затем второй и т.д. }

                   OutSignals[1..N * M] <=> Branch[+:1..M].OutSignals[1..N]

End                                                                                                 {Конец описания слоя Точек ветвления}

{Полный слой сигмоидных нейронов с произвольными сумматорами на N входов}

Cascad FullLay(aSum : Block; N,M : Long; Char : Real)

{Слой точек ветвления и слой нейронов}

         Contents Br: BLay1(M,N), Ne: Lay1(aSum,N,M,Char) 

         InSignals N                                                                  {Число входных сигналов – число точек ветвления}

         OutSignals M                                                     {Один выходной сигнал на нейрон}

{Число параметров определяется как взятое M раз число параметров нейронов}

         Parameters NumberOf(Parameters, Ne)

         Connections

{Входные сигналы – слою точек ветвления}

                   InSignals[1..N]<=> Br.InSignals[1..N]

{Выходные сигналы нейронов - выходные сигналы сети}

                   OutSignals[1..M] <=> Ne.OutSignals[1..M]

{Параметры слоя – параметры нейронов}

                  Parameters[1..NumberOf(Parameters, Ne)] <=>

                            Ne.Parameters[1.. NumberOf(Parameters, Ne)]

{Выход слоя точек ветвления – вход слоя нейронов}

                   Br.OutSignals[1..N * M] <=> Ne.InSignals[1..N * M]

End   {Конец описания слоя сигмоидных нейронов с произвольным сумматором}

{Сеть с сигмоидными нейронами и произвольными сумматорами, содержащая

                            Input – число нейронов на входном слое;

                            Output – число нейронов на выходном слое (число выходных сигналов);

                            Hidden – число нейронов на H>0 скрытых слоях;

                            N – число входных сигналов

все входные сигналы подаются на все нейроны входного слоя}

Cascad Net1(aSum : Block; Char : Real; Input, Output, Hidden, H, N : Long)

{Под тремя разными псевдонимами используется одна и та же подсеть с разными параметрами}

         Contents

                   In: FullLay(aSum,N,Input,Char),

                   Hid1: FullLay(aSum,Input,Hidden,Char)

                   Hid2: FullLay(aSum,Hidden,Hidden,Char)[H-1]                                 {Пусто при H=1}

                   Out: FullLay(aSum,Hidden,Output,Char)

         InSignals N                                                                  {Число входных сигналов – N}

         OutSignals Output                                    {Один выходной сигнал на нейрон}

{Число параметров определяется как сумма чисел параметров всех подсетей}

         Parameters NumberOf(Parameters, In)+ NumberOf(Parameters, Hid1)+

                   (H-1) * NumberOf(Parameters, Hid2)+ NumberOf(Parameters, Out)

         Connections

{Входные сигналы – входному слою}

                   InSignals[1..N]<=> In.InSignals[1..N]

{Выходные сигналы нейронов - с выходного слоя сети}

                   OutSignals[1..Output] <=> Out.OutSignals[1.. Output]

{Параметры сети последовательно всем подсетям}

                   Parameters[1..NumberOf(Parameters,In)] <=>

                                               In.Parameters[1.. NumberOf(Parameters, In)]

                   Parameters[NumberOf(Parameters,In)+1..NumberOf(Parameters,In)+

                            NumberOf(Parameters, Hid1)] <=>

                                                        Hid1.Parameters[1.. NumberOf(Parameters, Hid1)]

                   Parameters[NumberOf(Parameters,In)+ NumberOf(Parameters, Hid1)]+1

                            ..NumberOf(Parameters,In)+NumberOf(Parameters, Hid1)+

                            (H-1) * NumberOf(Parameters, Hid2)] <=>

                            Hid2[1..H-1].Parameters[1.. NumberOf(Parameters, Hid2)]

                   Parameters[NumberOf(Parameters,In)+ NumberOf(Parameters, Hid1)]+

                                      (H-1) * NumberOf(Parameters, Hid2)+1..NumberOf(Parameters,In)+

                                      NumberOf(Parameters,Hid1)+(H-1)*NumberOf(Parameters,Hid2)+

                                      NumberOf(Parameters, Out)] <=>

                                      Out.Parameters[1.. NumberOf(Parameters, Out)]

{Передача сигналов от слоя к слою}

{От входного к первому скрытому слою}

                   In.OutSignals[1..Input] <=> Hid1.InSignals[1..Input]

{От первого скрытого слоя}

                   Hid1.OutSignals[1..Hidden] <=> Hid2[1].InSignals[1..Hidden]

{Между скрытыми слоями. При H=1 эта запись пуста}

                   Hid2[1..H-2].OutSignals[1.. Hidden] <=> Hid2[2..H-1].InSignals[1.. Hidden]

{От скрытых – к выходному}

                   Hid2[H-1].OutSignals[1.. Hidden] <=> Out.InSignals[1.. Hidden]  

End

{Полносвязная сеть с M сигмоидными нейронами на К тактов функционирования с невыделенным входным слоем на M сигналов}

Loop Circle(aSum : Block; Char : Real; M, K : Long) K

         Contents

                   Net: FullLay(aSum,M,M,Char)

         InSignals M                                                        {Число входных сигналов – N}

         OutSignals M                                                     {Один выходной сигнал на нейрон}

                                                                                                                 {Число параметров определяется слоем FullLay}

         Parameters NumberOf(Parameters, Net)

         Connections

                   InSignals[1..M]<=> Net.InSignals[1..M]   {Входные сигналы – на вход слоя}

{Выходные сигналы – на выход слоя}

                   OutSignals[1..M] <=> Net.OutSignals[1.. M]    

                                      {Все параметры слою}

                   Parameters[1..NumberOf(Parameters,Net)] <=>

                                                        Net.Parameters[1.. NumberOf(Parameters,Net)]

                   Net.OutSignals[1..M] <=> Net.InSignals[1..M]  {Замыкаем выход на вход}

End   {Конец описания слоя сигмоидных нейронов с произвольным сумматором}

{Полносвязная сеть с М сигмоидными нейронами на К тактов функционирования с выделенным входным слоем на N сигналов. Все входные сигналы подаются на вход каждого нейрона входного слоя. Все параметры ограничены по абсолютному значению единицей}

Cascad  Net2: (aSum : Block; Char : Real; M, K, N : Long)

         Contents

                   In: FullLay(aSum,N,M,Char),   {Входной слой}

                   Net: Circle(aSum,Char,M,K)              {Полносвязная сеть}

         InSignals N                                                                                              {Число входных сигналов – N}

         OutSignals M                                                                                 {Один выходной сигнал на нейрон}

{Число параметров определяется как сумма чисел параметров всех подсетей}

         Parameters NumberOf(Parameters, In)+ NumberOf(Parameters, Net)

         ParamDef DefaultType -1 1

         Connections

                   InSignals[1..N]<=> In.InSignals[1..N]      {Входные сигналы – входному слою}

{Выходные сигналы нейронов - с выходного слоя сети}

                   OutSignals[1..M] <=> Net.OutSignals[1.. M]

{Параметры сети последовательно всем подсетям}

                   Parameters[1..NumberOf(Parameters, In)] <=>

                                               In.Parameters[1.. NumberOf(Parameters, In)]

                   Parameters[NumberOf(Parameters,In)+1..

                            NumberOf(Parameters,In)+NumberOf(Parameters, Net)]

                            <=> Net.Parameters[1.. NumberOf(Parameters, Net)]

{Передача сигналов от слоя к слою}

                   In.OutSignals[1..M] <=> Net.InSignals[1..M]              {От входного к циклу}

                   Net.OutSignals[1..M] <=> Net.InSignals[1..M]  {От первого скрытого слоя}

End

{Нейрон сети Хопфилда из N нейронов}

Cascad Hopf(N : Long)

         Contents Sum(N),Sign_Easy            {Сумматор и пороговый элемент}

         InSignals N                                                                                     {Число входных сигналов – N}

         OutSignals 1                                                                         {Число выходных сигналов – 1}

         Parameters NumberOf(Parameters,Sum(N))                      {Число параметров – N}

         Connections

                   InSignals[1..N]<=> Sum.InSignals[1..N]  {Входные сигналы – сумматору}

{Выходной сигнал нейрона – выходной сигнал порогового элемета}

                   OutSignals <=> Sign_Easy.OutSignals

{Параметры нейрона – параметры сумматора}

                   Parameters[1..NumberOf(Parameters, Sum(N))] <=>

                            Sum.Parameters[1.. NumberOf(Parameters, Sum(N))]

{Выход сумматора на вход порогового элемента}

                   Sum.OutSignals <=> Sign_Easy.InSignals

End

{Слой нейронов Хопфилда}

Layer HLay(N : Long)

         Contents Hop: Hopf(N)[N]               {В состав слоя входит N нейронов}

         InSignals N * N                                                           {N нейронов по N входных сигналов}

         OutSignals N                                                                        {Один выходной сигнал на нейрон}

         Parameters N * NumberOf(Parameters, Hop)

         Connections

{Первые NumberOf(InSignals, Hop) сигналов первому нейрону, и т.д.}

                   InSignals[1..Sqr(N)] <=> Hop[1..N].InSignals[1..N]

{Выходные сигналы нейронов - выходные сигналы сети}

                   OutSignals[1..N] <=> Hop[1..N].OutSignals

{Параметры слоя – параметры нейронов}

                   Parameters[1..N * NumberOf(Parameters, Hop)] <=>

                            Hop[1..N].Parameters[1.. NumberOf(Parameters, Hop)]

End

{Сеть Хопфилда из N нейронов}

Until Hopfield(N : Long) InSignals=OutSignals

         Contents BLay(N,N),HLay(N) {Слой точек ветвления и слой нейронов}

         InSignals N                                                                                     {Число входных сигналов – N}

         OutSignals N                                                                        {Число выходных сигналов – N}

         Parameters N * NumberOf(Parameters,HLay(N))     {Число параметров – N*N}

         Connections

{Входные сигналы – точкам ветвления}

                   InSignals[1..N]<=> BLay.InSignals[1..N]

{Выходные сигналы нейронов – выходные сигналы сети}

                   OutSignals[1..N] <=> HLay.OutSignals[1..N]

                   Parameters[1..N*NumberOf(Parameters, HLay(N))] <=>

                            HLay.Parameters[1..N*NumberOf(Parameters, HLay(N))]

                                      {Выход точек ветвления на вход нейронов}

                   BLay.OutSignals[1..Sqr(N)] <=> HLay.InSignals[1..Sqr(N)]

{Замыкаем конец на начало}

                   HLay.OutSignals[1..N] <=> BLay.InSignals[1..N]

End

End NetLib

NetWork Hop Used SubNets;                   {Сеть Хопфилда на пять нейронов}

MainNet Hopfield(5)

Parameters 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;

ParamMask -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1;

End NetWork

4.3.7.13. Сокращение описания сети

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

Раздел описания сигналов и параметров

Для всех видов блоков число параметров определяется как сумма чисел параметров всех подсетей, перечисленных в разделе описания состава. Это может приводить к лишним записям, но не повлияет на работу сети. Примером лишней записи может служить генерируемая запись:

Parameters M * NumberOf(Parameters,Branch(N))

в описании слоя точек ветвления, поскольку точки ветвления не имеют параметров.

Число входных сигналов блока определяется по следующим правилам:

·   для слоя число входных сигналов равно сумме числа входных сигналов всех подсетей, перечисленных в разделе описания состава;

·   для каскадов всех видов число входных сигналов блока равно числу входных сигналов подсети, стоящей первой в списке подсетей в разделе описания состава

Число выходных сигналов блока определяется по следующим правилам:

·   для слоя число выходных сигналов равно сумме числа выходных сигналов всех подсетей, перечисленных в разделе описания состава;

·   для каскадов всех видов число выходных сигналов блока равно числу выходных сигналов подсети, стоящей последней в списке подсетей в разделе описания состава;

Описания всех сетей, приведенные в предыдущем разделе полностью соответствуют правилам генерации. В качестве более общего примера приведем раздел описания сигналов и параметров двух условных блоков.

Layer  A

         Contents Net1, Net2[K], Net3

         InSignals NumberOf(InSignals,Net1)+K*NumberOf(InSignals,Net2)

                   +NumberOf(InSignals,Net3)

         OutSignals NumberOf(OutSignals,Net1)+K*NumberOf(OutSignals,Net2)

                   +NumberOf(OutSignals,Net3)

         Parameters NumberOf(Parameters,Net1)+

                   K*NumberOf(Parameters,Net2)+NumberOf(Parameters,Net3)

Cascad  B

         Contents Net1, Net2[K], Net3

         InSignals NumberOf(InSignals,Net1)

         OutSignals NumberOf(OutSignals,Net3)

         Parameters NumberOf(Parameters,Net1)+

                   K*NumberOf(Parameters,Net2)+NumberOf(Parameters,Net3)

Раздел описания связей

Раздел описания связей может быть разбит на пять подразделов.

1. Установление связи входных сигналов блока с входными сигналами подсетей.

2. Установление связи выходных сигналов блока с выходными сигналами подсетей.

3. Установление связи параметров блока с параметрами подсетей.

4. Установление связи между выходными сигналами одних подсетей и входными сигналами других подсетей.

5. Замыкание выхода блока на вход блока.

Для слоя раздел описания связей строится по следующим правилам.

1. Все подсети получают входные сигналы в порядке перечисления подсетей в разделе описания состава – первая часть массива входных сигналов слоя отдается первой подсети, следующая – второй и т.д. Если какая-либо подсеть в разделе описания состава указана с некоторым не равным единице числом экземпляров, то считается, что экземпляры этой подсети перечислены в списке в порядке возрастания номера.

2. Выходные сигналы подсетей образуют массив выходных сигналов слоя также в порядке перечисления подсетей в разделе описания состава – первая часть массива выходных сигналов слоя состоит из выходных сигналов первой подсети, следующая – второй и т.д. Если какая-либо подсеть в разделе описания состава указана с некоторым не равным единице числом экземпляров, то считается, что экземпляры этой подсети перечислены в списке в порядке возрастания номера.

3. Подразделы установления связи между выходными сигналами одних подсетей и входными сигналами других подсетей и замыкания выхода блока на вход для слоя отсутствуют.

Для каскадов раздел описания связей строится по следующим правилам:

1. Входные сигналы блока связываются с входными сигналами первой подсети в списке подсетей в разделе описания состава. Если для первой подсети указано не единичное число экземпляров, то все входные сигналы связываются с входными сигналами первого экземпляра подсети.

2. Выходные сигналы блока связываются с выходными сигналами последней подсети в списке подсетей в разделе описания состава. Если для последней подсети указано не единичное число экземпляров, то все выходные сигналы связываются с выходными сигналами последнего (с максимальным номером) экземпляра подсети.

3. Массив параметров блока образуется из массивов параметров подсетей в порядке перечисления подсетей в разделе описания состава – первая часть массива параметров блока состоит из параметров первой подсети, следующая – второй и т.д. Если какая-либо подсеть в разделе описания состава указана с некоторым не равным единице числом экземпляров, то считается, что экземпляры этой подсети перечислены в списке в порядке возрастания номера.

4. Выходные сигналы каждой подсети, кроме последней связываются с входными сигналами следующей подсети в списке подсетей в разделе описания состава. Если какая-либо подсеть в разделе описания состава указана с некоторым не равным единице числом экземпляров, то считается, что экземпляры этой подсети перечислены в списке в порядке возрастания номера.

5. Для блоков типа Cascad замыкание выхода блока на вход блока отсутствует. Для блоков типов Loop и Until замыкание выхода блока на вход блока достигается путем установления связей между выходными сигналами последней подсети в списке подсетей в разделе описания состава с входными сигналами первой подсети в списке подсетей в разделе описания состава. Если какая-либо подсеть в разделе описания состава указана с некоторым не равным единице числом экземпляров, то считается, что экземпляры этой подсети перечислены в списке в порядке возрастания номера.

Описания всех сетей, приведенные в предыдущем разделе полностью соответствуют правилам генерации. В качестве более общего примера приведем раздел описания сигналов и параметров трех условных блоков.

Layer  A

         Contents Net1, Net2[K], Net3

         InSignals[1..NumberOf(InSignals,Net1)+K*NumberOf(InSignals,Net2)

                   +NumberOf(InSignals,Net3)] <=>

                   Net1. InSignals[1..NumberOf(InSignals,Net1)],

                   Net2[1..K].InSignals[1..NumberOf(InSignals,Net2)],

                   Net3.InSignals[1..NumberOf(InSignals,Net3)]

         OutSignals[1..NumberOf(OutSignals,Net1)+

                   K*NumberOf(OutSignals,Net2)+NumberOf(OutSignals,Net3)] <=>

                   Net1. OutSignals[1..NumberOf(OutSignals,Net1)],

                   Net2[1..K].OutSignals[1..NumberOf(OutSignals,Net2)],

                   Net3.OutSignals[1..NumberOf(OutSignals,Net3)]

         Parameters[1..NumberOf(Parameters,Net1)+

                   K*NumberOf(Parameters,Net2)+NumberOf(Parameters,Net3)] <=>

                   Net1. Parameters[1..NumberOf(Parameters,Net1)],

                   Net2[1..K].Parameters[1..NumberOf(Parameters,Net2)],

                   Net3.Parameters[1..NumberOf(Parameters,Net3)]

Cascad B

         Contents Net1, Net2[K], Net3

         InSignals[1..NumberOf(InSignals,Net1)] <=>

                   Net1. InSignals[1..NumberOf(InSignals,Net1)]

         OutSignals[1..NumberOf(OutSignals,Net3)] <=>

                   Net3.OutSignals[1..NumberOf(OutSignals,Net3)]

         Parameters[1..NumberOf(Parameters,Net1)+

                   K*NumberOf(Parameters,Net2)+NumberOf(Parameters,Net3)] <=>

                   Net1. Parameters[1..NumberOf(Parameters,Net1)],

                   Net2[1..K].Parameters[1..NumberOf(Parameters,Net2)],

                   Net[3].Parameters[1..NumberOf(Parameters,Net3)]

                   Net1. OutSignals[1..NumberOf(OutSignals,Net1)],

                   Net2[1..K].OutSignals[1..NumberOf(OutSignals,Net2)] <=>

                   Net2[1..K].InSignals[1..NumberOf(InSignals,Net2)],

                   Net3.InSignals[1..NumberOf(InSignals,Net3)]

Loop  C N

         Contents Net1, Net2[K], Net3

         InSignals[1..NumberOf(InSignals,Net1)] <=>

                   Net1. InSignals[1..NumberOf(InSignals,Net1)]

         OutSignals[1..NumberOf(OutSignals,Net3)] <=>

                   Net3.OutSignals[1..NumberOf(OutSignals,Net3)]

         Parameters[1..NumberOf(Parameters,Net1)+

                   K*NumberOf(Parameters,Net2)+NumberOf(Parameters,Net3)] <=>

                   Net1. Parameters[1..NumberOf(Parameters,Net1)],

                   Net2[1..K].Parameters[1..NumberOf(Parameters,Net2)],

                   Net[3].Parameters[1..NumberOf(Parameters,Net3)]

                   Net1. OutSignals[1..NumberOf(OutSignals,Net1)],

                   Net2[1..K].OutSignals[1..NumberOf(OutSignals,Net2)] <=>

                   Net2[1..K].InSignals[1..NumberOf(InSignals,Net2)],

                   Net3.InSignals[1..NumberOf(InSignals,Net3)]

                   Net3.OutSignals[1..NumberOf(OutSignals,Net3)] <=>

                   Net1. InSignals[1..NumberOf(InSignals,Net1)]

Частично сокращенное описание

Если описываемый блок должен иметь связи, устанавливаемые не так, как описано в разд. «Раздел описания связей», то соответствующий раздел описания блока может быть описан явно полностью или частично. Если какой либо раздел описан частично, то действует следующее правило: те сигналы, параметры и их связи, которые описаны явно, берутся из явного описания, а те сигналы, параметры и их связи, которые не фигурируют в явном описании берутся из описания по умолчанию. Так, в приведенном в разд. «Пример описания блоков» описании слоя точек ветвления BLay невозможно использование генерируемого по умолчанию подраздела установления связи выходных сигналов блока с входными сигналами подсетей. Возможно следующее сокращенное описание.

                                      {Слой точек ветвления}

Layer BLay( N,M : Long)

         Contents Branch(N)[M]                    {В состав слоя входит M точек ветвления}

         Connections

{Выходные сигналы в порядке первый с каждой точки ветвления, затем второй и т.д. }

                   OutSignals[1..N * M] <=> Branch[+:1..M].OutSignals[1..N]

End                                                                                                          {Конец описания слоя точек ветвления}

Пример сокращенного описания блоков

При описании блоков используются элементы, описанные в библиотеке Elements, приведенной в разд. "Пример описания элементов".

NetBibl SubNets Used Elements;                                 

{Библиотека подсетей, использующая библиотеку Elements}

                                      {Сигмоидный нейрон с произвольным сумматором на N входов}

Cascad NSigm(aSum : Block; N : Long; Char : Real)

{В состав каскада входит произвольный сумматор на N входов и сигмоидный нейрон с необучаемой характеристикой}

         Contents aSum(N), S_NotTrain(Char)

End

{Слой сигмоидных нейронов с произвольными сумматорами на N входов}

Layer Lay1(aSum : Block; N,M : Long; Char : Real)

         Contents Sigm: NSigm(aSum,N,Char)[M]  {В состав слоя входит M нейронов}

End

{Слой точек ветвления}

Layer BLay( N,M : Long)

         Contents Branch(N)[M]          {В состав слоя входит M точек ветвления}

         Connections

{Выходные сигналы в порядке первый с каждой точки ветвления, затем второй и т.д. }

                   OutSignals[1..N * M] <=> Branch[+:1..M].OutSignals[1..N]

End

{Полный слой сигмоидных нейронов с произвольными сумматорами на N входов}

Cascad FullLay(aSum : Block; N,M : Long; Char : Real)

         Contents BLay1(M,N), Lay1(aSum,N,M,Char) {Слой точек ветвления и слой нейронов}

End   {Конец описания слоя сигмоидных нейронов с произвольным сумматором}

{Сеть с сигмоидными нейронами и произвольными сумматорами, содержащая

                   Input – число нейронов на входном слое;

                   Output – число нейронов на выходном слое (число выходных сигналов);

                   Hidden – число нейронов на H>0 скрытых слоях;

                   N – число входных сигналов

все входные сигналы подаются на все нейроны входного слоя}

Cascad  Net1(aSum : Block; Char : Real; Input, Output, Hidden, H, N : Long)

{Под тремя разными псевдонимами используется одна и таже подсеть с разными параметрами. Использование псевдонимов необходимо даже при сокращенном описании}

         Contents

                   In: FullLay(aSum,N,Input,Char),

                   Hid1: FullLay(aSum,Input,Hidden,Char)

                   Hid2: FullLay(aSum,Hidden,Hidden,Char)[H-1]              {Пусто при H=1}

                   Out: FullLay(aSum,Hidden,Output,Char)

End

{Полносвязная сеть с M сигмоидными нейронами на К тактов функционирования с невыделенным входным слоем на M сигналов. Все параметры ограничены по абсолютному значению единицей}

Loop Circle(aSum : Block; Char : Real; M, K : Long) K

         Contents

                   FullLay(aSum,M,M,Char)

         ParamDef DefaultType -1 1

End

{Полносвязная сеть с М сигмоидными нейронами на К тактов функционирования с выделенным входным слоем на N сигналов.

         Contents

                   In: FullLay(aSum,N,M,Char),             {Входной слой}

                   Net: Circle(aSum,Char,M,K)                       {Полносвязная сеть}

End

Cascad Hopf(N : Long)                                                         {Нейрон сети Хопфилда из N нейронов}

         Contents Sum(N),Sign_Easy                               {Сумматор и пороговый элемент}

End

{Слой нейронов Хопфилда}

Layer HLay(N : Long)

         Contents Hop: Hopf(N)[N]               {В состав слоя входит N нейронов}

End

{Сеть Хопфилда из N нейронов}

Until Hopfield(N : Long)  InSignals=OutSignals

         Contents BLay(N,N),HLay(N) {Слой точек ветвления и слой нейронов}

End

End NetLib

4.4. Запросы к компоненту сеть

В данном разделе главы рассмотрены все запросы, исполняемые компонентом сеть. Прежде чем приступать к описанию стандарта запросов компонента сеть следует выделить выполняемые им функции. Что должен делать компонент сеть? Очевидно, что прежде всего он должен уметь выполнять такие функции, как функционирование вперед (работа обученной сети) и назад (вычисление вектора поправок или градиента для обучения), модернизацию параметров (обучение сети) и входных сигналов (обучение примера). Кроме того компонент сеть должен уметь читать сеть с диска и записывать ее на диск. Необходимо так же предусмотреть возможность создавать сеть и редактировать ее структуру. Эти две функциональные возможности не связаны напрямую с работой (функционированием и обучением) сети. Таким образом, необходимо выделить сервисную компоненту – редактор сетей. Компонент редактор сетей позволяет создавать и изменять структуру сети, модернизировать обучаемые параметры в «ручном» режиме.

4.4.1. Запросы к компоненту сеть

Запросы к компоненту сеть можно разбить на пять групп:

1. Функционирование.

2. Изменение параметров.

3. Работа со структурой.

4. Инициация редактора и конструктора сетей.

5. Обработка ошибок.

Поскольку компонент сеть может работать одновременно с несколькими сетями, большинство запросов к сети содержат явное указание имени сети. Отметим, что при генерации запросов в качестве имени сети можно указывать имя любой подсети. Таким образом, иерархическая структура сети, описанная в стандарте языка описания сетей, позволяет работать с каждым блоком или элементом сети как с отдельной сетью. Ниже приведено описание всех запросов к компоненту сеть. Каждый запрос является логической функцией, возвращающей значение истина, если запрос выполнен успешно, и ложь – при ошибочном завершении исполнения запроса.

При вызове ряда запросов используются предопределенные константы. Их значения приведены в табл. 13.

 

 

 

 

Таблица 13.

Значения предопределенных констант

Название

Величина

Значение

InSignals

0

Входные сигналы прямого функционирования

OutSignals

1

Выходные сигналы прямого функционирования

Рarameters

2

Параметры

InSignalMask

3

Маска обучаемости входных сигналов

ParamMask

4

Маска обучаемости параметров

BackInSignals

5

Входные сигналы обратного функционирования

BackOutSignals

6

Выходные сигналы обратного функционирования

BackРarameters

7

Поправки к параметрам

Element

0

Тип подсети – элемент

Layer

1

Тип подсети – слой

Cascad

2

Тип подсети – простой каскад

CicleFor

3

Тип подсети – цикл с заданным числом проходов

CicleUntil

4

Тип подсети – цикл по условию

4.4.2. Запросы на функционирование

Два запроса первой группы позволяют проводить прямое и обратное функционирование сети. По сути эти запросы эквивалентны вызову методов Forw и Back сети или ее элемента.

4.4.2.1. Выполнить прямое Функционирование (Forw)

Описание запроса:

Pascal:

Function Forw ( Net : PString; InSignals : PRealArray ) : Logic;

C:

Logic Forw(PString Net, PRealArray InSignals)

Описание аргумента:

Net – указатель на строку символов, содержащую имя сети.

InSignals – массив входных сигналов сети.

Назначение – проводит прямое функционирование сети, указанной в параметре Net.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

3. Если список сетей компонента сеть пуст или имя сети, переданное в аргументе Net в этом списке не найдено, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Вызывается метод Forw сети, имя которой было указано в аргументе Net.

5. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 304 - ошибка прямого функционирования. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

4.4.2.2. Выполнить обратное Функционирование (Back)

Описание запроса:

Pascal:

Function Back( Net : PString; BackOutSignals : PRealArray) : Logic;

C:

Logic Back(PString Net, PRealArray BackOutSignals)

Описание аргумента:

Net – указатель на строку символов, содержащую имя сети.

BackOutSignals – массив производных функции оценки по выходным сигналам сети.

Назначение – проводит обратное  функционирование сети, указанной в параметре Net.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

3. Если список сетей компонента сеть пуст или имя сети, переданное в аргументе Net в этом списке не найдено, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Вызывается метод Back сети, имя которой было указано в аргументе Net.

5. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 305 -  ошибка обратного функционирования. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

4.4.3. Запросы на изменение параметров

Ко второй группе запросов относятся четыре запроса: Modify – модификация параметров, обычно называемая обучением, ModifyMask – модификация маски обучаемых синапсов, NullGradient – обнуление градиента и RandomDirection – сгенерировать случайное направление спуска.

4.4.3.1. Провести обучение (Modify)

Описание запроса:

Pascal:

Function Modify( Net : PString; OldStep, NewStep : Real; Tipe : Integer; Grad : PRealArray ) : Logic;

C:

Logic Modify(PString Net, Real OldStep, Real NewStep, Integer Tipe, PRealArray Grad)

Описание аргументов:

Net – указатель на строку символов, содержащую имя сети.

OldStep, NewStep – параметры обучения.

Tipe – одна из констант InSignals или Parameters.

Grad – адрес массива поправок или пустой указатель.

Назначение – проводит обучение параметров или входных сигналов сети, указанной в параметре Net.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

3. Если список сетей компонента сеть пуст или имя сети, переданное в аргументе Net в этом списке не найдено, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Если аргумент Grad содержит пустой указатель, то поправки берутся из массива Back.Parameters или Back.InputSignals в зависимости от значения аргумента Tipe.

5. В зависимости от значения аргумента Tipe для каждого параметра или входного сигнала P, при условии, что соответствующий ему элемент маски обучаемости, соответствующей аргументу Tipe равен -1 (значение истина) выполняется следующая процедура:

P1=P*OldStep+DP*NewStep.

Если для типа, которым описан параметр P, заданы минимальное и максимальное значения, то:

P2=Pmin, при P1<Pmin

P2=Pmax, при P1>Pmax

P2=P1 в противном случае

4.4.3.2. Изменить маску обучаемости (ModifyMask)

Описание запроса:

Pascal:

Function ModifyMask( Net : PString; Tipe : Integer; NewMask: PLogicArray ) : Logic;

C:

Logic Modify(PString Net, Integer Tipe, PLogicArray NewMask)

Описание аргументов:

Net – указатель на строку символов, содержащую имя сети.

Tipe – одна из констант InSignals или Parameters.

NewMask – новая маска обучаемости.

Назначение – Заменяет маску обучаемости параметров или входных сигналов сети, указанной в параметре Net.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

3. Если список сетей компонента сеть пуст или имя сети, переданное в аргументе Net в этом списке не найдено, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. В зависимости от значения параметра Tipe заменяет маску обучаемости параметров или входных сигналов на переданную в параметре NewMask.

4.4.3.3. Обнулить градиент (NullGradient)

Описание запроса:

Pascal:

Function NullGradient( Net : PString ) : Logic;

C:

Logic NullGradient(PString Net)

Описание аргументов:

Net – указатель на строку символов, содержащую имя сети.

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

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

3. Если список сетей компонента сеть пуст или имя сети, переданное в аргументе Net в этом списке не найдено, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Обнуляются массивы Back.Parameters и Back.OutSignals.

4.4.3.4. Случайное направление спуска (RandomDirection)

Описание запроса:

Pascal:

Function RandomDirection( Net : PString; Range : Real ) : Logic;

C:

Logic RandomDirection(PString Net, Real Range)

Описание аргументов:

Net – указатель на строку символов, содержащую имя сети.

Range – относительная ширина интервала, на котором должны быть распределены значения случайной величины.

Назначение – генерирует вектор случайных поправок к параметрам сети.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

3. Если список сетей компонента сеть пуст или имя сети, переданное в аргументе Net в этом списке не найдено, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Замещают все значения массива Back.Parameters на случайные величины. Интервал распределения случайной величины зависит от типа параметра, указанного при описании сети (ParamType) и аргумента Range. Полуширина интервала определяется как произведение полуширины интервала допустимых значений параметра, указанных в разделе ParamDef описания сети на величину Range. Интервал распределения случайной величины определяется как [-Полуширина; Полуширина].

4.4.4. Запросы, работающие со структурой сети

К третьей группе относятся запросы, позволяющие изменять структуру сети. Часть запросов этой группы описана в разд. "Остальные запросы".

4.4.4.1. Вернуть параметры сети (nwGetData)

Описание запроса:

Pascal:

Function nwGetData(Net : PString; DataType : Integer; Var Data : PRealArray) : Logic;

C:

Logic nwGetData(PString Net, Integer DataType, PRealArray* Data)

Описание аргументов:

Net – указатель на строку символов, содержащую имя сети.

DataType – одна из восьми предопределенных констант, описывающих тип данных сети.

Data – возвращаемый массив параметров сети.

Назначение – возвращает параметры, входные или выходные сигналы сети, указанной в аргументе Net.

Описание исполнения.

1. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является перавя сеть в списке сетей компонента сеть.

2. Если имя сети, переданное в аргументе Net не найдено в списке сетей компонента сеть или этот список пуст, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Если значение, переданное в аргументе DataType больше семи или меньше нуля, то возникает ошибка 306 – ошибочный тип параметра сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. В массиве Data возвращаются указанные в аргументе DataType параметры сети.

4.4.4.2. Установить параметры сети (nwSetData)

Описание запроса:

Pascal:

Function nwSetData(Net : PString; DataType : Integer; Var Data : RealArray) : Logic;

C:

Logic nwSetData(PString Net, Integer DataType, RealArray* Data)

Описание аргументов:

Net – указатель на строку символов, содержащую имя сети.

DataType – одна из восьми предопределенных констант, описывающих тип данных сети.

Data – массив параметров для замещения текущего массива параметров сети.

Назначение – замещает параметры, входные или выходные сигналы сети, указанной в аргументе Net на значения из массива Data.

Описание исполнения.

1. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

2. Если имя сети, переданное в аргументе Net не найдено в списке сетей компонента сеть или этот список пуст, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Если значение, переданное в аргументе DataType больше семи или меньше нуля, то возникает ошибка 306 – ошибочный тип параметра сети, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Значения параметров (входных или выходных сигналов) сети заменяются на значения из массива Data. Если длинны массива Data недостаточно для замены значений всех параметров (входных или выходных сигналов), то замещаются только столько элементов массива параметров (входных или выходных сигналов) сколько элементов в массиве Data. Если длинна массива Data больше длинны массива параметров (входных или выходных сигналов), то заменяются все элементы вектора параметров (входных или выходных сигналов), а лишние элементы массива Data игнорируются.

4.4.4.3. Нормализовать сеть (NormalizeNet)

Описание запроса:

Pascal:

Function NormalizeNet(Net : PString) : Logic;

C:

Logic NormalizeNet(PString Net)

Описание аргумента:

Net – указатель на строку символов, содержащую имя сети.

Назначение – нормализация сети, указанной в аргументе Net.

Описание исполнения.

1. Если в качестве аргумента Net дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая сеть в списке сетей компонента сеть.

2. Если имя сети, переданное в аргументе Net не найдено в списке сетей компонента сеть или этот список пуст, то возникает ошибка 301 – неверное имя сети, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Из сети удаляются связи, имеющие нулевой вес и исключенные из обучения. Нумерация сигналов и параметров сохраняется.

4. Из структуры сети удаляются «немые» участки – элементы и блоки, выходные сигналы которых не являются выходными сигналами сети в целом и не используются в качестве входных сигналов другими подсетями. Нумерация сигналов и параметров сохраняется.

5. Производится замена элементов, ставших «прозрачными» – путем замыкания входного сигнала на выходной, удаляются простые однородные сумматоры с одним входом и точки ветвления с одним выходом; адаптивные однородные сумматоры с одним входом заменяются синапсами. Нумерация сигналов и параметров сохраняется.

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

7. Производится изменение нумерации сигналов и параметров сети.

4.4.5. Остальные запросы

Ниже приведен список запросов, исполнение которых описано в главе 1:

nwSetCurrent – Сделать сеть текущей

nwAdd – Добавление сети

nwDelete – Удаление сети

nwWrite – Запись сети

nwGetStructNames – Вернуть имена подсетей

nwGetType – Вернуть тип подсети

nwEdit – Редактировать компоненту сеть

OnError – Установить обработчик ошибок

GetError – Дать номер ошибки

FreeMemory – Освободить память

В запросе nwGetType  в переменной TypeId возвращается значение одной из предопределенных констант, перечисленных в табл. 13.

Следует заметить, что два запроса nwGetData (Получить параметры) и nwSetData (Установить параметры) имеют название, совпадающее с названием запросов, описанных в разделе "Общий стандарт", но они имеют другой набор аргументов.

4.4.6. Ошибки компонента сеть

В табл. 14 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом сеть, и действия стандартного обработчика ошибок.

Таблица 14

Ошибки компонента сеть и действия стандартного обработчика ошибок.

Название ошибки

Стандартная обработка

301

Неверное имя сети

Занесение номера в Error

302

Ошибка считывания сети

Занесение номера в Error

303

Ошибка сохранения сети

Занесение номера в Error

304

Ошибка прямого функционирования

Занесение номера в Error

305

Ошибка обратного функционирования

Занесение номера в Error

306

Ошибочный тип параметра сети

Занесение номера в Error

5. Оценка и интерпретатор ответа

Эта глава посвящена обзору различных видов оценок, способам их вычисления. В ней так же рассмотрен способ определения уровня уверенности сети в выданном ответе и приведен способ построения оценок, позволяющих определять уровень уверенности. Приведен основной принцип проектирования оценки: надо учить сеть тому, что мы хотим от нее получить. Приведенные в данной главе результаты впервые были опубликованы в работах [78, 82, 84, 145, 146, 149, 152].

Основные функции, которые должна выполнять оценка:

1. Вычислять оценку решения, выданного сетью.

2. Вычислять производные этой оценки по выходным сигналам сети.

Кроме оценок, в первом разделе этой главы рассмотрен другой, тесно связанный с ней объект – интерпретатор ответа. Основное назначение этого объекта – интерпретировать выходной вектор сети как ответ, понятный пользователю. Однако, при определенном построении интерпретатора и правильно построенной по нему оценке, интерпретатор ответа может также оценивать уровень уверенности сети в выданном ответе.

При частичной аппаратной реализации нейрокомпьютера включение функции оценки в аппаратную часть не эффективно, поскольку оценка является сложным устройством (многие функции оценки включают в себя операции сортировки, и другие аналогичные операции). Однако при аппаратной реализации обученной нейронной сети (даже если предусматривается доучивание сети) аппаратная реализация интерпретатора ответа может оказаться эффективной, поскольку для обученной сети интерпретатор уже не меняется, и по сравнению с оценкой интерпретатор ответа достаточно прост.

5.1. Интерпретатор ответа

Как было показано в главе «Описание нейронных сетей», ответ, выдаваемый нейронной сетью, как правило, является числом, из диапазона . Если ответ выдается несколькими нейронами, то на выходе сети мы имеем вектор, каждый компонент которого лежит в интервале . Если в качестве ответа требуется число из этого диапазона, то мы можем его получить. Однако, в большинстве случаев это не так. Достаточно часто требуемая в качестве ответа величина лежит в другом диапазоне. Например, при предсказании температуры воздуха 25 июня в Красноярске ответ должен лежать в интервале от 5 до 35 градусов Цельсия. Сеть не может дать на выходе такого сигнала. Значит, прежде чем обучать сеть необходимо решить в каком виде будем требовать ответ. В данном случае ответ можно требовать в виде , где T – требуемая температура,  и  – минимальная и максимальная температуры, a – ответ, который будем требовать от сети. При интерпретации ответа необходимо проделать обратное преобразование. Если сеть выдала сигнал a, то ответом является величина . Таким образом, можно интерпретировать выдаваемый сетью сигнал, как величину из любого, наперед заданного диапазона.

Если при составлении обучающего множества ответ на примеры определялся с некоторой погрешностью, то от сети следует требовать не точного воспроизведения ответа, а попадания в интервал заданной ширины. В этом случае интерпретатор ответа может выдать сообщение о правильности (попадании в интервал) ответа.

Другим, часто встречающимся случаем, является предсказание сетью принадлежности входного вектора одному из заданных классов. Такие задачи называют задачами классификации, а решающие их сети – классификаторами. В простейшем случае задача классификации ставится следующим образом: пусть задано N классов. Тогда нейросеть выдает вектор из N сигналов. Однако, нет единого универсального правила интерпретации этого вектора. Наиболее часто используется интерпретация по максимуму: номер нейрона, выдавшего максимальный по величине сигнал, является номером класса, к которому относится предъявленный сети входной вектор. Такие интерпретаторы ответа называются интерпретаторами, кодирующими ответ номером канала (номер нейрона – номер класса). Все интерпретаторы, использующие кодирование номером канала, имеют один большой недостаток – для классификации на N классов требуется N выходных нейронов. При большом N требуется много выходных нейронов для получения ответа. Однако существуют и другие виды интерпретаторов.

Двоичный интерпретатор. Основная идея двоичного интерпретатора – получение на выходе нейронной сети двоичного кода номера класса. Это достигается двухэтапной интерпретацией:

1. Каждый выходной сигнал нейронной сети интерпретируется как 1, если он больше , и как 0 в противном случае.

2. Полученная последовательность нулей и единиц интерпретируется как двоичное число.

Двоичный интерпретатор позволяет интерпретировать N выходных сигналов нейронной сети как номер одного из 2N классов.

Порядковый интерпретатор. Порядковый интерпретатор кодирует номер класса подстановкой. Отсортируем вектор выходных сигналов по возрастанию. Вектор, составленный из номеров нейронов последовательно расположенных в отсортированном векторе выходных сигналов, будет подстановкой. Если каждой подстановке приписать номер класса, то такой интерпретатор может закодировать N! классов используя N выходных сигналов.

5.2. Уровень уверенности

Часто при решении задач классификации с использованием нейронных сетей недостаточно простого ответа «входной вектор принадлежит k-му классу». Хотелось бы также оценить уровень уверенности в этом ответе. Для различных интерпретаторов вопрос определения уровня уверенности решается по-разному. Однако, необходимо учесть, что от нейронной сети нельзя требовать больше того, чему ее обучили. В этом разделе будет рассмотрен вопрос об определении уровня уверенности для нескольких интерпретаторов, а в следующем будет показано, как построить оценку так, чтобы нейронная сеть позволяла его определить.

1. Кодирование номером канала. Знаковый интерпретатор. Знаковый интерпретатор работает в два этапа.

1. Каждый выходной сигнал нейронной сети интерпретируется как 1, если он больше , и как 0 в противном случае.

2. Если в полученном векторе только одна единица, то номером класса считается номер нейрона, сигнал которого интерпретирован как 1. В противном случае ответом считается неопределенный номер класса (ответ «не знаю»).

Для того чтобы ввести уровень уверенности для этого интерпретатора потребуем, чтобы при обучении сети для всех примеров было верно неравенство: , где ;  - i-ый выходной сигнал. e – уровень надежности (насколько сильно сигналы должны быть отделены от  при обучении). В этом случае уровень уверенности R определяется следующим образом: . Таким образом, при определенном ответе уровень уверенности показывает, насколько ответ далек от неопределенного, а в случае неопределенного ответа – насколько он далек от определенного.

2. Кодирование номером канала. Максимальный интерпретатор. Максимальный интерпретатор в качестве номера класса выдает номер нейрона, выдавшего максимальный сигнал. Для такого интерпретатора в качестве уровня уверенности естественно использовать некоторую функцию от разности между максимальным и вторым по величине сигналами. Для этого потребуем, чтобы при обучении для всех примеров обучающего множества разность между максимальным и вторым по величине сигналами была не меньше уровня надежности e. В этом случае уровень уверенности вычисляется по следующей формуле: , где  – максимальный, а  – второй по величине сигналы.

3. Двоичный интерпретатор. Уровень надежности для двоичного интерпретатора вводится так же, как и для знакового интерпретатора при кодировании номером канала.

4. Порядковый интерпретатор. При использовании порядкового интерпретатора в качестве уровня уверенности естественно брать функцию от разности двух соседних сигналов в упорядоченном по возрастанию векторе выходных сигналов. Для этого потребуем, чтобы при обучении для всех примеров обучающего множества в упорядоченном по возрастанию векторе выходных сигналов разность между двумя соседними элементами была не меньше уровня надежности e. В этом случае уровень уверенности можно вычислить по формуле , причем вектор выходных сигналов предполагается отсортированным по возрастанию.

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

5.3. Построение оценки по интерпретатору

Если в качестве ответа нейронная сеть должна выдать число, то естественной оценкой является квадрат разности выданного сетью выходного сигнала и правильного ответа. Все остальные оценки для обучения сетей решению таких задач являются модификациями данной. Приведем пример такой модификации. Пусть при составлении задачника величина , являющаяся ответом, измерялась с некоторой точностью e. Тогда нет смысла требовать от сети обучиться выдавать в качестве ответа именно величину . Достаточно, если выданный сетью ответ попадет в интервал. Оценка, удовлетворяющая этому требованию, имеет вид:

Эту оценку будем называть оценкой числа с допуском e.

Для задач классификации также можно пользоваться оценкой типа суммы квадратов отклонений выходных сигналов сети от требуемых ответов. Однако, эта оценка плоха тем, что во-первых, требования при обучении сети не совпадают с требованиями интерпретатора, во-вторых – такая оценка не позволяет оценить уровень уверенности сети в выданном ответе. Достоинством такой оценки является ее универсальность. Опыт работы с нейронными сетями, накопленный красноярской группой НейроКомп, свидетельствует о том, что при использовании оценки, построенной по интерпретатору, в несколько раз возрастает скорость обучения. Рассмотрим построение оценок по интерпретатору для четырех рассмотренных в предыдущем разделе интерпретаторов ответа.

В ряде описаний оценки и ее производной, приведенных далее, используется следующая функция и ее производная:

1. Кодирование номером канала. Знаковый интерпретатор. Пусть для рассматриваемого примера правильным ответом является k-ый класс. Тогда вектор выходных сигналов сети должен удовлетворять следующей системе неравенств:

где e- уровень надежности.

Оценку, вычисляющую расстояние от точки a в пространстве выходных сигналов до множества точек, удовлетворяющих этой системе неравенств, можно записать в виде:

Производная оценки по i-му выходному сигналу равна

.

2. Кодирование номером канала. Максимальный интерпретатор. Пусть для рассматриваемого примера правильным ответом является k-ый класс. Тогда вектор выходных сигналов сети должен удовлетворять следующей системе неравенств:при . Оценкой решения сетью данного примера является расстояние от точки a в пространстве выходных сигналов до множества точек, удовлетворяющих этой системе неравенств. Для записи оценки, исключим из вектора выходных сигналов сигнал , а остальные сигналы отсортируем по убыванию. Обозначим величину  через , а вектор отсортированных сигналов через . Система неравенств в этом случае приобретает вид , при i>1. Множество точек удовлетворяющих этой системе неравенств обозначим через D. Очевидно, что если , то точка b принадлежит множеству D. Если , то найдем проекцию точки b на гиперплоскость . Эта точка имеет координаты . Если , то точка  принадлежит множеству D. Если нет, то точку b нужно проектировать на гиперплоскость. Найдем эту точку. Ее координаты можно записать в следующем виде . Эта точка обладает тем свойством, что расстояние от нее до точки b минимально. Таким образом, для нахождения величины b достаточно взять производную от расстояния по b и приравнять ее к нулю:

Из этого уравнения находим b и записываем координаты точки :

.

Эта процедура продолжается дальше, до тех пор, пока при некотором l не выполнится неравенство или пока l не окажется равной N-1. Оценкой является расстояние от точки b до точки . Она равна следующей величине

.

Производная оценки по выходному сигналу  равна

Для перехода к производным по исходным выходным сигналам  необходимо обратить сделанные на первом этапе вычисления оценки преобразования.

3. Двоичный интерпретатор. Оценка для двоичного интерпретатора строится точно также как и для знакового интерпретатора при кодировании номером канала. Пусть правильным ответом является k-ый класс, тогда обозначим через K множество номеров сигналов, которым в двоичном представлении k соответствуют единицы. При уровне надежности оценка задается формулой:

Производная оценки по i-му выходному сигналу равна:

 .

4. Порядковый интерпретатор. Для построения оценки по порядковому интерпретатору необходимо предварительно переставить компоненты вектора a в соответствии с подстановкой, кодирующей правильный ответ. Обозначим полученный в результате вектор через . Множество точек, удовлетворяющих условию задачи, описывается системой уравнений , где e – уровень надежности. Обозначим это множество через D. Оценка задается расстоянием от точки b до проекции этой точки на множество D. Опишем процедуру вычисления проекции.

1. Просмотрев координаты точки , отметим те номера координат, для которых нарушается неравенство .

2. Множество отмеченных координат либо состоит из одной последовательности последовательных номеров , или из нескольких таких последовательностей. Найдем точку , которая являлась бы проекцией точки  на гиперплоскость, определяемую уравнениями , где i пробегает множество индексов отмеченных координат. Пусть множество отмеченных координат распадается на n последовательностей, каждая из которых имеет вид , где m – номер последовательности. Тогда точка  имеет вид:

1. Точка  является проекцией, и следовательно, расстояние от  до  должно быть минимальным. Это расстояние равно . Для нахождения минимума этой функции необходимо приравнять к нулю ее производные по . Получаем систему уравнений . Решая ее, находим .

2. Если точка  удовлетворяет неравенствам, приведенным в первом пункте процедуры, то расстояние от нее до точки  является оценкой. В противном случае, повторяем первый шаг процедуры, используя точку  вместо ; Объединяем полученный список отмеченных компонентов со списком, полученным при поиске предыдущей точки; находим точку , повторяя все шаги процедуры, начиная со второго.

Отметим, что в ходе процедуры число отмеченных последовательностей соседних индексов не возрастает. Некоторые последовательности могут сливаться, но новые возникать не могут. После нахождения проекции можно записать оценку:

.

Обозначим через  m-ую последовательность соседних координат, выделенную при последнем исполнении первого шага процедуры вычисления оценки: . Тогда производную оценки по выходному сигналу  можно записать в следующем виде:

 

Таким образом, построение оценки по интерпретатору сводится к следующей процедуре.

1. Определяем множество допустимых точек, то есть таких точек в пространстве выходных сигналов, которые интерпретатор ответа будет интерпретировать как правильный ответ со стопроцентным уровнем уверенности.

2. Находим проекцию выданной сетью точки на это множество. Проекцией является ближайшая точка из множества.

3. Записываем оценку как расстояние от точки, выданной сетью, до ее проекции на множество допустимых точек.

5.4. Оценка обучающего множества.
Вес примера

В предыдущем разделе был рассмотрен ряд оценок, позволяющих оценить решение сетью конкретного примера. Однако, ситуация, когда сеть хотят обучить решению только одного примера, достаточно редка. Обычно сеть должна научиться решать все примеры обучающего множества. Ряд алгоритмов обучения, которые будут рассматриваться в главе "учитель", требуют возможности обучать сеть решению всех примеров одновременно и, соответственно, оценивать решение сетью всех примеров обучающего множества. Как уже отмечалось, обучение нейронной сети – это процесс минимизации в пространстве обучаемых параметров функции оценки. Большинство алгоритмов обучения используют способность нейронных сетей быстро вычислять вектор градиента функции оценки по обучаемым параметрам. Обозначим оценку отдельного примера через . а оценку всего обучающего множества через . Простейший способ получения  из  – простая сумма. При этом вектор градиента вычисляется очень просто:

.

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

Обучение по всему обучающему множеству позволяет задействовать дополнительные механизмы ускорения обучения. Большинство этих механизмов будет рассмотрено в главе «Учитель». В этом разделе будет рассмотрен только один из них – использование весов примеров. Использование весов примеров может быть вызвано одной из следующих причин.

1. Один из примеров плохо обучается.

2. Число примеров разных классов в обучающем множестве сильно отличаются друг от друга.

3. Примеры в обучающем множестве имеют различную достоверность.

Рассмотрим первую причину – пример плохо обучается. Под «плохо обучается» будем понимать медленное снижение оценки данного примера по отношению к снижению оценки по обучающему множеству. Для того чтобы ускорить обучение данного примера, ему можно приписать вес, больший, чем у остальных примеров. При этом оценка по обучающему множеству и ее градиент можно записать в следующем виде: . где  – вес i-го примера. Эту функцию оценки будем называть оценкой взвешенных примеров. При этом градиент, вычисленный по оценке решения сетью этого примера, войдет в суммарный градиент с большим весом, и, следовательно, сильнее повлияет на выбор направления обучения. Этот способ применим также и для коррекции проблем, связанных со второй причиной – разное число примеров разных классов. Однако в этом случае увеличиваются веса всем примерам того класса, в котором меньше примеров. Опыт показывает, что использование весов в таких ситуациях позволяет улучшить обобщающие способности сетей.

В случае различной достоверности примеров в обучающем множестве функция взвешенных примеров не применима. Действительно, если известно, что достоверность ответа в k-ом примере в два раза ниже, чем в l-ом, хотелось бы, чтобы обученная сеть выдавала для k-ого примера в два раза меньший уровень уверенности. Этого можно достичь, если при вычислении оценки k-ого примера будет использоваться в два раза меньший уровень надежности. Оценка обучающего множества в этом случае вычисляется по формуле без весов, а достоверность учитывается непосредственно при вычислении оценки по примеру. Такую оценку будем называть оценкой взвешенной достоверности.

Таким образом, каждый пример может иметь два веса: вес примера и достоверность примера. Кроме того, при решении задач классификации каждый класс может обладать собственным весом. Окончательно функцию оценки по обучающему множеству и ее градиент можно записать в следующем виде:

где  – вес примера,  – его достоверность.

5.5. Глобальные и локальные оценки

В предыдущих разделах был рассмотрен ряд оценок. Эти оценки обладают одним общим свойством – для вычисления оценки по примеру, предъявленному сети, достаточно знать выходной вектор, выданный сетью при решении этого примера, и правильный ответ. Такие оценки будем называть локальными. Приведем точное определение.

Определение. Локальной называется любая оценка, являющаяся линейной комбинацией произвольных непрерывно дифференцируемых функций, каждая из которых зависит от оценки только одного примера.

Использование локальных оценок позволяет обучать сеть решению как отдельно взятого примера, так и всего обучающего множества в целом. Однако существуют задачи, для которых невозможно построить локальную оценку. Более того, для некоторых задач нельзя построить даже обучающее множество. Использование нелокальных оценок возможно даже при решении задач классификации.

Приведем два примера нелокальных оценки.

Кинетическая оценка для задачи классификации. Пусть в обучающее множество входят примеры k классов. Требуется обучить сеть так, чтобы в пространстве выходных сигналов множества примеров разных классов были попарно линейно разделимы.

Пусть сеть выдает N выходных сигналов. Для решения задачи достаточно, чтобы в ходе обучения все точки в пространстве выходных сигналов, соответствующие примерам одного класса, собирались вокруг одной точки – центра концентрации класса, и чтобы центры концентрации разных классов были как можно дальше друг от друга. В качестве центра концентрации можно выбрать барицентр множества точек, соответствующих примерам данного класса.

Таким образом, функция оценки должна состоять из двух компонентов: первая реализует притяжение между примерами одного класса и барицентром этого класса, а вторая отвечает за отталкивание барицентров разных классов. Обозначим точку в пространстве выходных сигналов, соответствующую m-му примеру, через , множество примеров i-го класса через , барицентр точек, соответствующих примерам этого класса, через  (), число примеров в i-ом классе через , а расстояние между точками a и b через . Используя эти обозначения, можно записать притягивающий компонент функции оценки для всех примеров i-го класса в виде:

Функция оценки  обеспечивает сильное притяжение для примеров, находящихся далеко от барицентра. Притяжение ослабевает с приближением к барицентру. Компонент функции оценки, отвечающий за отталкивание барицентров разных классов, должен обеспечивать сильное отталкивание близких барицентров и ослабевать с удалением барицентров друг от друга. Такими свойствами обладает гравитационное отталкивание. Используя гравитационное отталкивание можно записать второй компонент функции оценки в виде: . Таким образом, оценку, обеспечивающую сближение точек, соответствующих примерам одного класса, и отталкивание барицентров, можно записать в виде:

Вычислим производную оценки по j-му выходному сигналу, полученному при решении i-го примера. Пусть i-ый пример принадлежит l-му классу. Тогда производная имеет вид:

Эту оценку будем называть кинетической. Существует одно основное отличие этой оценки от всех других, ранее рассмотренных, оценок для решения задач классификации. При использовании традиционных подходов, сначала выбирают интерпретатор ответа, затем строят по выбранному интерпретатору функцию оценки, и только затем приступают к обучению сети. Для кинетической оценки такой подход не применим. Действительно, до того как будет закончено обучение сети невозможно построить интерпретатор. Кроме того, использование кинетической оценки, делает необходимым обучение сети решению всех примеров обучающего множества одновременно. Это связанно с невозможностью вычислить оценку одного примера. Кинетическая оценка, очевидно, не является локальной: для вычисления производных оценки по выходным сигналам примера необходимо знать барицентры всех классов, для вычисления которых, в свою очередь, необходимо знать выходные сигналы, получаемые при решении всех примеров обучающего множества.

Интерпретатор для кинетической оценки строится следующим образом. Для построения разделителя i-го и j-го классов строим плоскость, перпендикулярную к вектору  Уравнение этой плоскости можно записать в виде

 .

Для определения константы D находим среди точек i-го класса ближайшую к барицентру j-го класса. Подставляя координаты этой точки в уравнение гиперплоскости, получаем уравнение на D. Решив это уравнение, находим величину . Используя ближайшую к барицентру i-го класса точку j-го класса, находим величину . Искомая константа D находится как среднее арифметическое между  и . Для отнесения произвольного вектора к i-му или j-му классу достаточно подставить его значения в левую часть уравнения разделяющей гиперплоскости. Если значение левой части уравнения получается больше нуля, то вектор относится к j-му классу, в противном случае – к i-му.

Интерпретатор работает следующим образом: если для i-го класса все разделители этого класса с остальными классами выдали ответ i-ый класс, то окончательным ответом является i-ый класс. Если такого класса не нашлось, то ответ «не знаю». Ситуация, когда для двух различных классов все разделители подтвердили принадлежность к этому классу, невозможна, так как разделитель этих двух классов должен был отдать предпочтение одному из них.

Рассмотренный пример решения задачи с использованием нелокальной оценки позволяет выделить основные черты обучения с нелокальной оценкой:

1. Невозможность оценить решение одного примера.

2. Невозможность оценить правильность решения примера до окончания обучения.

3. Невозможность построения интерпретатора ответа до окончания обучения.

Этот пример является отчасти надуманным, поскольку его можно решить с использованием более простых локальных оценок. Ниже приведен пример задачи, которую невозможно решить с использованием локальных оценок.

Второй вариант – обучать сеть без задачника! Пусть нейросеть принимает один входной сигнал и выдает один выходной. При использовании сети выходной сигнал первого срабатывания сети (первое случайное число) будет служить входным сигналом для второго срабатывания сети и так далее.

Для построения оценки зададимся тремя наборами чисел:  – необходимое значение i-го момента,  – длина последовательности, на которой i-ый момент сгенерированной последовательности должен не более чем на  отличаться от .  – точность вычисления i-го момента.

Выборочная оценка совпадения i-го момента в сгенерированной последовательности на отрезке, начинающемся с j-го случайного числа, вычисляется по следующей формуле:  где  – выходной сигнал, полученный на l-ом срабатывании сети. Для оценки точности совпадения i-го момента в сгенерированной последовательности на отрезке, начинающемся с j-го случайного числа, воспользуемся оценкой числа с допуском :

Таким образом, при обучении сети генерации последовательности из N случайных чисел оценку можно записать в следующем виде:

Производная оценки по выходному сигналу l-го срабатывания сети можно записать в следующем виде:

Используя эту оценку можно обучать сеть генерировать случайные числа. Удобство этого подхода к решению задачи обучения генератора случайных чисел в том, что можно достаточно часто менять инициирующий сеть входной сигнал, что позволит сети генерировать не одну, а много различных последовательностей, обладающих всеми необходимыми свойствами.

При использовании предложенной оценки нет никаких гарантий того, что в генерируемой сетью последовательности не появятся сильно скоррелированные подпоследовательности. Для удаления корреляций можно модифицировать оценку так, чтобы она возрастала при появлении корреляций. Рассмотрим две подпоследовательности длинны L, первая из которых начинается с , а другая с . Коэффициент корреляции этих последовательностей записывается в виде:

В этой формуле приняты следующие обозначения: - среднее по последовательности, начинающейся с ;  – средний квадрат последовательности начинающейся с . Вычисление такого коэффициента корреляции довольно долгий процесс. Однако вместо выборочных моментов в формулу можно подставить значения моментов, которые последовательность должна иметь. В этом случае формула сильно упрощается:

Добавку для удаления корреляций последовательностей длиной от  до  и смещенных друг относительно друга на смещения от  до  можно записать в виде:

При необходимости можно ввести и другие поправки, учитывающие требования к генератору случайных чисел.

5.6. Составные интерпретатор ответа
и оценка

При использовании нейронных сетей для решения различных задач возникает необходимость получать от сети не один ответ, а несколько. Например, при обучении сети решению задачи диагностики отклонений в реакции на стресс нейронная сеть должна была определить наличие или отсутствие тринадцати различных патологий. Если одна сеть может выдавать только один ответ, то для решения задачи необходимо задействовать тринадцать сетей. Однако в этом нет необходимости. Поскольку каждый ответ, который должна выдавать сеть, имеет только два варианта, то можно использовать для его получения классификатор на два класса. Для такого классификатора необходимо два выходных сигнала. Тогда для решения задачи достаточно получать 26 выходных сигналов: первые два сигнала – для определения первой патологии, третий и четвертый – для второй и так далее. Таким образом, интерпретатор ответа для этой задачи состоит из тринадцати интерпретаторов, а оценка из тринадцати оценок. Более того, нет никаких ограничений на типы используемых интерпретаторов или оценок. Возможна комбинация, например, следующих ответов.

1. Число с допуском.

2. Классификатор на восемь классов.

3. Случайное число.

При использовании таких составных оценок и интерпретаторов каждый из этих компонентов должен следить за тем, чтобы каждая частная оценка или интерпретатор получали на вход те данные, которые им необходимы.

5.7. Запросы к компоненту интерпретатор ответа

Запросы к компоненту интерпретатор ответа можно разбить на пять групп:

1. Интерпретация.

2. Изменение параметров.

3. Работа со структурой.

4. Инициация редактора и конструктора интерпретатора ответа.

5. Обработка ошибок.

Поскольку нейрокомпьютер может работать одновременно с несколькими сетями, то и компонент интерпретатор ответа должен иметь возможность одновременной работы с несколькими интерпретаторами. Поэтому большинство запросов к интерпретатору содержат явное указание имени интерпретатора ответа. Ниже приведено описание всех запросов к компоненту интерпретатор ответа. Каждый запрос является логической функцией, возвращающей значение истина, если запрос выполнен успешно, и ложь – при ошибочном завершении исполнения запроса.

В запросах второй и третьей группы при обращении к частным интерпретаторам используется следующий синтаксис:

<Полное имя частного интерпретатора> ::= <Имя интерпретатора>.

<Псевдоним частного интерпретатора> [[<Номер экземпляра>]]

При вызове ряда запросов используются предопределенные константы. Их значения приведены в табл. 1.

Таблица 1

Значения предопределенных констант компонентов интерпретатор ответа и оценка

Название

Величина

Значение

Empty

0

Интерпретирует один сигнал как действительное число.

Binary

1

Кодирование номером канала. Знаковый интерпретатор

Major

2

Кодирование номером канала. Максимальный интерпретатор.

BynaryCoded

3

Двоичный интерпретатор.

UserType

-1

Интерпретатор, определенный пользователем.

5.7.1. Запрос на интерпретацию

Единственный запрос первой группы выполняет основную функцию компонента интерпретатор ответа – интерпретирует массив сигналов.

5.7.1.1. Интерпретировать массив сигналов (Interpretate)

Описание запроса:

Pascal:

Function Interpretate( IntName : PString; Signals : PRealArray;

Var Reliability, Answers : PRealArray ) : Logic;

C:

Logic Interpretate(PString IntName, PRealArray Signals, PRealArray* Reliability, PRealArray* Answers)

Описание аргумента:

IntName – указатель на строку символов, содержащую имя интерпретатора ответа.

Signals – массив интерпретируемых сигналов.

Answers – массив ответов.

Reliability – массив коэффициентов уверенности в ответе.

Назначение – интерпретирует массив сигналов Signals, используя интерпретатор ответа, указанный в параметре IntName.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента IntName дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первый интерпретатор ответа в списке интерпретаторов компонента интерпретатор.

3. Если список интерпретаторов компонента интерпретатор пуст или имя интерпретатора ответа, переданное в аргументе IntName в этом списке не найдено, то возникает ошибка 501 – неверное имя интерпретатора ответа, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Производится интерпретация ответа интерпретатором ответа, имя которого было указано в аргументе IntName.

5. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 504 – ошибка интерпретации. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

5.7.2. Остальные запросы

Ниже приведен список запросов, исполнение которых описано в разделе «Запросы общие для всех компонентов»:

aiSetCurrent – Сделать интерпретатор ответа текущим

aiAdd – Добавление нового интерпретатора ответа

aiDelete – Удаление интерпретатора ответа

aiWrite – Запись интерпретатора ответа

aiGetStructNames – Вернуть имена частных интерпретаторов

aiGetType – Вернуть тип частного интерпретатора

aiGetData – Получить параметры частного интерпретатора

aiGetName – Получить имена параметров частного интерпретатора

aiSetData – Установить параметры частного интерпретатора

aiEdit – Редактировать интерпретатор ответа

OnError – Установить обработчик ошибок

GetError – Дать номер ошибки

FreeMemory – Освободить память

В запросе aiGetType в переменной TypeId возвращается значение одной из предопределенных констант, перечисленных в табл. 1.

При исполнении запроса aiSetData генерируется запрос SetEstIntParameters к компоненте оценка. Аргументы генерируемого запроса совпадают с аргументами исполняемого запроса

5.7.3. Ошибки компонента интерпретатор ответа

В табл. 2 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом интерпретатор ответа, и действия стандартного обработчика ошибок.

Таблица 2.

Ошибки компонента интерпретатор ответа и действия стандартного

обработчика ошибок.

Название ошибки

Стандартная обработка

501

Неверное имя интерпретатора ответа

Занесение номера в Error

502

Ошибка считывания интерпретатора ответа

Занесение номера в Error

503

Ошибка сохранения интерпретатора ответа

Занесение номера в Error

504

Ошибка интерпретации

Занесение номера в Error

5.8.  Запосы к компоненту оценка

Запросы к компоненте оценка можно разбить на пять групп:

1. Оценивание.

2. Изменение параметров.

3. Работа со структурой.

4. Инициация редактора и конструктора оценки.

5. Обработка ошибок.

Поскольку нейрокомпьютер может работать одновременно с несколькими сетями, то и компонент оценка должен иметь возможность одновременной работы с несколькими оценками. Поэтому большинство запросов к оценке содержат явное указание имени оценки. Ниже приведено описание всех запросов к компоненту оценка. Каждый запрос является логической функцией, возвращающей значение истина, если запрос выполнен успешно, и ложь – при ошибочном завершении исполнения запроса.

В запросах второй и третьей группы при обращении к частным оценкам используется следующий синтаксис:

<Полное имя частной оценки> ::=

<Имя оценки>.<Псевдоним частной оценки> [[<Номер экземпляра>]]

При вызове ряда запросов используются предопределенные константы. Их значения приведены в табл. 1.

5.8.1. Запрос на оценивание

Единственный запрос первой группы выполняет основную функцию компонента оценка – вычисляет оценку и, если требуется, массив производных оценки по оцениваемым сигналам.

5.8.1.1. Оценить массив сигналов (Estimate)

Описание запроса:

Pascal:

Function Estimate( EstName : PString; Signals, Back, Answers, Reliability: PRealArray; Direv : Logic; Var Estim : Real ) : Logic;

C:

Logic Estimate(PString EstName, PRealArray Signals, PRealArray* Back, PRealArray Answers, PRealArray Reliability, Logic Direv, Real* Estim)

Описание аргумента:

EstName – указатель на строку символов, содержащую имя оценки.

Signals – указатель на массив оцениваемых сигналов.

Back – указатель на массив производных оценки по оцениваемым сигналам.

Answers – указатель на массив правильных ответов.

Reliability – указатель на массив правильных ответов.

Direv – признак необходимости вычисления производных (False – не вычислять).

Estim – вычисленная оценка.

Назначение – вычисляет оценку массива сигналов Signals, используя оценку, указанную в параметре EstName.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в качестве аргумента EstName дан пустой указатель, или указатель на пустую строку, то исполняющим запрос объектом является первая оценка в списке оценок компонента оценка.

3. Если список оценок компонента оценка пуст или имя оценки, переданное в аргументе EstName, в этом списке не найдено, то возникает ошибка 401 – неверное имя оценки, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Производится вычисление оценки оценкой, имя которой было указано в аргументе EstName.

5. Если во время выполнения запроса возникает ошибка, то генерируется внутренняя ошибка 404 – ошибка оценивания. Управление передается обработчику ошибок. Выполнение запроса прекращается. В противном случае выполнение запроса успешно завершается.

5.8.2. Остальные запросы

Ниже приведен список запросов, исполнение которых описано в разделе «Запросы общие для всех компонентов»:

esSetCurrent – Сделать оценку текущим

esAdd – Добавление новой оценки

esDelete – Удаление оценки

esWrite – Запись оценки

esGetStructNames – Вернуть имена частных оценок

esGetType – Вернуть тип частной оценки

esGetData – Получить параметры частной оценки

esGetName – Получить имена параметров частной оценки

esSetData – Установить параметры частной оценки

esEdit – Редактировать оценку

OnError – Установить обработчик ошибок

GetError – Дать номер ошибки

FreeMemory – Освободить память

В запросе esGetType в переменной TypeId возвращается значение одной из предопределенных констант, перечисленных в табл. 1.

Кроме того, во второй группе запросов есть запрос SetEstIntParameters аналогичный запросу esSetData, но определяющий частную оценку, параметры которой изменяются, по полному имени связанного с ней интерпретатора ответа.

5.8.2.1. Установить параметры (SetEstIntParameters)

Описание запроса:

Pascal:

Function SetEstIntParameters( IntName : PString; Param : PRealArray ) : Logic;

C:

Logic SetEstIntParameters(PString IntName, PRealArray Param)

Описание аргументов:

IntName – указатель на строку символов, содержащую полное имя частного интерпретатора ответа.

Param – адрес массива параметров.

Назначение – заменяет значения параметров частной оценки, связанной с интерпретатором ответа, указанного в аргументе IntName, на значения, переданные, в аргументе Param.

Описание исполнения.

1. Запрос передается всем частным оценкам всех оценок в списке оценок компонента оценка.

2. Если частная оценка связана с частным интерпретатором ответа, имя которого указано в аргументе IntName, то текущие значения параметров частной оценки заменяются на значения, хранящиеся в массиве, адрес которого передан в аргументе Param,.

5.8.3. Ошибки компонента оценка

В табл. 3 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом оценка, и действия стандартного обработчика ошибок.

Таблица 3

Ошибки компонента оценка и действия стандартного обработчика ошибок

Название ошибки

Стандартная обработка

401

Неверное имя оценки

Занесение номера в Error

402

Ошибка считывания оценки

Занесение номера в Error

403

Ошибка сохранения оценки

Занесение номера в Error

404

Ошибка вычисления оценки

Занесение номера в Error

6. Исполнитель

6.1. Описание компонента исполнитель

Компонент исполнитель является служебным. Это означает, что он универсален и невидим для пользователя. В отличие от всех других компонентов исполнитель не выполняет ни одной явной функции в обучении нейронных сетей, а является вспомогательным для компонентов учитель и контрастер. Задача этого компонента – упростить работу компонентов учитель и контрастер. Этот компонент выполняет всего несколько запросов, преобразуя каждый из них в последовательность запросов к различным компонентам. В данной главе содержательно рассмотрены алгоритмы исполнения всех запросов исполнителя.

Таблица 1

Параметры запроса для позадачной работы

Название параметра

1

2

3

4

Перейти к следующему примеру

+/–

+/–

+/–

+/–

Остановиться в конце обучающего множества

+/–

+/–

+/–

+/–

Вычислять оценку

+

+

+

Интерпретировать ответ

+

+

Вычислять градиент

+

Подготовка к контрастированию

+/–

Как было описано в главе «Функциональные компоненты», исполнитель выполняет четыре вида запросов.

1. Тестирование решения примера.

2. Оценивание решения примера.

3. Оценивание решения примера с вычислением градиента.

4. Оценивание и тестирование решения примера.

Все перечисленные запросы работают с текущей сетью и текущим примером задачника. Однако компоненту задачник необходимо указать, какой пример подлежит обработке. Кроме того, в главе «Оценка и интерпретатор ответа» введен класс оценок, вычисляемых по всему обучающему множеству. Такие оценки позволяют существенно улучшить обучаемость сети и ускорить ее обучение. Нет смысла возлагать перебор примеров на учителя, поскольку это снижает полезность компонента исполнитель. Таким образом, возникает еще четыре вида запросов.

5. Тестирование решения всех примеров обучающего множества.

6. Оценивание решения всех примеров обучающего множества.

7. Оценивание решения всех примеров обучающего множества с вычислением градиента.

8. Оценивание и тестирование решения всех примеров обучающего множества.

Как уже отмечалось в главе «Функциональные компоненты», каждую из приведенных четверок запросов можно объединить в один запрос с параметрами. В табл. 1 приведен полный список параметров для первой четверки запросов, а в табл. 2 – для второй.

Таблица 2

Параметры запроса для обучающего множества в целом

Название параметра

5

6

7

8

Вычислять оценку

+

+

+

Интерпретировать ответ

+

+

Вычислять градиент

+

Подготовка к

контрастированию

+/–

Символ «+» означает, что в запросе, номер которого указан в первой строке колонки, возможность, задаваемая данным параметром, должна быть использована. Символ «–» – что связанная с данным параметром возможность не используется. Символы «+/–» означают, что запрос может, как использовать, так и не использовать данную возможность. Отметим, что подготовка к контрастированию может быть задействована, только если производится вычисление градиента, а вычисление градиента невозможно без вычисления оценки. Остальные параметры независимы.

Отбор примеров в обучающее множество, открытие сеанса работы с задачником должны выполняться учителем или контрастером. Исполнитель только организует перебор примеров в обучающем множестве.

При полной или частичной аппаратной реализации нейрокомпьютера компонент исполнитель эффективно реализуется аппаратно, по следующим причинам.

Исполнитель реализует исключительно связные функции по отношению к другим компонентам.

Исполняемые им запросы постоянны и не зависят от реализаций других компонентов нейрокомпьютера.

Этот компонент работает чаще, чем любой другой, и, как следствие, ускорение в работе исполнителя приводит к соизмеримому ускорению работы нейрокомпьютера.

6.2. Запросы к компоненту исполнитель

В данном разделе описаны запросы исполнителя с алгоритмами их исполнения. При описании запросов используется аргумент Instruct, являющийся целым числом, принимающим значение одной из предопределенных констант, приведенных в табл. 3., или суммы любого числа этих констант. Аргумент Instruct является совокупностью шести битовых флагов.

Таблица 3

Предопределенные константы компонента исполнитель

Название

Иденти-
фикатор

Значение

Десят.

Шестн

Вычислять оценку

Estimate

1

H0001

Интерпретировать ответ

Interpret

2

H0002

Вычислять градиент

Gradient

4

H0004

Подготовка к контрастированию

Contrast

8

H0008

Перейти к следующему примеру

NextExample

16

H0010

Остановиться в конце обучающего множества

StopOnEnd

32

H0020

Устанавливать ответы

PutAnswers

64

H0040

Устанавливать оценки

PutEstimations

128

H0080

Устанавливать уверенность в ответе

PutReliability

256

H0100

В запросах не указываются используемые сеть, оценка и интерпретатор ответа, поскольку компонент исполнитель всегда использует текущие сеть, оценку и интерпретатор ответа.

6.2.1. Позадачная обработка (TaskWork)

Описание запроса:

Pascal:

Function TaskWork(Instruct, Handle : Integer; Var Answers, Reliability : PRealArray; Var Estim : Real) : Logic;

C:

Logic TaskWork(Integer Instruct, Integer Handle, PRealArray* Answers, PRealArray* Reliability; Real* Estim)

Описание аргументов:

Instruct – содержит инструкции о способе исполнения.

Handle – номер сеанса в задачнике.

Answers – указатель на массив вычисленных ответов.

Reliability – указатель на массив коэффициентов уверенности сети в ответах.

Estim – оценка решения примера.

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

Переменные, используемые при исполнении запроса

InArray, RelArray – адреса массивов для обменов с задачником.

Back – адрес массива для обменов с оценкой.

Описание исполнения.

Если в любой момент исполнения запроса возникает ошибка при исполнении запросов к другим компонентам, то исполнение запроса прекращается, возвращается значение ложь, ошибка компонента исполнитель не генерируется.

1.   Если в аргументе Instruct установлен бит Gradient и не установлен бит Estimate, то выполнение запроса прекращается, и генерируется ошибка 001 – Некорректное сочетание флагов в аргументе Instruct.

2.   Если в аргументе Instruct установлен бит Gradient, то генерируется запрос к сети NullGradient с аргументом Null.

3.   Если в аргументе Instruct установлен бит NextExample, то генерируется запрос к задачнику Next с аргументом Handle. (Переход к следующему примеру)

4.   Генерируется запрос к задачнику Last с аргументом Handle. (Проверка, существует ли пример)

5.   Если запрос Last вернул значение истина, то

5.1. Если в аргументе Instruct установлен бит StopOnEnd, то исполнение запроса прекращается, возвращается значение ложь. (Примера нет, переход на начало не нужен)

5.2. Генерируется запрос к задачнику Home с аргументом Handle. (Переход на начало обучающего множества)

6.   Переменной InArray присваивается значение Null и генерируется запрос к задачнику Get с аргументами Handle, InArray, tbPrepared (Получает от задачника предобработанные входные сигналы)

7.   Генерируется запрос к сети Forw, с аргументами Null, InArray (выполняется прямое функционирование сети).

8.   Освобождается массив InArray

9.   Присваивает переменной Data значение Null и генерирует запрос к сети GetNetData с аргументами Null, OutSignals, Data (Получает от сети выходные сигналы).

10.  Если в аргументе Instruct установлен бит Interpret, то

10.1. Генерируется запрос к интерпретатору ответа Interpretate с аргументами Data, Answers, Reliability. (Производит интерпретацию ответа)

10.2. Если в аргументе Instruct установлен бит PutAnswers, то генерируется запрос к задачнику Put с аргументами Handle, Answers, tbCalcAnswers (Передает задачнику вычисленные ответы)

10.3. Если в аргументе Instruct установлен бит PutReliability, то генерируется запрос к задачнику Put с аргументами Handle, Reliability, tbCalcReliability (Передает задачнику вычисленные коэффициенты уверенности в ответе)

11.  Если в аргументе Instruct установлен бит Gradient, то создается массив Back того же размера, что и Data. В противном случае переменной Back присваивается значение Null.

12.  Если в аргументе Instruct установлен бит Estimate, то

12.1. Переменной InArray присваивается значение Null и генерируется запрос к задачнику Get с аргументами Handle, InArray, tbAnswers (Получает от задачника правильные ответы)

12.2. Переменной RelArray присваивается значение Null и генерируется запрос к задачнику Get с аргументами Handle, RelArray, tbCalcReliability (Получает от задачника достоверности ответов)

12.3. Генерируется запрос к оценке Estimate с аргументами Data, Back, InArray, RelArray, Direv, Estim. Вместо Direv передается ноль, если в аргументе Instruct установлен бит Gradient, и 1 в противном случае. (Вычисляет оценку примера и, возможно, производные)

12.4. Если в аргументе Instruct установлен бит PutEstimations, то генерируется запрос к задачнику Put с аргументами Handle, Estim, tbEstimations (Передает задачнику оценку примера)

13.  Если в аргументе Instruct установлен бит Gradient, то генерируется запрос к сети Back, с аргументами Null, Back. Освобождает массив Back. (Выполняется обратное функционирование сети)

14.  Освобождается массив Data.

15.  Если в аргументе Instruct установлен бит Contrast, то генерируется запрос к контрастеру ContrastExample с аргументом истина.

16.  Завершает исполнение, возвращая значение истина

6.2.2. Обработка обучающего множества (TaskSetWork)

Описание запроса:

Pascal:

Function TaskSetWork(Instruct, Handle : Integer; Var Tasks : Integer; Var Correct : PRealArray; Var Estim : Real) : Logic;

C:

Logic TaskSetWork(Integer Instruct, Integer Handle, Integer* Tasks, PRealArray* Correct, Real* Estim)

Описание аргументов:

Instruct – содержит инструкции о способе исполнения.

Handle – номер сеанса в задачнике.

Tasks – число примеров в обучающем множестве.

Correct – указатель на массив, первый элемент которого равен числу правильных ответов на первую подзадачу и т.д.

Estim – средняя оценка решения всех примеров обучающего множества.

Назначение – производит обработку всех примеров обучающего множества.

Переменные, используемые при исполнении запроса

InArray, AnsArray, RelArray – адреса массивов для обменов с задачником.

Answers – указатель на массив вычисленных ответов.

Reliability – указатель на массив коэффициентов уверенности сети в ответах.

Back – адрес массива для обменов с оценкой.

Work – рабочая переменная типа Real для подсчета суммарной оценки.

Weight – рабочая переменная типа Real для веса примера.

Описание исполнения.

Если в любой момент исполнения запроса возникает ошибка при исполнении запросов к другим компонентам, то исполнение запроса прекращается, освобождаются все созданные в нем массивы, возвращается значение ложь, ошибка компонента исполнитель не генерируется.

Значение бит NextExample и StopOnEnd в аргументе Instruct игнорируются.

1.   Если в аргументе Instruct установлен бит Gradient и не установлен бит Estimate, то выполнение запроса прекращается, и генерируется ошибка 001 – Некорректное сочетание флагов в аргументе Instruct.

2.   Если в аргументе Instruct установлен бит Interpret, то создаются массивы Answers и Reliability того же размера, что и Correct

3.   Выполняется следующий фрагмент программы (Обнуление массива количеств правильных ответов)

3.1. For  I = 1 To TLong(Correct[0]) Do

3.2.   Correct[I] = 0

4.   Обнуляем счетчик числа примеров:  Tasks = 0

5.   Обнуляем суммарную оценку: Work = 0

6.   Переменной Back присваивается значение Null.

7.   Присваивает переменной Data значение Null и генерирует запрос к сети GetNetData с аргументами Null, OutSignals, Data. (Получает от сети выходные сигналы, для выяснения размерности массива Data. Сами значения сигналов не нужны)

8.   Если в аргументе Instruct установлен бит Gradient, то

8.1. Генерируется запрос к сети NullGradient с аргументом Null.

8.2. Создается массив Back того же размера, что и Data.

9.   Генерируется запрос к задачнику Home с аргументом Handle. (Переход на начало обучающего множества)

10.  Переменной InArray присваивается значение Null и генерируется запрос к задачнику Get с аргументами Handle, InArray, tbPrepared (Создаем массив InArray для получения от задачника предобработанных входных сигналов)

11.  Переменной AnsArray присваивается значение Null и генерируется запрос к задачнику Get с аргументами Handle, AnsArray, tbAnswers (Создаем массив AnsArray для получения от задачника правильных ответов)

12.  Если в аргументе Instruct установлен бит Estimate, то создается массив RelArray того же размера, что и AnsArray.

13.  Генерируется запрос к задачнику Last с аргументом Handle. (Проверка, существует ли пример)

14.  Если запрос Last вернул значение ложь, то

14.1. Tasks = Tasks + 1

14.2. Генерируется запрос к задачнику Get с аргументами Handle, InArray, tbPrepared (Получает от задачника предобработанные входные сигналы)

14.3. Генерируется запрос к сети Forw, с аргументами Null, InArray. (Выполняется прямое функционирование сети)

14.4. Генерирует запрос к сети GetNetData с аргументами Null, OutSignals, Data. (Получает от сети выходные сигналы)

14.5. Если в аргументе Instruct установлен бит Interpret, то

14.5.1. Генерируется запрос к интерпретатору ответа Interpretate с аргументами Data, Answers, Reliability. (Производит интерпретацию ответа)

14.5.2. Если в аргументе Instruct установлен бит PutAnswers, то генерируется запрос к задачнику Put с аргументами Handle, Answers, tbCalcAnswers (Передает задачнику вычисленные ответы)

14.5.3. Если в аргументе Instruct установлен бит PutReliability, то генерируется запрос к задачнику Put с аргументами Handle, Reliability, tbCalcReliability (Передает задачнику вычисленные коэффициенты уверенности в ответе)

14.5.4. Генерируется запрос к задачнику Get с аргументами Handle, AnsArray, tbAnswers (Получает от задачника правильные ответы)

14.5.5. Выполняется следующий фрагмент программы (Подсчитываются правильно полученные ответы)

14.5.5.1.For  I = 1 To TLong(Correct[0]) Do

14.5.5.2.If Answers[I] = AnsArray[I] Then TLong(Correct[I]) = TLong(Correct[I]) + 1

14.6. Если в аргументе Instruct установлен бит Estimate, то

14.6.1. Если в аргументе Instruct не установлен бит Interpret, то генерируется запрос к задачнику Get с аргументами Handle, AnsArray, tbAnswers (Получает от задачника правильные ответы)

14.6.2. Генерируется запрос к задачнику Get с аргументами Handle, RelArray, tbCalcReliability (Получает от задачника достоверности ответов)

14.6.3. Генерируется запрос к оценке Estimate с аргументами Data, Back, AnsArray, RelArray, Direv, Estim. Вместо Direv передается ноль, если в аргументе Instruct установлен бит Gradient, и 1 в противном случае. (Вычисляет оценку примера и, возможно, производные)

14.6.4. Генерируется запрос к задачнику Get с аргументами Handle, Weight, tbWeight (Получает от задачника вес примера)

14.6.5. Work = Work + Estim * Weight (Подсчитываем суммарную оценку)

14.6.6. Если в аргументе Instruct установлен бит PutEstimations, то генерируется запрос к задачнику Put с аргументами Handle, Estim, tbEstimations (Передает задачнику оценку примера)

14.7. Если в аргументе Instruct установлен бит Gradient, то генерируется запрос к сети Back, с аргументами Null, Back. (Выполняется обратное функционирование сети)

14.8. Если в аргументе Instruct установлен бит Contrast, то генерируется запрос к контрастеру ContrastExample с аргументом ложь.

14.9. Генерируется запрос к задачнику Next с аргументом Handle. (Переход к следующему примеру)

14.10.Переход к шагу 13 алгоритма.

15.  Вычисляем среднюю оценку: If Tasks = 0 Then Estim = 0 Else Estim = Work / Task

16.  Если в аргументе Instruct установлен бит Contrast, то генерируется запрос к контрастеру ContrastExample с аргументом истина.

17.  Освобождаются массивы Data, AnsArray è InArray.

18.  Если в аргументе Instruct установлен бит Estimate, то освобождается массив и RelArray.

19.  Если в аргументе Instruct установлен бит Interpret, то освобождаются массивы Answers и Reliability.

20.  Если Back <> Null освобождается массив Back.

21.  Завершает исполнение, возвращая значение истина

6.2.3. Ошибки компонента исполнитель

В табл. 4 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом исполнитель, и действия стандартного обработчика ошибок.

Таблица 4.

Ошибки компонента исполнитель
и действия стандартного обработчика ошибок.

Название ошибки

Стандартная обработка

001

Некорректное сочетание флагов в Instruct.

Занесение номера в Error

7. Учитель

Этот компонент не является столь универсальным как задачник, оценка или нейронная сеть, поскольку существует ряд алгоритмов обучения жестко привязаны к архитектуре нейронной сети. Примерами таких алгоритмов могут служить обучение (формирование синаптической карты) сети Хопфилда [316], обучение сети Кохонена [130, 131] и ряд других аналогичных сетей. Однако в главе «Описание нейронных сетей» приводится способ формирования сетей, позволяющий обучать сети Хопфилда [316] и Кохонена [130, 131] методом обратного распространения ошибки. Существуют также альтернативные способы вычисления градиента функции оценки по обучаемым параметрам нейронной сети и входным сигналам (см. например, [30, 285]). Описываемый в этой главе стандарт компонента учитель ориентирован в первую очередь на обучение двойственных сетей (сетей обратного распространения ошибки). Подробный обзор существующих методов обучения нейронных сетей приведен в [243, 251, 283].

7.1. Что можно обучать методом двойственности

Как правило, метод двойственности (обратного распространения ошибки) используют для подстройки параметров нейронной сети. Однако, как было показано в главе «Описание нейронных сетей», сеть может вычислять не только градиент функции оценки по обучаемым параметрам сети, но и по входным сигналам сети. Используя градиент функции оценки по входным сигналам сети можно решать задачу, обратную по отношению к обучению нейронной сети.

Рассмотрим следующий пример. Пусть есть сеть, обученная предсказывать по текущему состоянию больного и набору применяемых лекарств состояние больного через некоторый промежуток времени. Поступил новый больной. Его параметры ввели сети и она выдала прогноз. Из прогноза следует ухудшение некоторых параметров состояния больного. Возьмем выданный сетью прогноз, заменим значения параметров, по которым наблюдается ухудшение, на желаемые значения. Полученный вектор ответов объявим правильным ответом. Имея правильный ответ и ответ, выданный сетью, вычислим градиент функции оценки по входным сигналам сети. В соответствии со значениями элементов градиента изменим значения входных сигналов сети так, чтобы оценка уменьшилась. Проделав эту процедуру несколько раз, получим вектор входных сигналов, порождающих правильный ответ. Далее врач должен определить, каким способом (какими лекарствами или процедурами) перевести больного в требуемое (полученное в ходе обучения входных сигналов) состояние. В большинстве случаев часть входных сигналов не подлежит изменению (например пол или возраст больного). В этом случае эти входные сигналы должны быть помечены как не обучаемые (см. использование маски обучаемости входных сигналов в главе «Описание нейронных сетей»).

Таким образом, способность сетей вычислять градиент функции оценки по входным параметрам сети позволяет решать вполне осмысленную обратную задачу: так подобрать входные сигналы сети, чтобы выходные сигналы удовлетворяли заданным требованиям.

Кроме того, использование нейронных сетей позволяет ставить новые вопросы перед исследователем. В практике группы «НейроКомп» был следующий случай. Была поставлена задача обучить сеть ставить диагноз вторичного иммунодефицита по данным анализов крови и клеточного метаболизма. Вся обучающая выборка была разбита на два класса: больные и здоровые. При анализе базы данных стандартными статистическими методами значимых отличий обнаружить не удалось. Сеть оказалась не способна обучиться. Далее у исследователя было два пути: либо увеличить число нейронов в сети, либо определить, что мешает обучению. Исследователи выбрали второй путь. При обучении сети была применена следующая процедура: как только обучение сети останавливалось из-за невозможности дальнейшего уменьшения оценки, пример, имеющий наихудшую оценку, исключался из обучающего множества. После того, как сеть обучилась решению задачи на усеченном обучающем множестве, был проведен анализ исключенных примеров. Выяснилось, что исключено около половины больных. Тогда множество больных было разбито на два класса – больные1 (оставшиеся в обучающем множестве) и больные2 (исключенные). При таком разбиении обучающей выборки стандартные методы статистики показали значимые различия в параметрах классов. Обучение сети классификации на три класса быстро завершилось полным успехом. При содержательном анализе примеров, составляющих классы больные1 и больные2, было установлено, что к классу болные1 относятся больные на завершающей стадии заболевания, а к классу больные2 – на начальной. Ранее такое разбиение больных не проводилось. Таким образом, обучение нейронной сети решению прикладной задачи поставило перед исследователем содержательный вопрос, позволивший получить новое знание о предметной области.

Подводя итоги этого раздела, можно сказать, что, используя метод двойственности в обучении нейронных сетей можно:

1. Обучать сеть решению задачи.

2. Подбирать входные данные так, чтобы на выходе нейронной сети был заданный ответ.

3. Ставить вопросы о соответствии входных данных задачника постановке нейросетевой задачи.

7.2. Задача обучения сети

С точки зрения математики, задача обучения нейронной сети является задачей минимизации множества функций многих переменных. Речь идет именно о неструктурированном множестве функций, зависящих от одних и тех же переменных. Под переменными понимаются обучаемые параметры сети, а под функциями – оценки решения сетью отдельных примеров. Очевидно, что сформулированная выше задача является как минимум трудно разрешимой, а часто и просто некорректной.

Основная проблема состоит в том, что при оптимизации первой функции, значения других функций не контролируются. И наоборот, при оптимизации всех других функций не контролируется значение первой функции. Если обучение устроено по циклу – сначала оптимизация первой функции, потом второй и т.д., то после завершения цикла значение любой из функций может оказаться не меньше, а больше чем до начала обучения. Такой подход к обучению нейронных сетей привел к появлению различных методов «коррекции» данной трудности. Так, например, появилось правило, что нельзя «сильно» оптимизировать оценку отдельного примера, для того, чтобы при оптимизации сеть «не сильно» забывала остальные примеры. Возникли различные правила «правильного» перебора примеров и т.д. Наиболее ярким примером такого правила является случайный перебор примеров, рекомендованный для обучения сетей, обучаемых без учителя (сетей Кохонена [130, 131]). Однако все эти правила не гарантировали быстрого достижения результата. Более того, часто результат вообще не достигался за обозримое время.

Альтернативой всем правилам «малой оптимизации» и «правильного перебора примеров» является выработка единой функции оценки всего обучающего множества. Правила построения оценки обучающего множества из оценок отдельных примеров приведены в главе «Оценка и интерпретатор ответа».

В случае использования оценки обучающего множества, математическая интерпретация задачи приобретает классический вид задачи минимизации функции в пространстве многих переменных. Для этой классической задачи существует множество известных методов решения [48, 104, 144, 183, 240]. Особенностью обучения нейронных сетей является их способность быстро вычислять градиент функции оценки. Под быстро, понимается тот факт, что на вычисления градиента тратится всего в два-три раза больше времени, чем на вычисление самой функции. Именно этот факт делает градиентные методы наиболее полезными при обучении нейронных сетей. Большая размерность пространства обучаемых параметров нейронной сети (102-106) делает практически неприменимыми все методы, явно использующие матрицу вторых производных.

7.3. Описание алгоритмов обучения

Все алгоритмы обучения сетей методом обратного распространения ошибки опираются на способность сети вычислять градиент функции ошибки по обучающим параметрам. Даже правило Хебба использует вектор псевдоградиента, вычисляемый сетью при использовании зеркального порогового элемента (см. раздел «Пороговый элемент» главы «Описание нейронных сетей»). Таким образом, акт обучения состоит из вычисления градиента и собственно обучения сети (модификации параметров сети). Однако, существует множество не градиентных методов обучения, таких, как метод покоординатного спуска, метод случайного поиска и целое семейство методов Монте-Карло. Все эти методы могут использоваться при обучении нейронных сетей, хотя, как правило, они менее эффективны, чем градиентные методы. Некоторые варианты методов обучения описаны далее в этой главе.

Поскольку обучение двойственных сетей с точки зрения используемого математического аппарата эквивалентно задаче многомерной оптимизации, то в данной главе рассмотрены только несколько методов обучения, наиболее используемых при обучении сетей. Более полное представление о методах оптимизации, допускающих использование в обучении нейронных сетей, можно получить из книг по методам оптимизации (см. например [48, 104, 144]).

7.3.1. Краткий обзор макрокоманд учителя

При описании методов используется набор макросов, приведенный в табл. 2. В табл. 2 дано пояснение выполняемых макросами действий. Все макрокоманды могут оперировать с данными как пространства параметров, так и пространства входных сигналов сети. В первой части главы полагается, что объект обучения установлен заранее. В макросах используются понятия и аргументы, приведенные в табл. 1. Список макрокоманд приведен в табл. 2. При описании методов обучения все аргументы имеют тип, определяемый типом аргумента макрокоманды. Если в описании макрокоманды в табл. 2 тип аргумента не соответствует ни одному из типов, приведенных в табл. 1, то эти аргументы имеют числовой тип.

Таблица 1

Понятия и аргументы макрокоманд, используемых при описании учителя

Название

Смысл

Точка

Точка в пространстве параметров или входных сигналов. Аналогична вектору.

Вектор

Вектор в пространстве параметров или входных сигналов. Аналогичен точке.

Вектор_минимумов

Вектор минимальных значений параметров или входных сигналов.

Вектор_максимумов

Вектор максимальных значений параметров или входных сигналов.

Указатель_на_вектор

Адрес вектора. Используется для передачи векторов в макрокоманды.

Пустой_указатель

Указатель на отсутствующий вектор.

Таблица 2

Список макрокоманд, используемых для описания учителя

Название

Аргументы (типы)

Выполняемые действия

Модификация_вектора

Указатель_на_вектор

Старый_Шаг

Новый_Шаг

Генерирует запрос на модификацию вектора (см. раздел «Провести обучение (Modify)» приложения).

Вычислить_градиент

Вычисляет градиент функции оценки.

Установить_параметры

Указатель_на_вектор

Скопировать вектор, указанный в аргументе Указатель_на_вектор, в текущий вектор.

Таблица 2

Список макрокоманд, используемых для описания учителя (Продолжение)

Название

Аргументы (типы)

Выполняемые действия

Создать_вектор

Указатель_на_вектор

Создает экземпляр вектора с неопределенными значениями. Адрес вектора помещается в Указатель_на_вектор.

Освободить_вектор

Указатель_на_вектор

Освобождает память занятую вектором, расположенным по адресу Указатель_на_вектор.

Случайный_вектор

Указатель_на_вектор

В векторе, на который указывает Указатель_на_вектор, генерируется вектор, каждая из координат которого является случайной величиной, равномерно распределенной на интервале между значениями соответствующих координат векторов Вектор_минимумов и Вектор_максимумов.

Оптимизация_шага

Указатель_на_вектор

Начальный_Шаг

Производит подбор оптимального шага (см. рис. 3).

Сохранить_вектор

Указатель_на_вектор

Скопировать текущий вектор в вектор, указанный в аргументе Указатель_на_вектор.

Вычислить_оценку

Оценка

Вычисляет оценку текущего вектора. Вычисленную величину складывает в аргумент Оценка.

7.3.2. Неградиентные методы обучения

1. Создать_вектор В1

2. Создать_вектор В2

3. Вычислить_оценку О1

4. Сохранить_вктор В1

5. Установить_параметры В1

6. Случайный_вектор В2

7. Модификация_вектора В2, 0, 1

8. Вычислить_оценку О2

9. Если О2<О1 то переход к шагу 11

10. Переход к шагу 5

11. О1=О2

12. Переход к шагу 4

13. Установить_параметры В1

14. Освободить_вектор В1

15. Освободить_вектор В2

Рис. 1. Простейший алгоритм метода случайной стрельбы

Среди неградиентных методов рассмотрим следующие методы, каждый из которых является представителем целого семейства методов оптимизации:

1. Метод случайной стрельбы (представитель семейства методов Монте-Карло).

2. Метод покоординатного спуска (псевдоградиентный метод).

3. Метод случайного поиска (псевдоградиентный метод).

4. Метод Нелдера-Мида.

7.3.2.1. Метод
случайной стрельбы

Идея метода случайной стрельбы [48] состоит в генерации большой последовательности случайных точек и вычисления оценки в каждой из них. При достаточной длине последовательности минимум будет найден. Запись этой процедуры на макроязыке приведена на рис. 1

Остановка данной процедуры производится по команде пользователя или при выполнении условия, что О1 стало меньше некоторой заданной величины. Существует огромное разнообразие модификаций этого метода. Наиболее простой является метод случайной стрельбы с уменьшением радиуса. Пример процедуры, реализующей этот метод, приведен на рис. 2. В этом методе есть два параметра, задаваемых пользователем:

Число_попыток – число неудачных пробных генераций вектора при одном радиусе.

1. Создать_вектор В1

2. Создать_вектор В2

3. Вычислить_оценку О1

4. Число_Смен_Радиуса=1

5. Радиус=1/ Число_Смен_Радиуса

6. Попытка=0

7. Сохранить_вктор В1

8. Установить_параметры В1

9. Случайный_вектор В2

10. Модификация_вектора В2, 1, Радиус

11. Вычислить_оценку О2

12. Попытка=Попытка+1

13. Если О2<О1 то переход к шагу 16

14. Если Попытка<=Число_попыток то
переход к шагу 8

15. Переход к шагу 18

16. О1=О2

17. Переход к шагу 6

18. Число_Смен_Радиуса= Число_Смен_Радиуса+1

19. Радиус=1/ Число_Смен_Радиуса

20. Если радиус>= Минимальный_радиус
то переход к шагу 6

21. Установить_параметры В1

22. Освободить_вектор В1

23. Освободить_вектор В2

Рис. 2. Алгоритм метода случайной стрельбы с уменьшением радиуса

Минимальный_радиус – минимальное значение радиуса, при котором продолжает работать алгоритм.

Идея этого метода состоит в следующем. Зададимся начальным состоянием вектора параметров. Новый вектор параметров будем искать как сумму начального и случайного, умноженного на радиус, векторов. Если после Число_попыток случайных генераций не произошло уменьшения оценки, то уменьшаем радиус. Если произошло уменьшение оценки, то полученный вектор объявляем начальным и продолжаем процедуру с тем же шагом. Важно, чтобы последовательность уменьшающихся радиусов образовывала расходящийся ряд. Примером такой последовательности может служить использованный в примере на рис. 2 ряд .

Отмечен ряд случаев, когда метод случайной стрельбы с уменьшением радиуса работает быстрее градиентных методов, но обычно это не так.

7.3.2.2. Метод покоординатного спуска

Идея этого метода [48, 183] состоит в том, что если в задаче сложно или долго вычислять градиент, то можно построить вектор, обладающий приблизительно теми же свойствами, что и градиент следующим путем. Даем малое положительное приращение первой координате вектора. Если оценка при этом увеличилась, то пробуем отрицательное приращение. Далее так же поступаем со всеми остальными координатами. В результате получаем вектор, в направлении которого оценка убывает. Для вычисления такого вектора потребуется, как минимум, столько вычислений функции оценки, сколько координат у вектора. В худшем случае потребуется в два раза большее число вычислений функции оценки. Время же необходимое для вычисления градиента в случае использования двойственных сетей можно оценить как 2-3 вычисления функции оценки. Таким образом, учитывая способность двойственных сетей быстро вычислять градиент, можно сделать вывод о нецелесообразности применения метода покоординатного спуска в обучении нейронных сетей.

7.3.2.3. Подбор оптимального шага

Данный раздел посвящен описанию макрокоманды Оптимизация_Шага. Эта макрокоманда часто используется в описании процедур обучения и не столь очевидна как другие макрокоманды. Поэтому ее текст приведен на рис. 3. Идея подбора оптимального шага состоит в том, что при наличии направления в котором производится спуск (изменение параметров) задача многомерной оптимизации в пространстве параметров сводится к одномерной оптимизации – подбору шага. Пусть заданы начальный шаг (Ш2) и направление спуска  (антиградиент или случайное) (Н). Тогда вычислим величину О1 – оценку в текущей точке пространства параметров. Изменив параметры на вектор направления, умноженный на величину пробного шага, вычислим величину оценки в новой точке – О2. Если О2 оказалось меньше либо равно О1, то увеличиваем шаг и снова вычисляем оценку. Продолжаем эту процедуру до тех пор, пока не получится оценка, большая предыдущей. Зная три последних значения величины шага и оценки, используем квадратичную оптимизацию – по трем точкам построим параболу и следующий шаг сделаем в вершину параболы. После нескольких шагов квадратичной оптимизации получаем приближенное значение оптимального шага.

 Рис. 3. Алгоритм оптимизации шага

Если после первого пробного шага получилось О2 большее О1, то уменьшаем шаг до тех пор, пока не получим оценку, меньше чем О1. После этого производим квадратичную оптимизацию.

7.3.2.4. Метод случайного поиска

Этот метод [48] похож на метод случайной стрельбы с уменьшением радиуса, однако в его основе лежит другая идея – сгенерируем случайный вектор и будем использовать его вместо градиента. Этот метод использует одномерную оптимизацию – подбор шага. Одномерная оптимизация описана в разделе «Одномерная оптимизация». Процедура случайного поиска приведена на рис. 4. В этом методе есть два параметра, задаваемых пользователем.

Число_попыток – число неудачных пробных генераций вектора при одном радиусе.

Минимальный_радиус – минимальное значение радиуса, при котором продолжает работать алгоритм.

1. Создать_вектор Н

2. Число_Смен_Радиуса=1

3. Попытка=0

4. Радиус=1/ Число_Смен_Радиуса

5. Случайный_вектор Н

6. Оптимизация шага Н Радиус

7. Попытка=Попытка+1

8. Если Радиус=0 то Попытка=0

9. Если Попытка<=Число_попыток то переход к шагу 4

10. Число_Смен_Радиуса= Число_Смен_Радиуса+1

11. Радиус=1/ Число_Смен_Радиуса

12. Если Радиус>= Минимальный_радиус то переход к шагу 3

13. Освободить_вектор Н

Рис. 4. Алгоритм метода случайного поиска

Идея этого метода состоит в следующем. Зададимся начальным состоянием вектора параметров. Новый вектор параметров будем искать как сумму начального и случайного, умноженного на радиус, векторов. Если после Число_попыток случайных генераций не произошло уменьшения оценки, то уменьшаем радиус. Если произошло уменьшение оценки, то полученный вектор объявляем начальным и продолжаем процедуру с тем же шагом. Важно, чтобы последовательность уменьшающихся радиусов образовывала расходящийся ряд. Примером такой последовательности может служить использованный в примере на рис. 4 ряд .

7.3.2.5. Метод Нелдера-Мида

Этот метод [48] является одним из наиболее быстрых и наиболее надежных не градиентных методов многомерной оптимизации. Идея этого метода состоит в следующем. В пространстве оптимизируемых параметров генерируется случайная точка. Затем строится n-мерный симплекс с центром в этой точке, и длиной стороны l. Далее в каждой из вершин симплекса вычисляется значение оценки. Выбирается вершина с наибольшей оценкой. Вычисляется центр тяжести остальных n вершин. Проводится оптимизация шага в направлении от наихудшей вершины к центру тяжести остальных вершин. Эта процедура повторяется до тех пор, пока не окажется, что оптимизация не изменяет положения вершины. После этого выбирается вершина с наилучшей оценкой и вокруг нее снова строится симплекс с меньшими размерами (например ). Процедура продолжается до тех пор, пока размер симплекса, который необходимо построить, не окажется меньше требуемой точности.

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

7.3.3. Градиентные методы обучения

Изучению градиентных методов обучения нейронных сетей посвящено множество работ [47, 65, 92] (сослаться на все работы по этой теме не представляется возможным, поэтому дана ссылка на работы, где эта тема исследована наиболее детально). Кроме того, существует множество публикаций, посвященных градиентным методам поиска минимума функции [48, 104] (как и в предыдущем случае, ссылки даны только на две работы, которые показались наиболее удачными). Данный раздел не претендует на какую-либо полноту рассмотрения градиентных методов поиска минимума. В нем приведены только несколько методов, применявшихся в работе группой «НейроКомп». Все градиентные методы объединены использованием градиента как основы для вычисления направления спуска.

7.3.3.1. Метод наискорейшего спуска

Наиболее известным [48, 104, 183] среди градиентных методов является метод наискорейшего спуска. Идея этого метода проста: поскольку вектор градиента указывает направление наискорейшего возрастания функции, то минимум следует искать в обратном направлении. Последовательность действий приведена на рис. 5.

1. Вычислить_оценку О2

2. О1=О2

3. Вычислить_градиент

4. Оптимизация шага Пустой_указатель Шаг

5. Вычислить_оценку О2

6. Если О1-О2<Точность то переход к шагу 2

Рис. 5. Метод наискорейшего спуска

Этот метод работает, как правило, на порядок быстрее методов случайного поиска. Он имеет два параметра – Точность, показывающий, что если изменение оценки за шаг метода меньше чем Точность, то обучение останавливается; Шаг – начальный шаг для оптимизации шага. Заметим, что шаг постоянно изменяется в ходе оптимизации шага.

а)
б)
в)

Рис. 6. Траектории спуска при различных конфигурациях окрестности минимума и разных методах оптимизации.

Остановимся на основных недостатках этого метода. Во-первых, эти методом находится тот минимум, в область притяжения которого попадет начальная точка. Этот минимум может не быть глобальным. Существует несколько способов выхода из этого положения. Наиболее простой и действенный – случайное изменение параметров с дальнейшим повторным обучение методом наискорейшего спуска. Как правило, этот метод позволяет за несколько циклов обучения с последующим случайным изменением параметров найти глобальный минимум.

1. Создать_вектор В1

2. Создать_вектор В2

3. Шаг=1

4. Вычислить_оценку О2

5. Сохранить_вектор В1

6. О1=О2

7. N=0

8. Вычислить_градиент

9. Оптимизация_шага Пустой_указатель Шаг

10. N=N+1

11. Если N<k то переход к шагу 8

12. Сохранить_вектор В2

13. В2=В2-В1

14. ШагParTan=1

15. Оптимизация шага В2 ШагParTan

16. Вычислить_оценку О2

17. Если О1-О2<Точность то переход к шагу 5

Рис. 7. Метод kParTan

Вторым серьезным недостатком метода наискорейшего спуска является его чувствительность к форме окрестности минимума. На рис. 6а проиллюстрирована траектория спуска при использовании метода наискорейшего спуска, в случае, если в окрестности минимума линии уровня функции оценки являются кругами (рассматривается двумерный случай). В этом случае минимум достигается за один шаг. На рис. 6б приведена траектория метода наискорейшего спуска в случае эллиптических линий уровня. Видно, что в этой ситуации за один шаг минимум достигается только из точек, расположенных на осях эллипсов. Из любой другой точки спуск будет происходить по ломаной, каждое звено которой ортогонально к соседним звеньям, а длина звеньев убывает. Легко показать что для точного достижения минимума потребуется бесконечное число шагов метода градиентного спуска. Этот эффект получил название овражного, а методы оптимизации, позволяющие бороться с этим эффектом – антиовражных.

7.3.3.2. kParTan

Одним из простейших антиовражных методов [48, 104, 183] является метод kParTan. Идея метода состоит в том, чтобы запомнить начальную точку, затем выполнить k шагов оптимизации по методу наискорейшего спуска, затем сделать шаг оптимизации по направлению из начальной точки в конечную. Описание метода приведено на рис 7. На рис 6в приведен один шаг оптимизации по методу 2ParTan. Видно, что после шага вдоль направления из первой точки в третью траектория спуска привела в минимум. К сожалению, это верно только для двумерного случая. В многомерном случае направление kParTan не ведет прямо в точку минимума, но спуск в этом направлении, как правило, приводит в окрестность минимума меньшего радиуса, чем при еще одном шаге метода наискорейшего спуска (см. рис. 6б). Кроме того, следует отметить, что для выполнения третьего шага не потребовалось вычислять градиент, что экономит время при численной оптимизации.

7.3.3.3. Квазиньютоновские методы

Существует большое семейство квазиньютоновских методов [48], позволяющих на каждом шаге проводить минимизацию в направлении минимума квадратичной формы. Идея этих методов состоит в том, что функция оценки приближается квадратичной формой. Зная квадратичную форму, можно вычислить ее минимум и проводить оптимизацию шага в направлении этого минимума. Одним из наиболее часто используемых методов из семейства одношаговых квазиньютоновских методов является BFGS метод. Этот метод хорошо зарекомендовал себя при обучении нейронных сетей (см. [34]). Подробно ознакомиться с методом BFGS и другими квазиньютоновскими методами можно в работе [48].

7.4. Запросы к компоненту учитель

Компонент учитель одновременно работает только с одним учителем. Запросы к компоненту учитель можно разбить на следующие группы.

1. Обучение сети.

2. Чтение/запись учителя.

3. Инициация редактора учителя.

4. Работа с параметрами учителя.

7.4.1. Обучение сети

К данной группе относятся три запроса – обучить сеть (InstructNet), провести N шагов обучения (NInstructSteps) и прервать обучение (CloseInstruction).

7.4.1.1. Обучить сеть (InstructNet)

Описание запроса:

Pascal:

Function InstructNet : Logic;

C:

Logic InstructNet()

Аргументов нет.

Назначение – производит обучение сети.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Выполняется главная процедура загруженного учителя.

4. Если во время выполнения запроса возникает ошибка, а значение переменной Error равно нулю, то генерируется внутренняя ошибка 605 – ошибка исполнения учителя, управление передается обработчику ошибок, а обработка запроса прекращается.

5. Если во время выполнения запроса возникает ошибка, а значение переменной Error не равно нулю, то обработка запроса прекращается.

7.4.1.2. Провести N шагов обучения (NInstructSteps)

Описание запроса:

Pascal:

Function NInstructNet( N : Integer ) : Logic;

C:

Logic NInstructNet(Integer N)

Описание аргумента:

N – число выполнений блока одного шага обучения сети.

Назначение – производит обучение сети.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Выполняется блок инициации главной процедуры загруженного учителя, N раз выполняется блок одного шага обучения, выполняется блок завершения обучения.

4. Если во время выполнения запроса возникает ошибка, а значение переменной Error равно нулю, то генерируется внутренняя ошибка 605 – ошибка исполнения учителя, управление передается обработчику ошибок, а обработка запроса прекращается.

5. Если во время выполнения запроса возникает ошибка, а значение переменной Error не равно нулю, то обработка запроса прекращается.

7.4.1.3. Прервать обучение (CloseInstruction)

Описание запроса:

Pascal:

Function CloseInstruction: Logic;

C:

Logic CloseInstruction()

Аргументов нет.

Назначение – прерывает обучение сети.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Если в момент получения запроса не выполняется ни один из запросов обучить сеть (InstructNet) или провести N шагов обучения (NInstructSteps), то возникает ошибка 606 – неверное использование запроса на прерывание обучения, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Завершается выполнение текущего шага обучения сети.

5. Выполняется блок завершения обучения сети.

6. Если во время выполнения запроса возникает ошибка, а значение переменной Error равно нулю, то генерируется внутренняя ошибка 605 – ошибка исполнения учителя, управление передается обработчику ошибок, а обработка запроса прекращается.

7. Если во время выполнения запроса возникает ошибка, а значение переменной Error не равно нулю, то обработка запроса прекращается.

7.4.2. Чтение/запись учителя

В данном разделе описаны запросы, позволяющие загрузить учителя с диска или из памяти, выгрузить учителя и сохранить текущего учителя на диске или в памяти.

7.4.2.1. Прочитать учителя (inAdd)

Описание запроса:

Pascal:

Function inAdd( CompName : PString ) : Logic;

C:

Logic inAdd(PString CompName)

Описание аргумента:

CompName – указатель на строку символов, содержащую имя файла компонента или адрес описания компонента.

Назначение – читает учителя с диска или из памяти.

Описание исполнения.

1. Если в качестве аргумента CompName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя компонента и после пробела имя файла, содержащего компоненту. В противном случае считается, что аргумент CompName содержит указатель на область памяти, содержащую описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то допускается включение в текст описания компонента ключевого слова Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

2. Если в данный момент загружен другой учитель, то выполняется запрос inDelete. Учитель считывается из файла или из памяти.

3. Если считывание завершается по ошибке, то возникает ошибка 602 – ошибка считывания учителя, управление передается обработчику ошибок, а обработка запроса прекращается.

7.4.2.2. Удаление учителя (inDelete)

Описание запроса:

Pascal:

Function inDelete : Logic;

C:

Logic inDelete()

Аргументов нет.

Назначение – удаляет загруженного в память учителя.

Описание исполнения.

1. Если список в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя учителя, управление передается обработчику ошибок, а обработка запроса прекращается.

7.4.2.3. Запись компонента (inWrite)

Описание запроса:

Pascal:

Function inWrite(Var FileName : PString) : Logic;

C:

Logic inWrite(PString* FileName)

Описание аргументов:

CompName – указатель на строку символов, содержащую имя компонента.

FileName – имя файла или адрес памяти, куда надо записать компонент.

Назначение – сохраняет учителя в файле или в памяти.

Описание исполнения.

1. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

2. Если в качестве аргумента FileName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя файла для записи компонента. В противном случае FileName должен содержать пустой указатель. В этом случае запрос вернет в нем указатель на область памяти, куда будет помещено описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то в текст будет включено ключевое слово Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

3. Если во время сохранения компонента возникнет ошибка, то возникает ошибка 603 – ошибка сохранения компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

7.4.3. Инициация редактора учителя

К этой группе запросов относится запрос, который инициирует работу не рассматриваемого в данной работе компонента – редактора учителя.

7.4.3.1. Редактировать компонент (inEdit)

Описание запроса:

Pascal:

Procedure inEdit(CompName : PString);

void inEdit(PString CompName)

Описание аргумента:

CompName – указатель на строку символов – имя файла или адрес памяти, содержащие описание учителя.

Если в качестве аргумента CompName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя учителя и после пробела имя файла, содержащего описание учителя. В противном случае считается, что аргумент CompName содержит указатель на область памяти, содержащую описание учителя в формате для записи на диск. Если описание не вмещается в одну область памяти, то допускается включение в текст описания ключевого слова Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

Если в качестве аргумента CompName передан пустой указатель или указатель на пустую строку, то редактор создает нового учителя.

7.4.4. Работа с параметрами учителя

В данном разделе описаны запросы, позволяющие изменять параметры учителя.

7.4.4.1. Получить параметры (inGetData)

Описание запроса:

Pascal:

Function inGetData(Var Param : PRealArray ) : Logic;

C:

Logic inGetData(PRealArray* Param)

Описание аргумента:

Param – адрес массива параметров.

Назначение – возвращает вектор параметров учителя.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. В массив, адрес которого передан в аргументе Param, заносятся значения параметров. Параметры заносятся в массив в порядке описания в разделе описания статических переменных.

7.4.4.2. Получить имена параметров (inGetName)

Описание запроса:

Pascal:

Function inGetName(Var Param : PRealArray ) : Logic;

C:

Logic inGetName(PRealArray* Param)

Описание аргумента:

Param – адрес массива указателей на названия параметров.

Назначение – возвращает вектор указателей на названия параметров учителя.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. В массив, адрес которого передан в аргументе Param, заносятся адреса символьных строк, содержащих названия параметров.

7.4.4.3. Установить параметры (inSetData)

Описание запроса:

Pascal:

Function inSetData(Param : PRealArray ) : Logic;

C:

Logic inSetData(PRealArray Param)

Описание аргументов:

Param – адрес массива параметров.

Назначение – заменяет значения параметров учителя на значения, переданные, в аргументе Param.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса учитель не загружен, то возникает ошибка 601 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Параметры, значения которых хранятся в массиве, адрес которого передан в аргументе Param, передаются учителю.

7.4.5. Обработка ошибок

В табл. 3 приведен полный список ошибок, которые могут возникать при выполнении запросов компонентом учитель, и действия стандартного обработчика ошибок.

Таблица 3

Ошибки компонента учитель и действия стандартного обработчика ошибок.

Название ошибки

Стандартная обработка

601

Несовместимость сети и учителя

Занесение номера в Error

602

Ошибка считывания учителя

Занесение номера в Error

603

Ошибка сохранения учителя

Занесение номера в Error

604

Некорректная работа с памятью

Занесение номера в Error

605

Ошибка исполнения учителя

Занесение номера в Error

606

Неверное использование запроса на прерывание обучения

Занесение номера в Error

8. Контрастер

Компонент контрастер предназначен для контрастирования нейронных сетей. Первые работы, посвященные контрастированию (скелетонизации) нейронных сетей появились в начале девяностых годов [63, 330, 347]. Однако, задача контрастирования нейронных сетей не являлась центральной, поскольку упрощение сетей может принести реальную пользу только при реализации обученной нейронной сети в виде электронного (оптоэлектронного) устройства. Только в работе А.Н. Горбаня и Е.М. Миркеса «Логически прозрачные нейронные сети» [81] (более полный вариант работы см. [79, 82, 150]), опубликованной в 1995 году задаче контрастирования нейронных сетей был придан самостоятельный смысл – впервые появилась реальная возможность получать новые явные знания из данных. Различные вариации методов контрастирования описаны в [32, 41, 45, 63, 81, 152, 330, 347]

8.1. Задачи для контрастера

Из анализа литературы и опыта работы группы НейроКомп можно сформулировать следующие задачи, решаемые с помощью контрастирования нейронных сетей.

1. Упрощение архитектуры нейронной сети.

2. Уменьшение числа входных сигналов.

3. Сведение параметров нейронной сети к небольшому набору выделенных значений.

4. Снижение требований к точности входных сигналов.

5. Получение явных знаний из данных.

Далее в этом разделе все перечисленные выше задачи рассмотрены более подробно.

8.1.1. Упрощение архитектуры нейронной сети

Стремление к упрощению архитектуры нейронных сетей возникло из попытки ответить на следующие вопрос: «Сколько нейронов нужно использовать и как они должны быть связаны друг с другом?» При ответе на этот вопрос существует две противоположные точки зрения. Одна из них утверждает, что чем больше нейронов использовать, тем более надежная сеть получится. Сторонники этой позиции ссылаются на пример человеческого мозга. Действительно, чем больше нейронов, тем больше число связей между ними, и тем более сложные задачи способна решить нейронная сеть. Кроме того, если использовать заведомо большее число нейронов, чем необходимо для решения задачи, то нейронная сеть точно обучится. Если же начинать с небольшого числа нейронов, то сеть может оказаться неспособной обучиться решению задачи, и весь процесс придется повторять сначала с большим числом нейронов. Эта точка зрения (чем больше – тем лучше) популярна среди разработчиков нейросетевого программного обеспечения. Так, многие из них как одно из основных достоинств своих программ называют возможность использования любого числа нейронов.

 Рис. 1. Аппроксимация табличной функции

Вторая точка зрения опирается на такое «эмпирическое» правило: чем больше подгоночных параметров, тем хуже аппроксимация функции в тех областях, где ее значения были заранее неизвестны. С математической точки зрения задачи обучения нейронных сетей сводятся к продолжению функции заданной в конечном числе точек на всю область определения. При таком подходе входные данные сети считаются аргументами функции, а ответ сети – значением функции. На рис. 1 приведен пример аппроксимации табличной функции полиномами 3-й (рис. 1.а) и 7-й (рис. 1.б) степеней. Очевидно, что аппроксимация, полученная с помощью полинома 3-ей степени, больше соответствует внутреннему представлению о «правильной» аппроксимации. Несмотря на свою простоту, этот пример достаточно наглядно демонстрирует суть проблемы.

Второй подход определяет нужное число нейронов как минимально необходимое. Основным недостатком является то, что это, минимально необходимое число, заранее неизвестно, а процедура его определения путем постепенного наращивания числа нейронов весьма трудоемка. Опираясь на опыт работы группы НейроКомп в области медицинской диагностики [18, 49 – 52, 73, 93, 94, 163, 164, 168, 188 – 192, 195 – 214, 261, 300 – 302, 321, 322, 351 – 355, 361, 371], космической навигации и психологии можно отметить, что во всех этих задачах ни разу не потребовалось более нескольких десятков нейронов.

Подводя итог анализу двух крайних позиций, можно сказать следующее: сеть с минимальным числом нейронов должна лучше («правильнее», более гладко) аппроксимировать функцию, но выяснение этого минимального числа нейронов требует больших интеллектуальных затрат и экспериментов по обучению сетей. Если число нейронов избыточно, то можно получить результат с первой попытки, но существует риск построить «плохую» аппроксимацию. Истина, как всегда бывает в таких случаях, лежит посередине: нужно выбирать число нейронов большим, чем необходимо, но не намного. Это можно осуществить путем удвоения числа нейронов в сети после каждой неудачной попытки обучения. Наиболее надежным способом оценки минимального числа нейронов является использование процедуры контрастирования. Кроме того, процедура контрастирования позволяет ответить и на второй вопрос: какова должна быть структура сети.

Как уже отмечалось ранее, основная сложность в аппаратной реализации нейронных сетей – большое число связей между элементами. В связи с этим, задача уменьшения числа связей (упрощения архитектуры нейронной сети) приобретает особенную важность. Во многих приложениях, выполненных группой НейроКомп [18, 49 – 52, 73, 93, 94, 163, 164, 168, 188 – 192, 195 – 214, 261, 291, 295, 300 – 306, 321, 322, 351 – 355, 361, 371, 374] в ходе процедуры контрастирования число связей уменьшалось в 5-10 раз. Кроме того, при этом уменьшалось общее число элементов. Такое кардинальное упрощение архитектуры нейронной сети резко упрощает ее аппаратную реализацию.

Однако существует и обратный подход. Основная идея этого подхода – начинать с одного или нескольких нейронов, а потом, по мере необходимости, наращивать их число (см., например, [24 – 26]). К сожалению, эффективные алгоритмы наращивания существуют только для сетей, решающих некоторые конкретные задачи.

8.1.2. Уменьшение числа входных сигналов

При постановке задачи для нейронной сети не всегда удается точно определить сколько и каких входных данных нужно подавать на вход. В случае недостатка данных сеть не сможет обучиться решению задачи. Однако гораздо чаще на вход сети подается избыточный набор входных параметров. Например, при обучении сети постановке диагноза в задачах медицинской диагностики на вход сети подаются все данные, необходимые для постановки диагноза в соответствии с существующими методиками. Следует учесть, что стандартные методики постановки диагнозов разрабатываются для использования на большой территории (например, на территории России). Как правило, при диагностике заболеваний населения какого-нибудь небольшого региона (например города) можно обойтись меньшим набором исходных данных. Причем этот усеченный набор будет варьироваться от одного малого региона к другому. Требуется определить, какие данные необходимы для решения конкретной задачи, поставленной для нейронной сети. Кроме того, в ходе решения этой задачи определяются значимости входных сигналов. Следует заметить, что умение определять значимость входных сигналов представляет самостоятельную ценность.

8.1.3. Сведение параметров нейронной сети к выделенным значениям

При обучении нейронных сетей на универсальных компьютерах параметры сети являются действительными числами из заданного диапазона. При аппаратной реализации нейронной сети не всегда возможно реализовать веса связей с высокой точностью (в компьютерном представлении действительных чисел хранятся первые 6-7 цифр мантиссы). Опыт показывает, что в обученной сети веса многих синапсов можно изменять в довольно широком диапазоне (до полуширины интервала изменения веса) не изменяя качество решения сетью поставленной перед ней задачи. Исходя из этого, умение решать задачу замены значений параметров сети на значения из заданного набора приобретает важный практический смысл.

8.1.4. Снижение требований к точности входных сигналов

При обработке экспериментальных данных полезно знать, что измерение с высокой точностью, как правило, дороже измерения с низкой точностью. Причем достаточно часто получение очередной значащей цифры измеряемого параметра стоит на несколько порядков дороже. В связи с этим задача снижения требований к точности измерения входных параметров сети приобретает смысл. Первые работы, в которых рассматриваются методы решения данной задачи – [132 – 135].

8.1.5. Получение явных знаний из данных

Одной из главных загадок мышления является то, как из совокупности данных об объекте, появляется знание о нем. До недавнего времени наибольшим достижением в области искусственного интеллекта являлось либо воспроизведение логики человека-эксперта (классические экспертные системы), либо построение регрессионных зависимостей и определение степени зависимости одних параметров от других.

С другой стороны, одним из основных недостатков нейронных сетей, с точки зрения многих пользователей, является то, что нейронная сеть решает задачу, но не может рассказать как. Иными словами из обученной нейронной сети нельзя извлечь алгоритм решения задачи. Таким образом, нейронные сети позволяют получать неявные знания из данных.

В домашнем задании I Всесоюзной олимпиады по нейрокомпьютингу, проходившей в мае 1991 года в городе Омске, в исследовательской задаче участникам было предложено определить, как нейронная сеть решает задачу распознавания пяти первых букв латинского алфавита (полный текст задания и наиболее интересные варианты решения приведены в [171]). Это была первая попытка извлечения алгоритма решения задачи из обученной нейронной сети.

В 1995 году была сформулирована идея логически прозрачных сетей, то есть сетей, на основе структуры которых можно построить вербальное описание алгоритма получения ответа. Это достигается при помощи специальным образом построенной процедуры контрастирования.

Получение явных знаний из данных позволяет решить часть проблем, встающих перед разработчиками экспертных систем [101, 124, 125, 178, 223, 241, 250, 282, 364, 375].

В приложении 1 приведен пример логически прозрачной нейронной сети для реальной задачи – постановки диагноза заболевания шизофренией.

8.1.5.1. Построение логически прозрачных сетей

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

Зададимся нейронной сетью у которой все входные сигналы подаются на все нейроны входного слоя, а все нейроны каждого следующего слоя принимают выходные сигналы всех нейронов предыдущего слоя. Обучим сеть безошибочному решению задачи.

После этого будем производить контрастирование в несколько этапов. На первом этапе будем удалять только входные связи нейронов входного слоя. Если после этого у некоторых нейронов осталось больше трех входных сигналов, то увеличим число входных нейронов. Затем аналогичную процедуру выполним поочередно для всех остальных слоев. После завершения описанной процедуры будет получена логически прозрачная сеть. Можно произвести дополнительное контрастирование сети, чтобы получить минимальную сеть. На рис. 2 приведены восемь минимальных сетей. Если под логически прозрачными сетями понимать сети, у которых каждый нейрон имеет не более трех входов, то все сети кроме пятой и седьмой являются логически прозрачными. Пятая и седьмая сети демонстрируют тот факт, что минимальность сети не влечет за собой логической прозрачности.

8.1.5.2. Получение явных знаний

Рис. 2. Набор минимальных сетей для решения задачи о предсказании результатов выборов президента США. В рисунке использованы следующие обозначения: буквы «П» и «О» – обозначают вид ответа, выдаваемый нейроном: «П» – положительный сигнал означает победу правящей партии, а отрицательный – оппозиционной; «О» – положительный сигнал означает победу оппозиционной партии, а отрицательный – правящей;

 

После получения логически прозрачной нейронной сети наступает этап построения вербального описания. Принцип построения вербального описания достаточно прост. Используемая терминология заимствована из медицины. Входные сигналы будем называть симптомами. Выходные сигналы нейронов первого слоя – синдромами первого уровня. Очевидно, что синдромы первого уровня строятся из симптомов. Выходные сигналы нейронов k-о слоя будем называть синдромами k-о уровня. Синдромы k-о первого уровня строятся из симптомов и синдромов более низких уровней. Синдром последнего уровня является ответом.

В качестве примера приведем интерпретацию алгоритма рассуждений, полученного по второй сети приведенной на рис. 2. Постановка задачи: по ответам на 12 вопросов необходимо предсказать победу правящей или оппозиционной партии на выборах Президента США. Ниже приведен список вопросов.

1. Правящая партия была у власти более одного срока?

2. Правящая партия получила больше 50% голосов на прошлых выборах?

3. В год выборов была активна третья партия?

4. Была серьезная конкуренция при выдвижении от правящей партии?

5. Кандидат от правящей партии был президентом в год выборов?

6. Год выборов был временем спада или депрессии?

7. Был ли рост среднего национального валового продукта на душу населения больше 2.1%?

8. Произвел ли правящий президент существенные изменения в политике?

9. Во время правления были существенные социальные волнения?

10. Администрация правящей партии виновна в серьезной ошибке или скандале?

11. Кандидат от правящей партии – национальный герой?

12. Кандидат от оппозиционной партии – национальный герой?

Ответы на вопросы описывают ситуацию на момент, предшествующий выборам. Ответы кодировались следующим образом: «да» – единица, «нет» – минус единица. Отрицательный сигнал на выходе сети интерпретируется как предсказание победы правящей партии. В противном случае, ответом считается победа оппозиционной партии. Все нейроны реализовывали пороговую функцию, равную 1, если алгебраическая сумма входных сигналов нейрона больше либо равна 0, и -1 при сумме меньшей 0.

Проведем поэтапно построение вербального описания второй сети, приведенной на рис. 2. После автоматического построения вербального описания получим текст, приведенный на рис. 3. Заменим все симптомы на тексты соответствующих вопросов. Заменим формулировку восьмого вопроса на обратную. Подставим вместо Синдром1_Уровня2 название ответа сети при выходном сигнале 1. Текст, полученный в результате этих преобразований приведен на рис. 4.

Синдром1_Уровня1 равен 1, если выражение Симптом4 + Симптом6 – Симптом 8 больше либо равно нулю, и –1 – в противном случае.

Синдром2_Уровня1 равен 1, если выражение Симптом3 + Симптом4 + Симптом9 больше либо равно нулю, и –1 – в противном случае.

Синдром1_Уровня2 равен 1, если выражение Синдром1_Уровня1 + Синдром2_Уровня1 больше либо равно нулю, и –1 – в противном случае.

Рис. 3. Автоматически построенное вербальное описание

Синдром1_Уровня1 равен 1, если выражение «Была серьезная конкуренция при выдвижении от правящей партии?» + «Год выборов был временем спада или депрессии?» + «Правящий президент не произвел существенных изменений в политике?» больше либо равно нулю, и –1 – в противном случае.

Синдром2_Уровня1 равен 1, если выражение «В год выборов была активна третья партия?» + «Была серьезная конкуренция при выдвижении от правящей партии?» + «Во время правления были существенные социальные волнения?» больше либо равно нулю, и –1 – в противном случае.

Оппозиционная партия победит, если выражение Синдром1_Уровня1 + Синдром2_Уровня1 больше либо равно нулю.

Рис. 4. Вербальное описание после элементарных преобразований

Заметим, что все три вопроса, ответы на которые формируют Синдром1_Уровня1, относятся к оценке качества правления действующего президента. Поскольку положительный ответ на любой из этих вопросов характеризует недостатки правления, то этот синдром можно назвать синдромом плохой политики. Аналогично, три вопроса, ответы на которые формируют Синдром2_Уровня1, относятся к характеристике политической стабильности. Этот синдром назовем синдромом политической нестабильности.

Тот факт, что оба синдрома первого уровня принимают значение 1, если истинны ответы хотя бы на два из трех вопросов, позволяет избавиться от математических действий с ответами на вопросы. Окончательный ответ может быть истинным только если оба синдрома имеют значение –1.

Используя приведенные соображения, получаем окончательный текст решения задачи о предсказании результатов выборов президента США, приведенный на рис. 5.

Таким образом, использовав идею логически прозрачных нейронных сетей и минимальные интеллектуальные затраты на этапе доводки вербального описания, был получен текст решения задачи. Причем процедура получения логически прозрачных нейронных сетей сама отобрала значимые признаки, сама привела сеть к нужному виду. Далее элементарная программа построила по структуре сети вербальное описание.

Правление плохое, если верны хотя бы два из следующих высказываний: «Была серьезная конкуренция при выдвижении от правящей партии», «Год выборов был временем спада или депрессии», «Правящий президент не произвел существенных изменений в политике».

Ситуация политически нестабильна, если верны хотя бы два из следующих высказываний: «В год выборов была активна третья партия», «Была серьезная конкуренция при выдвижении от правящей партии», «Во время правления были существенные социальные волнения».

Оппозиционная партия победит, если правление плохое или ситуация политически нестабильна.

Рис. 5. Окончательный вариант вербального описания

На рис. 2 приведены структуры шести логически прозрачных нейронных сетей, решающих задачу о предсказании результатов выборов президента США [303 – 305]. Все сети, приведенные на этом рисунке минимальны в том смысле, что из них нельзя удалить ни одной связи так, чтобы сеть могла обучиться правильно решать задачу. По числу нейронов минимальна пятая сеть.

Заметим, что все попытки авторов обучить нейронные сети со структурами, изображенными на рис. 2, и случайно сгенерированными начальными весами связей закончились провалом. Все сети, приведенные на рис. 2, были получены из существенно больших сетей с помощью процедуры контрастирования. Сети 1, 2, 3 и 4 были получены из трехслойных сетей с десятью нейронами во входном и скрытом слоях. Сети 5, 6, 7 и 8 были получены из двухслойных сетей с десятью нейронами во входном слое. Легко заметить, что в сетях 2, 3, 4 и 5 изменилось не только число нейронов в слоях, но и число слоев. Кроме того, почти все веса связей во всех восьми сетях равны либо 1, либо -1.

8.2. Множества повышенной надежности

Алгоритмы контрастирования, рассматриваемые в данной главе, позволяют выделить минимально необходимое множество входных сигналов. Использование минимального набора входных сигналов позволяет более экономично организовать работу нейркомпьютера. Однако у минимального множества есть свои недостатки. Поскольку множество минимально, то информация, несомая одним из сигналов, как правило не подкрепляется другими входными сигналами. Это приводит к тому, что при ошибке в одном входном сигнале сеть ошибается с большой степенью вероятности. При избыточном наборе входных сигналов этого, как правило, не происходит, поскольку информация каждого сигнала подкрепляется (дублируется) другими сигналами [72].

Таким образом возникает противоречие – использование исходного избыточного множества сигналов неэкономично, а использование минимального набора сигналов приводит к повышению риска ошибок. В этой ситуации правильным является компромиссное решение – необходимо найти такое минимальное множество, в котором вся информация дублируется. В данном разделе рассматриваются методы построения таких множеств, повышенной надежности. Кроме того, построение дублей второго рода позволяет установить какие из входных сигналов не имеют дублей в исходном множестве сигналов. Попадание такого «уникального» сигнала в минимальное множество является сигналом о том, что при использовании нейронной сети для решения данной задачи следует внимательно следить за правильностью значения этого сигнала.

8.2.1. Формальная постановка задачи

Пусть дана таблица данных, содержащая N записей, каждая из которых содержит M+1 поле. Обозначим значение i-о поля j-й записи через, где , . Обозначим через  задачник, в котором ответы заданы в полях с номерами , а входные данные содержатся в полях с номерами .  Множество А будем называть множеством ответов, а множество S – множеством входных данных. Минимальное множество входных сигналов, полученное при обучении сети на задачнике , обозначим через . В случае, когда сеть не удалось обучить решению задачи будем считать, что . Число элементов в множестве A будем обозначать через . Через  будем обозначать сеть, обученную решать задачу предсказания всех полей (ответов), номера которых содержатся в множестве A, на основе входных сигналов, номера которых содержатся в множестве S.

Задача. Необходимо построить набор входных параметров, который позволяет надежно решать задачу .

Решение задачи будем называть множеством повышенной надежности, и обозачать .

Для решения этой задачи необходимо определит набор параметров, дублирующих минимальный набор . Возможно несколько подходов к определению дублирующего набора. В следующих разделах рассмотрены некоторые из них.

8.2.2. Классификация дублей

Возможно два типа дублей – набор входных сигналов, способный заменить определенный входной сигнал или множество сигналов при получении ответа первоначальной задачи, и набор входных сигналов, позволяющий вычислить дублируемый сигнал (множество дублируемых сигналов). Дубли первого типа будем называть прямыми, а дубли второго типа – косвенными.

Возможна другая классификация, не зависящая от ранее рассмотренной. Дубли первого и второго рода будем различать по объекту дублирования. Дубль первого рода дублирует все множество вцелом, а дубль второго рода дублирует конкретный сигнал.

Очевидно, что возможны все четыре варианта дублей: прямой первого рода, косвенный первого рода, прямой второго рода и косвенный второго рода. В следующих разделах будут описаны алгоритмы получения дублей всех вышеперечисленных видов.

8.2.3. Прямой дубль первого рода

Для нахождения прямого дубля первого рода требуется найти такое множество сигналов D что существует сеть  и . Решение этой задачи очевидно. Удалим из множества входных сигналов те их них, которые вошли в первоначальное минимальное множество входных сигналов .  Найдем минимальное множество входных сигналов среди оставшихся. Найденное множество и будет искомым дублем.

Формально описанную выше процедуру можно записать следующей формулой:

.

Множество повышенной надежности в этом случае можно записать в следующем виде:

.

Очевидно, что последнюю формулу можно обобщить, исключив из первоначального множества входных сигналов найденное ранее множество повышенной надежности и попытавшись найти минимальное множество среди оставшихся входных сигналов. С другой стороны, для многих нейросетевых задач прямых дублей первого рода не существует. Примером может служить одна из классических тестовых задач – задача о предсказании результатов выборов президента США.

8.2.4. Косвенный дубль первого рода

Для нахождения косвенного дубля первого рода необходимо найти такое множество входных сигналов D что существует сеть  и . Другими словами, среди множества входных сигналов, не включающем начальное минимальное множество, нужно найти такие входные сигналы, по которым можно восстановит значения входных сигналов начального минимального множества. Формально описанную выше процедуру можно записать следующей формулой:

.

Множество повышенной надежности в этом случае можно записать в следующем виде:

Эта формула так же допускает обобщение. Однако, следует заметить, что косвенные дубли первого рода встречаются еще реже чем прямые дубли первого рода. Соотношение между косвенным и прямым дублем первого рода описываются следующей теоремой.

Теорема 1. Если множество D является косвенным дублем первого рода, то оно является и прямым дублем первого рода.

Доказательство. Построим нейронную сеть, состоящую из последовательно соединенных сетей   и , как показано на рис. 6. Очевидно, что на выходе первой сети будут получены те сигналы, которые, будучи поданы на вход второй сети, приведут к получению на выходе второй сети правильного ответа. Таким образом сеть, полученная в результате объединения двух сетей  и , является сетью . Что и требовалось доказать.

Рис. 6. Сеть для получения ответа из косвенного дубля.

Следствие. Если у множества  нет прямого дубля первого рода, то у нее нет и косвенного дубля первого рода

Доказательство. Пусть  это не так. Тогда существует косвенный дубль первого рода. Но по теореме 1 он является и прямым дублем первого рода, что противоречит условию теоремы. Полученное противоречие доказывает следствие.

8.2.5. Прямой дубль второго рода

Перенумеруем входные сигналы из множества . Множество сигналов, являющееся прямым дублем второго рода для сигнала  можно получить найдя минимальное множество для получения ответа, если из исходного множества входных сигналов исключен сигнал . Таким образом прямые дубли второго рода получаются следующим образом:

.

Полный прямой дубль второго рода получается объединением всех дублей для отдельных сигналов . Множество повышенной надежности для прямого дубля второго рода можно записать в следующем виде:

Заметим, что при построении прямого дубля второго рода не требовалось отсутствия в нем всех элементов множества , как это было при построении прямого дубля первого рода.  Такое снижение требований приводит к тому, что прямые дубли второго рода встречаются чаще, чем прямые дубли первого рода. Более того, прямой дубль первого рода очевидно является прямым дублем второго рода. Более точное соотношение между прямыми дублями первого и второго родов дает следующая теорема.

Теорема 2. Полный прямой дубль второго рода является прямым дублем первого рода тогда, и только тогда, когда

.                      (1)

Доказательство. Построим сеть, состоящую из параллельно работающих сетей, , за которыми следует элемент, выдающтй на выход среднее арифметическое своих входов. Такая сеть очевидно будет решать задачу, а в силу соотношения (1) она будет сетью . Таким образом, если соотношение (1) верно, то прямой дубль второго рода является прямым дублем первого рода. Необходимость следует непосредственно из определения прямого дубля первого рода.

8.2.6. Косвенный дубль второго рода

Косвенный дубль второго рода для сигнала  является минимальным множеством входных сигналов, для которых существует сеть . Полный косвенный дубль второго рода строится как объединение косвенных дублей второго рода для всех сигналов первоначального минимального множества:

.

Соотношения между косвенными дублями второго рода и другими видами дублей первого и второго рода задаются теоремами 1, 2 и следующими двумя теоремами.

Теорема 3. Косвенный дубль второго рода всегда является прямым дублем второго рода.

Доказательство данной теоремы полностью аналогично доказательству теоремы 1.

Теорема 4. Полный косвенный дубль второго рода является косвенным дублем первого рода тогда, и только тогда, когда верно соотношение

Доказателство данной теоремы полностью аналогично доказательству теоремы 2.

8.2.7. Косвенный супердубль

Последним рассматриваемым в данной работе видом дубля является косвенный супердубль. Косвенным супердублем будем называть минимальное множество входных сигналов, которое позволяет восстановит все входные сигналы. Косвенный супердубль формально описывается следующей формулой:

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

8.3. Процедура контрастирования

Существует два типа процедуры контрастирования – контрастирование по значимости параметров и не ухудшающее контрастирование. В данном разделе описаны оба типа процедуры контрастирования.

8.3.1. Контрастирование на основе показателей значимости

С помощью этой процедуры можно контрастировать, как входные сигналы, так и параметры сети. Далее в данном разделе будем предполагать, что контрастируются параметры сети. При контрастировании входных сигналов процедура остается той же, но вместо показателей значимости параметров сети используются показатели значимости входных сигналов. Обозначим через  –  показатель значимости p-о параметра; через  – текущее значение p-о параметра; через  – ближайшее выделенное значение для p-о параметра.

Используя введенные обозначения процедуру контрастирования можно записать следующим образом:

1. Вычисляем показатели значимости.

2. Находим минимальный среди показателей значимости – .

3. Заменим соответствующий этому показателю значимости параметр  на , и исключаем его из процедуры обучения.

4. Предъявим сети все примеры обучающего множества. Если сеть не допустила ни одной ошибки, то переходим ко второму шагу процедуры.

5. Пытаемся обучить полученную сеть. Если сеть обучилась безошибочному решению задачи, то переходим к первому шагу процедуры, в противном случае переходим к шестому шагу.

6. Восстанавливаем сеть в состояние до последнего выполнения третьего шага. Если в ходе выполнения шагов со второго по пятый был отконтрастирован хотя бы один параметр, (число обучаемых параметров изменилось), то переходим к первому шагу. Если ни один параметр не был отконтрастирован, то получена минимальная сеть.

Возможно использование различных обобщений этой процедуры. Например, контрастировать за один шаг процедуры не один параметр, а заданное пользователем число параметров. Наиболее радикальная процедура состоит в контрастировании половины параметров связей. Если контрастирование половины параметров не удается, то пытаемся контрастировать четверть и т.д. Другие варианты обобщения процедуры контрастирования будут описаны при описании решения задач. Результаты первых работ по контрастированию нейронных сетей с помощью описанной процедуры опубликованы в [171, 306, 307].

8.3.2. Контрастирование без ухудшения

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

Обозначим через  p-й входной сигнал сумматора при решении q-о примера; через  – выходной сигнал сумматора при решении q-о примера; через  – вес p-о входного сигнала сумматора; через  – требуемую точность; через n – число входных сигналов сумматора; через m – число примеров. Очевидно, что при решении примера выполняется равенство . Требуется найти такой набор индексов , что , где  – новый вес p-о входного сигнала сумматора. Набор индексов будем строить по следующему алгоритму.

1. Положим , , , , k=0.

2. Для всех векторов  таких, что , проделаем следующее преобразование: если , то исключаем p из множества обрабатываемых векторов – , в противном случае нормируем вектор  на единичную длину – .

3. Если  или , то переходим к шагу 10.

4. Находим  – номер вектора, наиболее близкого к  из условия

.

5. Исключаем  из множества индексов обрабатываемых векторов: .

6. Добавляем  в множество индексов найденных векторов:

7. Вычисляем не аппроксимированную часть (ошибку аппроксимации) вектора выходных сигналов:

8. Преобразуем обрабатываемые вектора к промежуточному представлению – ортогонализуем их к вектору , для чего каждый вектор , у которого  преобразуем по следующей формуле: .

9. Увеличиваем k на единицу и переходим к шагу 2.

10. Если , то весь сумматор удаляется из сети и работа алгоритма завершается.

11. Если , то контрастирование невозможно и сумматор остается неизменным.

12. В противном случае полагаем и вычисляем новые веса связей () решая систему уравнений .

13. Удаляем из сети связи с номерами , веса оставшихся связей полагаем равными ().

Данная процедура позволяет производить контрастирование адаптивных сумматоров. Причем значения, вычисляемые каждым сумматором после контрастирования, отличаются от исходных не более чем на заданную величину. Однако, исходно была задана только максимально допустимая погрешность работы сети в целом. Способы получения допустимых погрешностей для отдельных сумматоров исходя из заданной допустимой погрешности для всей сети описаны в ряде работ [97, 98, 170, 215 – 219, 362].

8.3.3. Гибридная процедура контрастирования

Можно упростить процедуру контрастирования, описанную в разд. «Контрастирование без ухудшения». Предлагаемая процедура годится только для контрастирования весов связей адаптивного сумматора (см. разд. «Составные элементы»). Контрастирование весов связей производится отдельно для каждого сумматора. Адаптивный сумматор суммирует входные сигналы нейрона, умноженные на соответствующие веса связей. Для работы нейрона наименее значимым будем считать тот вес, который при решении примера даст наименьший вклад в сумму. Обозначим через  входные сигналы рассматриваемого адаптивного сумматора при решении q-го примера. Показателем значимости веса назовем следующую величину: . Усредненный по всем примерам обучающего множества показатель значимости имеет вид . Производим контрастирование по процедуре, приведенной в разд. «Контрастирование на основе показателей значимости». В самой процедуре контрастирования есть только одно отличие – вместо проверки на наличие ошибок при предъявлении всех примеров проверяется, что новые выходные сигналы сети отличаются от первоначальных не более чем на заданную величину.

8.3.4. Контрастирование при обучении

Существует еще один способ контрастирования нейронных сетей. Идея этого способа состоит в том, что функция оценки модернизируется таким способом, чтобы для снижения оценки было выгодно привести сеть к заданному виду. Рассмотрим решение задачи приведения параметров сети к выделенным значениям. Используя обозначения из предыдущих разделов требуемую добавку к функции оценки, являющуюся штрафом за отклонение значения параметра от ближайшего выделенного значения:, можно записать в виде .

Для решения других задач вид добавок к функции оценки много сложнее.

8.4. Определение показателей значимости

В данном разделе описан способ определения показателей значимости параметров и сигналов. . Далее будем говорить об определении значимости параметров. Показатели значимости сигналов сети определяются по тем же формулам с заменой параметров на сигналы.

8.4.1. Определение показателей значимости через градиент

Нейронная сеть двойственного функционирования может вычислять градиент функции оценки по входным сигналам и обучаемым параметрам сети

Показателем значимости параметра при решении q-о примера будем называть величину, которая показывает насколько изменится значение функции оценки решения сетью q-о примера если текущее значение параметра  заменить на выделенное значение . Точно эту величину можно определить произведя замену и вычислив оценку сети. Однако учитывая большое число параметров сети вычисление показателей значимости для всех параметров будет занимать много времени. Для ускорения процедуры оценки параметров значимости вместо точных значений используют различные оценки [32, 65, 93]. Рассмотрим простейшую и наиболее используемую линейную оценку показателей значимости. Разложим функцию оценки в ряд Тейлора с точностью до членов первого порядка: ,где  – значение функции оценки решения q-о примера при . Таким образом показатель значимости p-о параметра при решении q-о примера определяется по следующей формуле:

                                         (2)

Показатель значимости (2) может вычисляться для различных объектов. Наиболее часто его вычисляют для обучаемых параметров сети. Однако показатель значимости вида (2) применим и для сигналов. Как уже отмечалось в главе «Описание нейронных сетей» сеть при обратном функционировании всегда вычисляет два вектора градиента – градиент функции оценки по обучаемым параметрам сети и по всем сигналам сети. Если показатель значимости вычисляется для выявления наименее значимого нейрона, то следует вычислять показатель значимости выходного сигнала нейрона. Аналогично, в задаче определения наименее значимого входного сигнала нужно вычислять значимость этого сигнала, а не сумму значимостей весов связей, на которые этот сигнал подается.

8.4.2. Усреднение по обучающему множеству

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

.                                              (3)

В рамках другого подхода обучающее множество рассматривают как случайную выборку в пространстве входных параметров. В этом случае показателем значимости по всему обучающему множеству будет служить результат некоторого усреднения по обучающей выборке.

Существует множество способов усреднения. Рассмотрим два из них. Если в результате усреднения показатель значимости должен давать среднюю значимость, то такой показатель вычисляется по следующей формуле:

.                                         (4)

Если в результате усреднения показатель значимости должен давать величину, которую не превосходят показатели значимости по отдельным примерам (значимость этого параметра по отдельному примеру не больше чем ), то такой показатель вычисляется по следующей формуле:

.                                           (5)

Показатель значимости (5) хорошо зарекомендовал себя при использовании в работах группы НейроКомп.

8.4.3. Накопление показателей значимости

Все показатели значимости зависят от точки в пространстве параметров сети, в которой они вычислены, и могут сильно изменяться при переходе от одной точки к другой. Для показателей значимости, вычисленных с использованием градиента эта зависимость еще сильнее, поскольку при обучении по методу наискорейшего спуска (см. раздел «Метод наискорейшего спуска») в двух соседних точках пространства параметров, в которых вычислялся градиент, градиенты ортогональны. Для снятия зависимости от точки пространства используются показатели значимости, вычисленные в нескольких точках. Далее они усредняются по формулам аналогичным (4) и (5). Вопрос о выборе точек в пространстве параметров в которых вычислять показатели значимости обычно решается просто. В ходе нескольких шагов обучения по любому из градиентных методов при каждом вычислении градиента вычисляются и показатели значимости. Число шагов обучения, в ходе которых накапливаются показатели значимости, должно быть не слишком большим, поскольку при большом числе  шагов обучения первые вычисленные показатели значимости теряют смысл, особенно при использовании усреднения по формуле (5).

8.5. Запросы к компоненту контрастер

Компонента контрастер одновременно работает только с одним контрастером. Запросы к компоненте контрастер можно разбить на следующие группы.

1. Контрастирование сети.

2. Чтение/запись контрастера.

3. Инициация редактора контрастера.

4. Работа с параметрами контрастера.

8.5.1. Контрастирование сети

К данной группе относятся три запроса – контрастировать сеть (ContrastNet), прервать контрастирование (CloseContrast) и контрастировать пример (ContrastExample).

8.5.1.1. Контрастировать сеть(ContrastNet)

Описание запроса:

Pascal:

Function ContrastNet: Logic;

C:

Logic ContrastNet()

Аргументов нет.

Назначение – производит контрастирование сети.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса контрастер не загружен, то возникает ошибка 701 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Выполняется главная процедура загруженного контрастера.

4. Если во время выполнения запроса возникает ошибка, а значение переменной Error равно нулю, то генерируется внутренняя ошибка 705 – ошибка исполнения контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

5. Если во время выполнения запроса возникает ошибка, а значение переменной Error не равно нулю, то обработка запроса прекращается.

8.5.1.2. Прервать контрастирование (CloseContrast)

Описание запроса:

Pascal:

Function CloseContrast: Logic;

C:

Logic CloseContrast()

Аргументов нет.

Назначение – прерывает контрастирование сети.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса контрастер не загружен, то возникает ошибка 701 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. Если в момент получения запроса не выполняется запрос ContrastNet, то возникает ошибка 706 – неверное использование запроса на прерывание контрастирования, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Завершается выполнение текущего шага контрастирования сети.

5. Если во время выполнения запроса возникает ошибка, а значение переменной Error равно нулю, то генерируется внутренняя ошибка 705 – ошибка исполнения контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

6. Если во время выполнения запроса возникает ошибка, а значение переменной Error не равно нулю, то обработка запроса прекращается.

8.5.1.3. Контрастировать пример (ContrastExample)

Описание запроса:

Pascal:

Function ContrastExample( TheEnd : Logic) : Logic;

C:

Logic ContrastExample(Logic TheEnd )

Описание аргумента:

TheEnd – значение аргумента имеет следующий смысл: ложь – обработан еще один пример обучающего множества при обучении по всему задачнику в целом.

Назначение – извлекает из сети необходимые для вычисления показателей значимости параметры.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Вызывает функцию, адрес которой хранится в переменной ContrastFunc, передавая ей аргумент TheEnd в качестве аргумента.

3. Если функция ContrastFunc возвращает значение ложь, а значение переменной Error равно нулю, то генерируется внутренняя ошибка 705 – ошибка исполнения контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

4. Если функция ContrastFunc возвращает значение ложь, а значение переменной Error не равно нулю, то обработка запроса прекращается.

5. Запрос в качестве результата возвращает возвращенное функцией ContrastFunc значение.

8.5.2. Чтение/запись контрастера

В данном разделе описаны запросы позволяющие, загрузить контрастер с диска или из памяти, выгрузить контрастера и сохранить текущего контрастера на диске или в памяти.

8.5.2.1. Прочитать контрастера (cnAdd)

Описание запроса:

Pascal:

Function cnAdd( CompName : PString ) : Logic;

C:

Logic cnAdd(PString CompName)

Описание аргумента:

CompName – указатель на строку символов, содержащую имя файла компонента или адрес описания компонента.

Назначение – читает контрастера с диска или из памяти.

Описание исполнения.

1. Если в качестве аргумента CompName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя компонента и после пробела имя файла, содержащего компонент. В противном случае считается, что аргумент CompName содержит указатель на область памяти, содержащую описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то допускается включение в текст описания компонента ключевого слова Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

2. Если в данный момент загружен другой контрастер, то выполняется запрос cnDelete. Контрастер считывается из файла или из памяти.

3. Если считывание завершается по ошибке, то возникает ошибка 702 – ошибка считывания контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

8.5.2.2. Удаление контрастера (cnDelete)

Описание запроса:

Pascal:

Function cnDelete : Logic;

C:

Logic cnDelete()

Аргументов нет.

Назначение – удаляет загруженного в память контрастера.

Описание исполнения.

1. Если список в момент получения запроса контрастер не загружен, то возникает ошибка 701 – неверное имя контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

8.5.2.3. Запись контрастера (cnWrite)

Описание запроса:

Pascal:

Function cnWrite(Var FileName : PString) : Logic;

C:

Logic cnWrite(PString* FileName)

Описание аргументов:

CompName – указатель на строку символов, содержащую имя контрастера.

FileName – имя файла или адрес памяти, куда надо записать контрастера.

Назначение – сохраняет контрастера в файле или в памяти.

Описание исполнения.

1. Если в момент получения запроса контрастер не загружен, то возникает ошибка 701 – неверное имя контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

2. Если в качестве аргумента FileName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя файла, для записи компонента. В противном случае FileName должен содержать пустой указатель. В этом случае запрос вернет в нем указатель на область памяти, куда будет помещено описание компонента в формате для записи на диск. Если описание не вмещается в одну область памяти, то в текст будет включено ключевое слово Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

3. Если во время сохранения компонента возникнет ошибка, то возникает ошибка 703 – ошибка сохранения контрастера, управление передается обработчику ошибок, а обработка запроса прекращается.

8.5.3. Инициация редактора контрастера

К этой группе запросов относится запрос, который инициирует работу не рассматриваемого в данной работе компонента – редактора контрастера.

8.5.3.1. Редактировать контрастера (cnEdit)

Описание запроса:

Pascal:

Procedure cnEdit(CompName : PString);

C:

void cnEdit(PString CompName)

Описание аргумента:

CompName – указатель на строку символов – имя файла или адрес памяти, содержащие описание контрастера.

Если в качестве аргумента CompName дана строка, первые четыре символа которой составляют слово File, то остальная часть строки содержит имя контрастера и после пробела имя файла, содержащего описание контрастера. В противном случае считается, что аргумент CompName содержит указатель на область памяти, содержащую описание контрастера в формате для записи на диск. Если описание не вмещается в одну область памяти, то допускается включение в текст описания ключевого слова Continue, за которым следует четыре байта, содержащие адрес следующей области памяти.

Если в качестве аргумента CompName передан пустой указатель или указатель на пустую строку, то редактор создает нового контрастера.

8.5.4. Работа с параметрами контрастера

В данном разделе описаны запросы, позволяющие изменять параметры контрастера.

8.5.4.1. Получить параметры (cnGetData)

Описание запроса:

Pascal:

Function cnGetData(Var Param : PRealArray ) : Logic;

C:

Logic cnGetData(PRealArray* Param)

Описание аргумента:

Param – адрес массива параметров.

Назначение – возвращает вектор параметров контрастера.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса контрастер не загружен, то возникает ошибка 701 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. В массив, адрес которого передан в аргументе Param, заносятся значения параметров. Параметры заносятся в массив в порядке описания в разделе описания статических переменных.

8.5.4.2. Получить имена параметров (cnGetName)

Описание запроса:

Pascal:

Function cnGetName(Var Param : PRealArray ) : Logic;

C:

Logic cnGetName(PRealArray* Param)

Описание аргумента:

Param – адрес массива указателей на названия параметров.

Назначение – возвращает вектор указателей на названия параметров контрастера.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса контрастер не загружен, то возникает ошибка 701 – неверное имя компонента, управление передается обработчику ошибок, а обработка запроса прекращается.

3. В массив, адрес которого передан в аргументе Param, заносятся адреса символьных строк, содержащих названия параметров.

8.5.4.3. Установить параметры (cnSetData)

Описание запроса:

Pascal:

Function cnSetData(Param : PRealArray ) : Logic;

C:

Logic cnSetData(PRealArray Param)

Описание аргументов:

Param – адрес массива параметров.

Назначение – заменяет значения параметров контрастера на значения, переданные, в аргументе Param.

Описание исполнения.

1. Если Error <> 0, то выполнение запроса прекращается.

2. Если в момент получения запроса контрастер не загружен, то возникает ошибка 701 – невер