Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Журнал(производственная практика) 3 курс.doc
Скачиваний:
40
Добавлен:
16.03.2015
Размер:
2.98 Mб
Скачать
  1. Отчет по прОизводствеНной практике

    1. Использование RBF-сети в качестве аппроксиматора

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

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

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

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

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

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

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

Простейшая радиальная нейронная сеть радиального типа функционирует по принципу многомерной интерполяции, состоящей в отображении pразличных входных векторовxi (i = 1, 2, …, p)из входногоN-мерного пространства во множество изpрациональных чиселdi (i = 1, 2. …, p). Для реализации этого процесса необходимо использоватьpскрытых нейронов радиального типа и задать такую функцию отображенияF(x), для которой выполняется условие интерполяции

.

(4.1)

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

,

(4.2)

где K < p, аci (i= 1, 2, …, K)– множество центров, которые необходимо определить. В особом случае, если принятьK = p, то можно получить точное решениеci = xi.

Задача аппроксимации состоит в подборе соответствующего количества радиальных функций и их параметров, а также в таком подборе весовwi (i=1, 2, …, K), чтобы решение уравнения (4.2) было наиболее близким к точному. Поэтому проблему подбора параметров радиальных функций и значений весовwiсети можно свести к минимизации целевой функции, которая при использовании метрики Евклида записывается в форме

,

(4.3)

В этом уравнении Kпредставляет количество радиальных нейронов, аp – количество обучающих пар(xi, di), гдеxi– это входной вектор, аdi– соответствующая ему ожидаемая величина.

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

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

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

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

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

.

(4.4)

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

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

    1. Объектная модель RBF-нейросети

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

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

Входные сигналы

Синапсы

первого слоя

Сумматоры

первого

слоя

Преобразователи первого

слоя

Синапсы

второго

слоя

Сумматор второго слоя

Выходной сигнал

F

...

Рисунок 4.1 – Структура нейросети

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

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

  • подключение нового нейрона;

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

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

Таким образом, вычисление градиента функции ошибки будем производить, используя схему, двойственную той, что изображена на рисунке 4.1. Приближаемое k-го нейроном значение функции вычисляется по формуле 4.5.

,

(4.5)

Опираясь на алгоритм определения градиента методами теории графов, можно рассчитать конкретные компоненты вектора градиента для любого слоя.

1) для скрытого слоя

,

(4.6)

2) для первого слоя

,

(4.7)

3) для выходного слоя

,

(4.8)

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

Входные сигналы

Синапсы

первого слоя

Сумматор

первого

слоя

Преобразователь первого

слоя

Синапс

второго

слоя

Сумматор второго слоя

Выходной сигнал

F

...

Рисунок 4.2 – Структура потока

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

Используя объектно-ориентированную парадигму программирования произведем декомпозицию нейросети. Базовым типом элементов, используемым для описания нейронной сети, является общий элемент сети – абстрактный класс, инкапсулирующий основные свойства и методы, характерные для всех компонентов сети – TnetElement. КлассTNetElement является абстрактным, включает в себя

атрибуты: а) Next– указатель на следующий элемент сети;б)Prev– указатель на предыдущий элемент сети; в)FOut– значение сигнала, передающегося элементов вперед при прямом функционировании; г)BOut– значение сигнала, передающегося элементов назад при обратном функционировании;

методы: а) Create– конструктор объектов;б)Destroy– деструктор объектов;в)FAction() – действия элемента во время такта прямого функционирования;г)BAction() – действия элемента во время такта обратного функционирования;

Для связи сети с задачником и передачи используется объекты класса TNetInput– входной элемент сети. Данный класс является потомкомTNetElementи поэтому наследует его атрибуты и методы. Кроме того, класс имеет атрибутSource, который содержит номер поля задачника, с которого данный вход собирает значение.МетодыFAction() иBAction() перегружены. МетодFAction() выполняет передачу значения из соответствующего данному элементу поля задачника на выходной сигнал элемента –FOut().МетодBAction() передает двойственный сигнал следующего элемента на свой двойственный сигнал –BOut().

Выходной элемент сети описывает класс TNetOutput, также являющийся потомкомTNetElement

Для описания синапсов сети используются объекты класса TNetSyn. Как наследник классаTNetElement, он наследует все методы и атрибуты. Помимо этого включены новые атрибуты:Alpha– вес синапса,Alpha2 – сигнал, двойственный весу синапса.

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

Нейрон в понимании нелинейного преобразователя реализован как класс TNetNeuron. Для хранения значений параметров радиальной функции (параметр преобразователя, параметр «спонтанной активности») и двойственных им включены атрибутыAlpha,AlphaS,Alpha2,AlphaS2.

Фрагмент сети, состоящий из слоя входных синапсов, сумматора, нейрона и выходного синапса и названный «потоком» представлен в программной модели классом-потомком от абстрактного класса – общий элемент сети.

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

Структурное представление сети приведено на рисунке 4.4 в виде диаграммы классов.

Управление разработанной структурой сети осуществляет класс TNetManager.

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

    1. Программная модель нейроаппроксиматора

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

class TNetManager

{

public:

double r,p,A,delta,eps;//параметры алгоритма

int Nst;

TNetStream* Stream;//текущий обучаемый поток

double (*XY) [2];//входная выборка

TNetManager(double r,double p,double A,double d,double e, int nst, int sz);

~ TNetManager(){};

void changeMap(double,double*);//изменение параметров сети

doubleincrease(double,double*);//поиск оптимального шага в сторону увеличения

doubledecrease(double,double*);//поиск оптимального шага в сторону уменьшения

double parabola(double ,double,double ,double ,double* ); //поиск оптимального шага в направлении параболы

doublecountError(double,double*);//вычисление ошибки потока сети с измененными параметрами

doublecountError();//вычисление ошибки сети до изменения параметров

voidStudy();//алгоритм обучения потока

};

Алгоритм обучения нейросети начинает работать после указания всех необходимых параметров алгоритма в диалоговом окне.(рисунок 4.4)

Рисунок 4.4 – Диалоговое окно при обучении сети

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

Рисунок 4.5 – Диаграмма состояний нейросети

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

// Сформировали набор функций

TList* functionsList = new TList();

functionsList->Add(new TF1());

functionsList->Add(new TF2());

functionsList->Add(new TF3());

//Создали менеджер сети, Взяли базу данных из файла в задачник менеджера сети

Задачник сети представляет собой матрицу (N+1)xP, гдеN-число переменных функции,P-количество обучающих примеров.

M->Lines->LoadFromFile(leFile->Text);//file with study set (xi,yi)

TNetManager NetMan(StrToFloat(frmStudyNet->ler->Text),StrToFloat(frmStudyNet->lep->Text),StrToFloat(frmStudyNet->leA->Text),StrToFloat(frmStudyNet->led->Text),StrToFloat(frmStudyNet->lee->Text), StrToInt(frmStudyNet->leNst->Text),M->Lines->Count);

for (int i=0;i<M->Lines->Count;i++)

{

int xCharNumber = M->Lines->Strings[i].Pos(";");

int yCharNumber = M->Lines->Strings[i].Length() - M->Lines->Strings[i].Pos(";");

AnsiString xString = M->Lines->Strings[i].SubString(1, xCharNumber - 1);

AnsiString yString = M->Lines->Strings[i].SubString(M->Lines->Strings[i].Pos(";")+1, yCharNumber);

NetMan.XY[i][0]=StrToFloat(xString);

NetMan.XY[i][1]=StrToFloat(yString);

};

//Создали пустую сеть

TNet RBFNet(M->Lines->Count,NetMan.XY);//create net with one stream

//цикл обучения сети

NetMan.Stream=RBFNet.StreamsFirst;//point to one existing stream in empty net

NetMan.Stream->functionList=functionsList;

double H=10;

while (H>StrToFloat(leH->Text))

{

NetMan.Study();

if (RBFNet.StreamsFirst->link!=NULL) NetMan.Stream=RBFNet.AddStream();

H=RBFNet.countError(NetMan.XY);

;};

}

Как уже было отмечено ранее обучение сети есть итерационный процесс обучения элементарных структур – «потоков». Схема алгоритма представлена на рисунке 4.6.

Алгоритм обучения потока также реализует классTNetManager.

void TNetManager::Study(){

double * st=new double[sizeof(this->Stream->alpha0)];

for(int i=0;i<this->Stream->functionList->Count;i++){

TFunction* function = (TFunction*)this->Stream->functionList->Items[i];

int iNst=0;

while( iNst<Nst){

double h0 = 0.1;

this->Stream->initializeMap(function);

double * s = this->Stream->gradient(st);

double Hp = this->countError();

double Hs = this->countError(h0,s);//h0*s + alpha0

if(Hp >= Hs){

changeMap(increase(h0,s),s);

} else {

changeMap(decrease(h0,s),s);

}

iNst++;

}

}

};

Следующий метод вычисляет фунцию ошибки аппроксимации потока.

double TNetManager::countError(double h0, double* s){

double H=0;

double wjk=0;

double wk=0;

double xj=0;

double yj=0;

double an=0;

double ac=0;

int k=0;

for (int j=0;j<sizeof(this->XY[1]);j++)

{

for (k=0;k<sizeof(this->Stream->alpha0)-3;k++)

{

wjk=Stream->alpha0[k]+h0*s[k];

xj=xj+wjk*XY[k][0];

};

wk=Stream->alpha0[k]+h0*s[k];

an=Stream->alpha0[k+1]+h0*s[k+1];

ac=Stream->alpha0[k+2]+h0*s[k+2];

yj=Stream->Neuron->function->execute(xj,an,ac);

H=H+pow(wk*yj-XY[j][1],2);

};

returnH;

};

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

double TNetManager::parabola(double h0,double h1,double h2,double h3,double* s){

bool f1,f2;

double H1=this->countError(h1,s);

double H2=this->countError(h2,s);

double H3=this->countError(h3,s);

int k=0;

while(f1||f2||(k<Nst))

{

double W=(h3+h1)/2-(H3-H1)/((H3-H2)/(h3-h2)-(H2-H1)/(h2-h1));

double Hw=this->countError(W,s);

k++;

if (H2<Hw)

{

if (W>h2)

{

h3=W;

H3=Hw;

}

else

{

h1=W;

H1=Hw;

};

}

else

{

if (W>h2)

{

h3=h2;

h2=W;

H3=H2;

H2=Hw;

}

else

{

h1=h2;

h2=W;

H1=H2;

H2=Hw;

};

};

f1= abs(H3-H2)<delta||abs(H2-H1)<delta;

f2= abs(h3-h2)<eps||abs(h2-h1)<eps;

};

return ( ( (H3>H2)?h2:h3 )>H1)?h1:( (H3>H2)?h2:h3 );

};

double TNetManager::increase(double h0,double* s){

double h1=0;

double h2=h0;

double h3=r*h0;

bool endFlag=false;

while (!endFlag)

{

double H1=this->countError(h1,s);

double H2=this->countError(h2,s);

double H3=this->countError(h3,s);

if (H3>A)

{

endFlag=true;

}

else

{

if (abs((h3-h2)/h3)<eps&&abs(H3-H2)<delta)

{

endFlag=true;

return (H3>H2)?h2:h3;

}

else

{

bool cmpFlag=false;

while (!cmpFlag)

{

if (H3>H2)

{

endFlag=true;

cmpFlag=true;

return parabola(h0,h1,h2,h3,s);

}

else

{

if (H2<(H3*(h3-h2)+H1*(h2-h1))/(h3-h1))

{

double W=(h3+h1)/2-(H3-H1)/((H3-H2)/(h3-h2)-(H2-H1)/(h2-h1));

if (W>h3)

{

h1=h2;

h2=W;

cmpFlag=true;

}

else

{

h1=h2;

h2=h3;

h3=W;

H1=H2;

H2=H3;

H3=this->countError(h3,s);

};

}

else

{

h1=h2;

h2=h3;

h3=r*h2;

};

};

};

};

};

};

};

double TNetManager::decrease(double h0, double* s){

bool parFlag=false;

bool zstFlag=false;

double h1=h0*p;

double h2=0;

double h3=0;

double H2=0;

double H1= this->countError(h1,s);

double H0= this->countError(h0,s);//do not shure

if (h1>eps)

{

zstFlag=true;

if (!parFlag) return 0;

else

{

H2=this->countError(p*h1,s);

if (H0>H2&&H2<H1)

{

h3=h1;

h2=p*h1;

h1=0;

return parabola(h0,h1,h2,h3,s);

}

else return 0;

};

}

else

{

if (H1<H2)

{

parFlag=true;

}

else

{

H2=this->countError(p*h1,s);

if (H0>H2&&H2<H1)

{

h3=h1;

h2=p*h1;

h1=0;

return parabola(h0,h1,h2,h3,s);

}

else return 0;

};

};

};