PDF, 1.01 Мб, 20 с.

advertisement
Доля П.Г.
Харьковский Национальный Университет
механико – математический факультет
2014 г.
Нейронные сети.
Оглавление
1. Введение ............................................................................................................... 1
2. Модель искусственного нейрона ....................................................................... 2
3. Архитектура нейронных сетей .......................................................................... 5
4. Примеры нейронных сетей................................................................................ 6
1. Введение
Исследования головного мозга показали, что мозговая ткань состоит из
большого числа связанных друг с другом клеток – нейронов. Все они имеют
схожую структуру (рис. 1.1). От центральной части нейрона – ядра отходят
древовидные отростки – дендриты. Они играют роль рецепторов –
"контактов", принимающих сигналы от других нейронов. Аксон, самый
крупный отросток, передает сигнал активности от ядра другим нейронам.
Место соединения аксона с дендритами других нейронов называют
синапсом.
Рис. 1.1 Биологический нейрон.
Сигналы между нейронами передаются химическим и электрическим путем.
При поступлении через дендриты сигналов от других нейронов в ядре
накапливаются изменения – меняется количество ионов натрия Na+,
поступающие ионы Na+ добавляются к уже имеющимся ионам и заряд ядра
резко повышается, нейрон "срабатывает" и возбуждение передается через
аксон на другие нейроны. Затем ядро постепенно приходит в свое исходное
состояние. Чем чаще "срабатывает" нейрон, тем большей становится
электрическая проводимость его синапсов (нервных стыков) – говорят, что
вес синаптической связи увеличивается. Принято считать, что изменения в
синапсах ответственны за память.
Головной мозг – это очень сложная система с множеством нейронов,
связей и внешних сенсоров. Число нейронов можно оценить приблизительно
в 1011 и каждый нейрон в среднем имеет 104 синаптических связей. До конца
понять, как происходит процесс мышления, мы пока не в состоянии. Однако
можем попытаться смоделировать процессы, происходящие в нейронах.
В середине 40 – х годов прошлого века В. Маккаллох и В. Питтс
предложили систему обработки информации в виде сети, состоящей из
простых вычислителей, созданных по принципу биологического нейрона.
Они показали, что такие сети могут производить вычисления, подобно
известной машине Тьюринга. В начале 60 – х годов прошлого века
Ф. Розенблатт для решения проблемы классификации символов предложил
использовать особый тип искусственной нейронной сети, названный им
персептроном (перцептроном). Однако вскоре было показано, что персептрон
не может решать целый класс простых задач, что привело к затуханию
активности в исследованиях по "искусственным нейронным сетям". В 80 – х
годах ситуация изменилась – была предложена модель многослойного
персептрона, который уже не обладал недостатками однослойного
персептрона Розенблатта. Начиная с того времени, теория нейронных сетей
испытывает настоящий бум. Сейчас нейронные сети применяются для
решения разнообразных практических задач, таких как задачи обработки
изображений, управления роботами и непрерывными производствами, для
понимания и синтеза речи, для диагностики заболеваний людей и
технических неполадок в машинах и приборах, для предсказания курсов
валют и результатов соревнований, и даже для предсказания погоды.
2. Модель искусственного нейрона
Из упрощенной биологической схемы функционирования нейрона следует,
что каждый нейрон можно считать своеобразным устройством, которое
суммирует с соответствующими весами сигналы, приходящие от других
нейронов, выполняет над результатом суммирования нелинейное
преобразование и передает результат на выход. Структурную схему
искусственного нейрона можно представить следующим образом
Рис. 2.1 Структура искусственного нейрона
В состав нейрона входят умножители (синапсы), сумматор и нелинейный
преобразователь. Синапсы умножают входной сигнал на число,
характеризующее силу связи (вес синапса). Сумматор выполняет сложение
"взвешенных" сигналов, поступающих на вход нейрона с выходов других
n
нейронов или с внешних сенсоров s  b   xi wi . Здесь wi – веса синапсов,
i 1
xi – компоненты входного вектора, b – смещение (порог) нейрона, s –
результат суммирования. Нелинейный преобразователь реализует функцию
одного аргумента s – выхода сумматора. Она называется "функцией
активации" или передаточной функцией нейрона. Нейрон в целом реализует
скалярную функцию многих переменных y  f x1 , x2 ,...,xn  . При этом
функция f s  зависит не только от значений xi i  1,2,...,n сигналов на
входе нейрона, но и от параметров wi i  1,2,...,n и b, характеризующих
состояние нейрона. Алгоритм подбора этих параметров составляет суть
"обучения" одного нейрона или множества связанных нейронов (нейронной
сети) для решения той или иной задачи.
Функция активации (передаточная функция) нейрона может иметь
самый различный вид. В простейшем случае она принимает только два
значения 0 и 1 и называется пороговой функцией:
0, s  0
f s   
1, s  0
(1)
В пакете Neural Network Toolbox (NNT) функция, задаваемая формулой (1),
называется hardlim. . Чтобы построить ее график в Matlab, можно
выполнить команды
x=-2:0.05:2;
plot(x,hardlim(x),'LineWidth',3);
% функция активации
Линейная функция активации в пакете NNT обозначается purelin. Ее
график показан на следующем рисунке.
f s   s
(2)
В нейронных сетях (НС) часто используются сигмоидальные функции: S –
образные непрерывные функции, имеющие две горизонтальные асимптоты и
одну точку перегиба. Одной из таких часто используемых функций является
логистическая функция описываемая соотношением (3). Ее значения
изменяются от 0 до 1, когда аргумент меняется от   до   . В пакете NNT
она называется logsig.
f s   logsig( s) 
1
1  e s
(3)
Символ в квадрате в правом верхнем углу графика характеризует функцию
активации. Это изображение используется в структурных схемах нейронных
сетей.
Другой сигмоидальной функцией, используемой в пакете NNT, является
tansig. Ее график показан на следующем рисунке
В пакет NNT включены и другие функции активации; пользователь также
может создавать свои собственные уникальные функции.
3. Архитектура нейронных сетей
Искусственная нейронная сеть (ИНС) может содержать один или большее
количество слоев, состоящих из одного или большего количества нейронов.
Такие сети бывают однослойные или многослойные. Развернутая схема сети
из одного слоя с R входами и S нейронами показана на следующем рисунке.
В этой сети каждый элемент вектора входа соединен со входами всех
нейронов.
Весовые
коэффициенты
задаются
матрицей
весов
пороговые
значения
задаются
вектором
Wi j i  1,...,S , j  1,...,R  ;
bi i  1,...,S  ; в каждом слое, как правило, используется одна и та же
функция активации f. Совокупность скалярных выходов нейронов образует S
– элементный вектор a. Т.о. описание слоя нейронов имеет вид
a  f W  p  b ,
где функция активации f применяется поэлементно к результатам
суммирования каждого нейрона.
Количество входов R в слое может не совпадать с количеством
нейронов S. Элементы вектора входа передаются в сеть через матрицу весов
Заметим, что индексы строк матрицы W указывают адресатов весов (номер
нейрона), а индексы столбцов – номер входа
Т.о. сформулируем выводы. Вход функции активации нейрона
определяется смещением и суммой взвешенных входов. Выход нейрона
зависит как от входов, так и от вида функции активации.
Архитектура сети состоит из описания того, сколько слоев имеет сеть,
количества нейронов в каждом слое, вида функции активации каждого слоя и
информации о соединении слоев. Обычно архитектура сети определяется той
задачей, которую должна решать сеть.
Работа сети состоит в вычислении выходов сети на основе известных
входов с целью формирования желаемого результата (вектора) на выходе.
Рассмотрим архитектуру нескольких классических сетей.
4. Примеры нейронных сетей
Нейронная сеть (персептрон Розенблатта, рис. 1.2а) состоит из k нейронов,
имеет d входов и k выходов - по одному выходу из каждого нейрона. Каждый
нейрон имеет настраиваемые веса wi j (i  1,...,d ) – i номер входа, j – номер
нейрона. Нейроны имеют структуру, представленную на рис. 1.1 и
показанную упрощенно на рис. 1.2б.
б
а
Каждый j – й нейрон сети вычисляет взвешенную сумму своих входов
d
y j   xi  wi j  w0 j ,
i 1
где w0 j – порог j – го нейрона. Входной вектор иногда расширяют до
x  1, x1 ,...,xd  и порог w0 j вносится под знак суммы
d
y j   xi  wi j .
i 0
Выходной сигнал каждого нейрона определяется нелинейной пороговой
функцией (1).
Когда персептрон содержит только один нейрон с двумя входами правило
обучения такое.
На начальном шаге параметрам w1 , w2 , b присваиваются произвольные,
например, нулевые значения. Вычисляется реакция нейрона a на первом
векторе p1 и определяется ошибка e  t  a между желаемым ответом t1 и
реакцией
a. Если ошибка равна нулю, то веса wi и порог нейрона bне
меняются и проверяют следующий входной вектор p. Если ответ нейрона 0, а
должен быть 1 ( a  0, t  1 и e  t  a  1 ), то входной вектор прибавляется к
вектору весов. Если ответ нейрона 1, а должен быть 0 ( a  1, t  0 и
e  t  a  1), то входной вектор вычитается из вектора весов. Порог нейрона
bможно рассматривать как дополнительный единичный вход с весом b, для
которого правило корректировки принимается таким же, как и для весов. В
результате правило "обучения" состоит в следующем
1. e  0  w  0 , b  0 .
2. e 1  w  p , b  e  1  e .
3. e  1  w   p , b  e  1  e
В любом из трех случаев
w  t  a   p  e  p и
b  t  a 1  e . Таким
образом
w new  w old  e  p и b new  b old  e , где e  t  a
В случае нескольких нейронов эти соотношения обобщаются следующим
образом:
Доказано, что если решение существует, то процесс обучения персептрона
сходится за конечное число шагов
Пример 1. Рассмотрим пример нейронной сети, состоящей из одного
нейрона, на вход которого подается вектор x  x1 , x2  , компоненты которого
могут принимать только два значений 0 или 1 и функцией активации (1).
"Научим" такую простейшую нейронную сеть реализовывать функцию
логического "ИЛИ". Для этого подберем параметры w1 , w2 , b так, чтобы
всегда выполнялось f x1 , x2   x1  x2 , если x1 , x2 принимают только два
булевых значений 0 и 1. Функцияf на четырех возможных комбинациях
аргументов должна принимать следующие значения
f 0,0  0, f 0,1  1, f 1,0  1, f 1,1  1
Подбор параметров w1 , w2 , b выполним в соответствии с алгоритмом
Розенблатта.
Поскольку в нашем пособии для моделирования искусственных
нейронных сетей мы будем использовать Matlab и его пакет расширения
Neural Network Toolbox, то нам будет удобно принять обозначения этого
пакета. Входные вектора обозначим
0
0
1 
1
p1   , p2   , p3   , p4   
0
1 
0
1
Значения функции активации на этих векторах называются целевыми.
Обозначим их через t i , т.е.
t1  0, t 2  1, t3  1, t 4  1
Координаты векторов p будем обозначать как p k i , где i–номер вектора, k–
номер
координаты,
например,
p1   p11 , p21  ,
T
где
верхний
индекс T
обозначает транспонирование. Выход нейрона будем обозначать через a, т.е.
a  f  p.
Нужно подобрать параметры w1 , w2 , b так, чтобы всегда выполнялись
равенства f  pi   ti i  1,2,3,4 . Алгоритм обучения Розенблатта (подбора
параметров w1 , w2 , b ) для нашего примера состоит в следующем.
На начальном шаге параметрам w1 , w2 , b присваиваются произвольные,
например, нулевые значения. Вычисляется реакция нейрона a на первом
векторе p1 и определяется ошибка e  t  a между желаемым ответом t1 и
реакцией
a. Если ошибка равна нулю, то веса wi и порог нейрона bне
меняются и проверяют следующий входной вектор p.Если ответ нейрона 0, а
должен быть 1 ( a  0, t  1 и e  t  a  1 ), то входной вектор прибавляется к
вектору весов. Если ответ нейрона 1, а должен быть 0 ( a  1, t  0 и
e  t  a  1), то входной вектор вычитается из вектора весов. Порог нейрона
bможно рассматривать как дополнительный единичный вход с весом b, для
которого правило корректировки принимается таким же, как и для весов. В
результате правило "обучения" состоит в следующем
1. e  0  w  0 , b  0 .
2. e 1  w  p , b  e  1  e .
3. e  1  w   p , b  e  1  e
В любом из трех случаев
w  t  a   p  e  p и
b  t  a 1  e . Таким
образом
w new  w old  e  p и b new  b old  e , где e  t  a
В нашем примере имеем
0
0
1 
1
p1   , p2   , p3   , p4    ; t1  0, t 2  1, t3  1, t 4  1
0
1 
0
1
Проверка и корректировка весов w1 , w2 , b для всех входных векторов
pi i  1,2,3,4 называется циклом обучения. Для решения задачи может
потребоваться несколько циклов.
На начальном шаге полагаем
 w1  0
 w   0  и b  0
 2  
Выполняем первый цикл обучения. Для вектора p1 имеем
a  f b  p11  w1  p21  w2   f b  0  w1  0  w2   f 0  1
Здесь и далее в этом примере полагаем, что функцией активации является
пороговая функция (1). Вычисляем ошибку
e  t1  a  0  1  1
Поскольку e  0 , то требуется корректировка весов (значений w1 , w2 , b )
new
 w1 
 w1 
 x1  0
0 0 new




e




1
w 
w 
 x  0
0  0 , b  b  e  0   1  1
   
 2
 2
 2  
На следующем шаге используем вектор p2 . Для новых весов имеем
a  f  1  0  w1  1  w2   f  1  0  0  f  1  0 , e  t 2  a  1  0  1
Ошибка e  1 , поэтому требуется корректировка весов.
new
 w1 
0
0 0 new





1
w 
0
1   1  , b  1   1  0
 
   
 2
На следующем шаге используем вектор p3 . Имеем
a  f 0  1  w1  0  w2   f 1  0  0  1, e  t3  a  1  1  0
Ошибка e  0 и корректировка не требуется. Для вектора p4 имеем
a  f 0  1  w1  1  w2   f 0  0  1  f 1  1 , e  t 4  a  1  1  0
Ошибка опять равна 0 и корректировка не требуется. На этом первый цикл
обучения заканчивается. Теперь мы должны проверить, что i  1,2,3,4
условия f  pi   ti выполняются. Если это не так, то потребуется новая
корректировка весов – второй цикл обучения.
Выполняем проход по всем входным векторам pi еще раз. Сразу видим, что
для вектора p1 ошибка отлична от нуля
a  f 0  0  w1  0  w2   f 0  1 и e  t1  a  0  1  1
Поэтому выполняем корректировку весов
new
 w1 
0
0 0 new
 w   1    1 0  1  , b  0   1  1
 
   
 2
На следующем шаге используем вектор p2 . Имеем
a  f  1  0  w1  1  w2   f  1  0  1  f 0  1 , e  t 2  a  1  1  0
Ошибка 0 и корректировка весов не требуется. На следующем шаге
используем вектор p3 . Имеем
a  f  1  1  w1  0  w2   f  1  0  0  f  1  0 , e  t3  a  1  0  1
Опять выполняем корректировку весов
new
 w1 
0
1  1 new





1
w 
1 
0  1 , b  1   1  0
 
  
 2
Проверяя вектор p4 , убеждаемся, что корректировка не требуется поскольку
a  f 0  1  w1  1  w2   f 0  1  1  f 2  1 , e  t 4  a  1  1  0
На этом второй цикл обучения заканчивается. Чтобы проверить, что
полученные веса wi и порог b удовлетворяют условиям f  pi   ti i  1,2,3,4
,выполним проход по всем входным векторам pi еще раз.
Третий цикл обучения. Для вектора
поскольку
p1 проверка не проходит,
a  f 0  0  w1  0  w2   f 0  1, e  t1  a  0  1  1
Выполняем корректировку весов
new
 w1 
1
0 1 new





1
w 
1
0  1 , b  0   1  1

  
 2
Для вектора p2 корректировка не требуется, поскольку
a  f  1  0  w1  1 w2   f  1  0  1  f 0  1 , e  t 2  a  1  1  0
Для вектора p3 корректировка не требуется, поскольку
a  f  1  1  w1  0  w2   f  1  1  0  f 0  1, e  t3  a  1  1  0
Для вектора p4 проверка проходит, поскольку
a  f  1  1  w1  1  w2   f  1  1  1  f 1  1 , e  t 4  a  1  1  0
Здесь заканчивается третий цикл обучения.
С новыми весами выполним проверку для всех входных векторов pi
еще раз. Для вектора p1 проверка проходит, поскольку
a  f  1  0  w1  0  w2   f  1  0 , e  t1  a  0  0  0
Для векторов p2 , p3 , p4 при данных весах проверка уже выполнялась. Таким
образом, для всех четырех векторов ошибка eравна 0. Мы получили, что
w1  1, w2  1, b  1
При этих параметрах для всех четырех векторов pi имеем f  pi   ti i  1,2,3,4
. Таким образом, функция, которую реализует нейрон, имеет вид
f  1  1  x1  1  x2  , где функция активации f   задана соотношением (1).
Для нашей задачи (при двух входных значениях x1 , x2 ) можно привести
графическую интерпретацию. Для этого на плоскости
x , x 
1
2
построим
четыре точки, соответствующие нашим входным векторам, и прямую L с
уравнением  1  x1  x2  0 .
Пороговая функция f на этой прямой и выше нее принимает значение 1, а
ниже прямой – ноль. Подбирая веса, мы нашли коэффициенты уравнения
прямой b  w1  x1  w2  x2  0 .Она разделяет входные вектора (точки на
плоскости) на две группы – первая состоит из точек (0,1), (1,0), (1,1), вторая –
из точки (0,0). Из рисунка ясно, что таких прямых можно построить много.
Например, веса b  1, w1  3, w2  2 приводят к функции, вида
f  1  x1  3  x2  2 , которая также правильно разделяет наши четыре
вектора.
Теперь выполним приведенные выше вычисления с помощью пакета
расширения Neural Network Toolbox программы Matlab.
Для создания однослойного персептрона используется функция newp
в виде newp(P,Q)или newp(P,T). Функции нужно передать два
аргумента – диапазон (матрицу)Pизменения значений координат входного
вектора (минимальные и максимальные значения) и количество нейронов
Qили вектор Tдиапазонов выходных значений. Количество строк в матрице
Pопределит количество входов сети, а количество строк в матрице
Tопределит количество нейронов в сети (однослойном персептроне) и, тем
самым, количество выходов сети.
clear all; warning off all;
net=newp([0 1;0 1],1); % создание персептрона из одного нейрона
Массив ячеек IW{1,1} созданного объекта net содержит массив весов wi ,
а массив ячеек b{1} этого объекта содержит вектор пороговых значений.
Чтобы посмотреть их начальные значения, выполним команду
w=net.iw{1,1}, b=net.b{1}
w = 0
0
b = 0
Теперь зададим входные вектора pi и целевые значения ti
p1=[0;
p2=[0;
p3=[1;
p4=[1;
0];t1=[0];
1];t2=[1];
0];t3=[1];
1];t4=[1];
Первый цикл состоит в последовательном обучении сети на каждом из
четырех входных векторов. Выполняем обучение сети на первом векторе.
Для этого выполним вычисление
s=b+w*p1
s =0
Пороговая функция f, задаваемая формулой (1), для персептрона в
Matlabназывается hardlim. Например, чтобы построить ее график, можно
выполнить команду
x=-2:0.05:2;
plot(x,hardlim(x),'LineWidth',3);
% функция активации
Используя эту функцию, определим откликa нейрона
a=hardlim(s)
a = 1
Отклик нейронной сети можно выполнить командой
a=sim(net,p1)
a = 1
% эквивалент hardlim(b+w*p1)
На самом деле функция sim вызовет функцию активации, заданную при
конструировании персептрона. Синтаксис функции newp в общем виде
следующий
net = newp(p,t,tf,lf)
Здесь
p –R x Q матрицаиз Q входных векторов, R – количество входов (длина
вектор–столбца входного вектора);
t –S x Q матрица из Q целевых векторов, S – количество выходов (длина
вектор–столбца выходного вектора);
tf–передаточная функция, default ='hardlim'.
lf– обучающая функция, default = 'learnp'.
Если третий и четвертый параметры не заданы, то они принимают значения
имен функций 'hardlim' и 'learnp'.
Теперь вычислим ошибку
e=t1-a
e = -1
Обучение персептрона выполняет функция learnp. В нашем случае ее
можно вызвать следующими командами
% приращение весов
dw=learnp(w,p1,[],[],[],[],e1,[],[],[],[],[])
dw = 0
0
%приращение смещения
db=learnp(b,[1],[],[],[],[],e1,[],[],[],[],[])
db = -1
Здесь второй аргумент[1] – вектор из единиц(по размеру целевых векторов и
их количеству). Теперь вычисляем новые значения wи b
w=w+dw1
w = 0
b=b+db1
b = -1
0
В результате мы получаем такие же значения весов w  w1 , w2  и смещенияb,
как и при ручном счете выше.Все приведенные здесь простые вычисления
для персептрона можно выполнить с помощью одной функции train. Ей
передаются аргументы – идентификатор объекта сети, вектор входных
значений и целевое значение t.Сразу после вызова функции trainвыводим
новые значения весов wi и порога b.
net=train(net,p1,t1);w=net.iw{1,1}, b=net.b{1}
w = 0
0
b = -1
Теперь выполняем обучение сети на втором векторе, используя функцию
train
net=train(net,p2,t2);w=net.iw{1,1},
w = 0
b =0
b=net.b{1}
1
Видим, что веса изменилисьтакже как и при ручном счете. Выполняем
обучение сети на третьем векторе
net=train(net,p3,t3);w=net.iw{1,1}, b=net.b{1}
w = 0
1
b =0
Веса не изменились. Выполняем обучение сети на четвертом векторе
net=train(net,p4,t4);w=net.iw{1,1}, b=net.b{1}
w = 0
1
b = 0
Первый цикл обучения сети закончился. Выполним второй цикл обучения.
net=train(net,p1,t1);w=net.iw{1,1}, b=net.b{1}
w = 0
1
b = -1
net=train(net,p2,t2);w=net.iw{1,1}, b=net.b{1}
w = 01
b = -1
net=train(net,p3,t3);w=net.iw{1,1}, b=net.b{1}
w = 1
1
b = 0
net=train(net,p4,t4);w=net.iw{1,1}, b=net.b{1}
w = 1
1
b = 0
После каждого шага второго цикла мы получаем такие же значения, которые
мы получали при ручном счете. Выполним третий цикл обучения.
net=train(net,p1,t1);w=net.iw{1,1},
w = 1
1
b = -1
net=train(net,p2,t2);w=net.iw{1,1},
w = 11
b =-1
net=train(net,p3,t3);w=net.iw{1,1},
w = 1
1
b = -1
net=train(net,p4,t4);w=net.iw{1,1},
w = 1
1
b =-1
b=net.b{1}
b=net.b{1}
b=net.b{1}
b=net.b{1}
После каждого шага третьего цикла, используя функцию trainMatlab, мы
получаем такие же значения, которые мы получали при ручном счете.
Поскольку вначале третьего цикла еще происходили изменения, то
выполним проверку подобранных весов вектораp1.
net=train(net,p1,t1);w=net.iw{1,1}, b=net.b{1}
w = 1
1
b = -1
Видим, что дальнейшая тренировка сети не требуется, т.к. для всех четырех
входных векторов веса сети уже не меняются.
Выполнять тренировку сети, используя по одному вектору за раз,
утомительно. Поэтому для функции trainпредусмотрена возможность
прохода сразу всего цикла обучения за один раз для всех входных векторов.
Для этого нужно выполнить команду
net.trainParam.epochs=1;
% количество циклов обучения
которая устанавливает количество циклов обучения сети, и передать
функции train матрицы векторов pи t.
clear all; warning off all;
net=newp([0 1;0 1],1);
net.trainParam.epochs=1;
p=[[0;0] [0;1] [1;0] [1;1]]
t=[0 11 1]
p = 0
0
1
1
0
1
0
1
t = 0
11
1
Теперь обучение выполняется сразу для всех четырех входных векторов, т.е.
выполняется первый цикл обучения одним вызовом функции train.
net=train(net,p,t);w=net.iw{1,1}, b=net.b{1}
w = 0
b = 0
1
Выполним второй цикл обучения.
net=train(net,p,t);w=net.iw{1,1}, b=net.b{1}
w = 1
1
b =0
Выполним третий цикл обучения.
net=train(net,p,t);w=net.iw{1,1}, b=net.b{1}
w = 1
1
b =-1
Обучение сети закончено. В конце каждого цикла обучения мы получали те
же значения весов, что и в конце соответствующих циклов при ручном счете.
Теперь проверим вычисления на всем массиве входных векторов.
a=sim(net,p)
a = 0
11
% симулируем работу НС
1
Здесь функция sim выполняет моделирование работы сети на векторах,
заданных в переменной (матрице) p.
Можно сразу указать, чтобы при вызове функции train выполнялось
несколько циклов обучения. Для этого надо задать максимальное количество
циклов обучения следующим образом
net.trainParam.epochs=6;
Выполняемобучение
clear all; warning off all; net=newp([0 1;0 1],1);
net.trainParam.epochs=6;
p=[[0;0] [0;1] [1;0] [1;1]]; t=[0 1 1 1]
net=train(net,p,t);w=net.iw{1,1}, b=net.b{1}
w = 1
1
b =-1
a=sim(net,p)
% моделирование работы НС
a = 0
1
1
1
Вычисляем вектор ошибки
error=a-t
error = 0
0
0
0
Еще две полезные функция позволяют нарисовать входные вектора (разными
символами выделить точки из разных групп) и нарисовать разделительную
прямую w1  x1  w2  x2  b  0 (в нашем случае x1  x2  1  0 )
plotpv(p,t);
% строит два множества точек
hold on;
plotpc(w,b);
% строит разделяющую прямую
hold off;
set(gcf,'Color',[1 1 1]);
Пример 2. Создание нейрона, выполняющего функцию логического "И".
Создадим нейронную сеть (НС), составленную из одного нейрона с
двухэлементным входом, интервалы изменений значения которых [0 1].
clear all; warning off all;
net=newp([0 1;0 1],1);
net.trainParam.epochs=6; % макс. кол-во циклов обучения
p=[[0;0] [0;1] [1;0] [1;1]]; t=[0 0 0 1];
net=train(net,p,t);w=net.iw{1,1}, b=net.b{1}
w =
2
1
b =
-3
Заметим, что функция train также открывает окно, в котором в
схематическом виде изображена НС, а также в области "Epoch" можно
увидеть количество циклов обучения. В нашем примере получилось
5 iterations.
a=sim(net,p)
a =
0
0
% моделирование работы НС
0
1
Вычисляем вектор ошибки
error=a-t
error = 0
0
0
plotpv(p,t); hold on;
plotpc(w,b); hold off;
0
% рисует два множества точек
% рисует разделяющую прямую
Полученную НС можно использовать и для векторов, отличных от
используемых в обучающей выборке. Например
c=[0.5 ; 0.5]; a=sim(net,c)
a =
0
c=[1.5; 1.5]; a=sim(net,c)
a =
1
Теперь не имеет значение, какой была обучающая выборка входных
векторов. НС настроена так, что для всех точек, лежащих левее и ниже
разделяющей прямой, НС будет возвращать 0, а правее и выше – 1.
□
Модели линейных сетей о своей структуре аналогичны персептрону и
отличаются лишь функцией активации, которая является линейной. Выход
линейной сети может принимать любые значения, в то время как выход
персептрона ограничен значениями 0 и 1. Линейные сети, как и персептроны
способны решать только линейно отделимые задачи, но в них используется
другое правило обучения, основанное на методе наименьших квадратов.
Настройка параметров сети выполняется так, чтобы обеспечить минимум
ошибки. Рассмотрим пример.
Пример 3. Сеть с одним "линейным" нейроном (линейная функция
активации), имеющим один вход и один выход, может быть обучена
проводить ближайшую прямую линию y  m  x  c через множество точек
xi , yi  in1 . В качестве меры близости обычно используется сумма квадратов
отклонений прямой от этих точек. Для оценки y мы можем записать
yi  m  xi  c  ei , где ei обозначает ошибку в вычислении y для i – ой точки.
Сумма квадратов ошибок вычисляется по формуле
E  i 1 ei2  i 1  yi  m  xi  c  .
n
n
2
(1)
Заметим, что величина E m, c  является квадратичной функцией своих
аргументов и, поэтому имеет единственный экстремум. Для нахождения
n
E
минимума приравниваем частные производные
 2  xi  yi  m  xi  c  и
m
i 1
n
E
 2   yi  m  xi  c  нулю и решаем систему. Имеем
c
i 1
n
 xi  yi  m  xi  c   0
i 1
n
  y  m  x  c   0
i
 i 1 i
или
n
 n 2
m  xi  c  xi 
i 1
i 1
 n
n
m  x  c  n   y
i
 i 1 i
i 1
Откуда
m
n
n
n
i 1
i 1
i 1
2
n  xi yi   xi   yi


n  xi2    xi 
i 1
 i 1 
n
n
n
и c
y
i 1
n
i
 m   xi
i 1
n
(2)
Задача требует, чтобы сеть оценивала коэффициенты m и с. Поэтому они
принимаются за весовой коэффициенты w и смещение b. Построение
линейной сети в Matlab можно выполнить функцией newlind(P,T),
которая на входе принимает вектор P (в общем случае матрицу R x Q, R –
количество входов сети, Q – количество векторов в обучающей выборке) и T
– целевые значения (в общем случае матрица S x Q, S – количество выходов
сети). В качестве обучающего алгоритма используется метод наименьших
квадратов. В нашем примере в качестве входов P нужно принять вектор X –
абсцисс входных точек, а в качестве T – вектор Y ординат этих точек. Пусть
X=[1 2]
Y=[2 3]
Легко понять, что в этом случае искомая прямая будет проходить через
заданные точки (1,2) и (2, 3). Уравнение такой прямой y  x  1 . Наша НС
даст
net = newlind(X,Y);
w=net.iw{1,1}, b=net.b{1}
w =
1
b =
1
Т.е. мы получили w  1, b  1 . Заметим, что обучение линейной сети
происходит вместе с ее построением в функции newlind(P,T).
Следующий график слева показывает исходные точки и прямую.
plot(X,Y,'o'); xlim([0 3]); ylim([0 4]);
hold on; x=0:0.25:3; y=w*x+b; plot(x,y); hold off;
set(gcf,'Color',[1 1 1]);
Для следующих трех точек имеем (рисунок вверху справа)
clear all; X=[1 2 3]; Y=[2 6 4];
net = newlind(X,Y); w=net.iw{1,1}, b=net.b{1}
w =
1.0000
b =
2.0000
plot(X,Y,'o'); xlim([0 4]); ylim([0 7]);
hold on; x=0:0.25:4; y=w*x+b; plot(x,y); hold off;
Формулы (*) дают те же значения коэффициентов прямой.
Несложно проверить следующий пример (след. рисунок слева)
clear all; X=[1 2 3 4]; Y=[2 5 4 4];
net = newlind(X,Y); w=net.iw{1,1}, b=net.b{1}
w =
0.5000
b =
2.5000
plot(X,Y,'o'); hold on; x=0:0.25:5; y=net(x); plot(x,y);
hold off; xlim([0 5]); ylim([0 6]);
Для проверки работы на больших массивах точек, создадим функцию,
реализующую вычисления по формулам (*)
% Возвращает коэффициенты m и c в уравнении прямой y=m*x+c,
% выполняющей линейную регрессию массива точек (x,y)
function [ m,c] = LinRegrKoef( x,y )
n=length(x);
sx=sum(x);
sy=sum(y);
sxy=sum(x.*y);
sx2=sum(x.^2);
m=(n*sxy-sx*sy)/(n*sx2-sx^2);
c=(sy-m*sx)/n;
end
Пусть
X=[0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0];
Y=[0.5 0.6 0.4 0.5 0.4 0.7 0.7 0.8 1.0];
[m,c]=LinRegrKoef(X,Y)
m =
0.5667
c =
0.2822
net = newlind(X,Y); w=net.iw{1,1}, b=net.b{1}
w =
0.5667
b =
0.2822
plot(X,Y,'o'); hold on; x=0:0.25:5; y=net(x); plot(x,y);
hold off; xlim([0 1]); ylim([0 1]); % пред. рис. справа
Прямую w  x   1  y  b  0 можно нарисовать по-другому (пред. рисунок
справа)
plot(X,Y,'o'); hold on;
plotpc([w,-1],b); hold off;
Еще в пакете Neural Network Toolbox есть вспомогательная функция
errsurf, которая позволяет построить поверхность ошибок нейрона,
имеющего один вход. Она принимает вектора P и T, диапазоны изменения
коэффициентов w и b и имя функции активации . Она возвращает двумерный
массив (матрицу) значений функции E w, b . Имея эту матрицу можно
построить ее поверхность или линии уровня.
Специальная функция plotes строит Plot error surface of single-input neuron
plotes(WV,BV,ES,V) takes these arguments,
строить поверхность ошибок E m, c  и ее линии постоянного значения.
X=[1 -1.2]; Y=[0.5 1];
ES=errsurf(X,Y,-2:0.1:1,-1:0.1:2,'purelin');
[x,y]=meshgrid([-2:0.1:1],[-1:0.1:2]);
surf(x,y,ES);
Download