Пролог и нейронные сети(Prolog and Neural Network). 

 

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

Для этого рассмотрим простой пример классификации или распознавания. 

Примечание – для данного примера используется SWI – Prolog. Для реализации в виде нейронной сети – Matlab. 

 

1. Пролог(Prolog). 

 

Пусть мы хотим распознать животных – bear (Медведь), elephant (Слон), cat (Кот). Эти животные представляют из себя некоторое множество. 

Распознавание – попытка разбить множество на классы по некоторым признакам. 

 Что их отличает в первую очередь? Если Вы задумаетесь, то человеческий мозг вначале пытается разбить «образы» по размеру. Действительно, что вы обычно говорите о малознакомом предмете? 

«….это небольшого размера…. », «…. он большой …» и т.д. 

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

big(bear). 

big(elephant). 

small(cat). 

В нейросетях, как будет показано далее это происходит иначе.  

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

Пусть в нашем случае медведь бурый, кот черный, ну а слоны все серые. Дополнительно вводим еще три факта – класса. 

brown(bear). 

black(cat). 

grey(elephant). 

Как видно из рис. 1 множество big включает множество brown. 

`⊂`(brown, big) 

То есть из того что brown, следует, что big.  

Но так же из того что.  

`⊂`(grey, big) 

И это никак не поможет нам разобраться в животных. 

Рассмотрим черного кота. 

`⊂`(black, small)

Так как «смотрим издалека», то бурый и черный будут малоотличимы, но они будут темнее серого. 

Отсюда следует некоторый класс «темнее» или просто темный. 

Который будет представлять объединение множеств

 

 

Или  – «для того чтобы быть темным достаточно быть бурым или черным». 

Для пролога этот факт записывается в виде. 

dark(Z):-black(Z). % из того что черный следует, что темный 

dark(Z):-brown(Z). % из того что бурый следует, что темный  

Полный код пролог программы. 

big(bear). % задание фактов или классов 

big(elephant). 

small(cat). 

brown(bear). 

black(cat). 

grey(elephant). 

dark(Z):-black(Z). % из того что черный следует, что темный 

dark(Z):-brown(Z). % из того что бурый следует, что темный 

 

 

Image 

 

Рис. 1. 

 

Наше множество разбито на четыре класса. 

Зададим вопрос. 

 

help( 

 

 

 

Ответом будет – bear. 

Проанализируем вопрос. 

 «темный и большой». 

 Операция and означает, что множества пересекаются, т.е. bear принадлежит обоим множествам. 

Или. 

(black or brown) and big 

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

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

 

Image 

                                                                    рис 2. 

 

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

Рассмотрим наше множество. 

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

Введем новый элемент в множество - пусть это будет мышь. Маленькая и белая.. 

Окончательный вид программы. 

big(bear). 

big(elephant). 

small(cat). 

small(mouse). 

brown(bear). 

black(cat). 

grey(elephant). 

white(mouse). 

dark(Z):-black(Z). % из того что черный следует, что темный 

dark(Z):-brown(Z). % из того что бурый следует, что темный 

not_dark(Z):-grey(Z). % из того что серый следует, что не темный 

not_dark(Z):-white(Z). % из того что серый следует, что не темный 

 

Зададим вопрос. 

 

С точки зрения нейросети - "вопрос", сигналы поступающие на вход. Ответ - выход сети. 

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

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

Но верно и обратное - когда мы работаем с неограниченным множеством, аналитическое задание классов либо малоэффективно либо также невозможно. 

 

 

 

2. Нейронные сети (Neural Network). 

 

Придется расстаться с Прологом и перейти к самой мощной среде для технических расчетов и моделирования - Matlab. 

Для наших целей идеально подходит линейная сеть, с функцией активации hardlim. 

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

a = hardlim(W*p+b) 

 

Алгоритм  обучения основан на минимизации среднеквадратической ошибки. 

На первом шаге нам необходимо создать сеть. 

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

[bear [big brown]] = [1 1 1]. 

[elephant [big grey]] - [2 1 0] 

[cat [small  black]] -   [3 0 1] 

[mouse [small white]] - [4 0 0] 

Как видим, нумерацию животных можно опустить, их вполне описывают соответствующие признаки (в данном случае мы приняли черный = бурому =1, белый = серому = 0). Входное множество примет вид. 

[bear, elephant, cat, mouse] 

P=[1            1           0         0;  

    1             0          1         0]; 

 

Выходное (целевое) множество будет аналогичным. 

 

Посмотрим как это выглядит на графике. 

 

Image 

Соответствующий код. 

P=[1 1 0 0;  

  1 0 1 0]; 

 

T= [1 1 0 0;  

  1 0 1 0]; 

 

plotpv(P,T); 

text(1.1,1,'bear') 

text(1.1,0,'elephant') 

text(0.1,1,'cat') 

text(0.1,0,'mouse') 

 

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

И адаптируем ее к данному множеству. 

 

net = newp([0 1;0 1],2); 

net.adaptParam.passes = 10; 

net = adapt(net,P,T); 

plotpc(net.IW{1},net.b{1}); 

 

Посмотрим на результат. 

 

Image 

 

 

Как видим, множество успешно разбито на классы, и для этого понадобилось всего 10 "проходов". 

Теперь зададим сети вопрос - относительно маленький и относительно белый. 

 

 

 

Image 

 

Похож на мышь - относится к классу относительно маленьких и белых. Соответствующий "вопрос" к сети. 

p = [0.1; 0.2]; %  

a = sim(net,p); % получаем отклик сети. 

Очень просто и гораздо эффективнее. Но у вас возникнет вопрос - кто это? Ответ - похож на мышь. 

Это ограничение нашей сети - она может разбить двумерное пространство только на четыре класса (что отвечает принятому нами условию - "смотрим издалека"). Так же эту сеть еще называют однослойным персептроном (one lauer perceptrons ) 

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

Приведенная сеть может ответить на вопрос - медведь, похож на медведя, слон, похож на слона и т.д.  

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

Но подобный подход реализуется и по другому. Например используем Maple. 

 

>

big :={bear, elephant}:# ~big(bear).

 

>

small:={cat,mouse}:# ~big(elephant).

 

>

brown:={bear}:

 

>

black:={cat}:

 

>

grey:={elephant}:

 

>

white:={mouse}:

 

>

dark:=black union brown: #~dark(Z):-black(Z).dark(Z):-brown(Z).

 

>

not_dark:=grey union white:

 

 

Зададим вопрос. 

 

`intersect`(dark, big) 

{bear} 

 

`intersect`(not_dark, small) 

{mouse} 

 

 

Преимущество - соответствие правил записи в математике и кода. Если рассматривать обучение студентов, то это преимущество сложно переоценить. 

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

То что логическое программирование актуально как никогда - факт. Но отвечает ли Пролог требованиям времени? 

 

Vsoft(c).