Распознаём образы: Нейронная сеть Хопфилда

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

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

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

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

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


Однако эту сеть нельзя научить практически ничему. Нам нужно намного больше нейронов. Сеть, содержащая N нейронов может запомнить не более ~0.15*N образов. Так что реальная сеть должна содержать достаточно внушительное количество нейронов. Это одно из существенных недостатков сети Хопфилда – небольшая ёмкость. Плюс ко всему образы не должны быть очень похожи друг на друга, иначе в некоторых случаях возможно зацикливание при распознавании.

Как работает сеть

Образ, который сеть запоминает или распознаёт (любой входной образ) может быть представлен в виде вектора X размерностью n, где n – число нейронов в сети. Выходной образ представляется вектором Y с такой же размерностью. Каждый элемент вектора может принимать значения: +1 либо -1 (Можно свести к 0 и 1, однако +1 и -1 удобнее для расчётов).

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

Обучение сети

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

for i in range(0,n):
    for j in range(0,n):
        if (i == j):
            self.W[i][j] = 0
        else:
            self.W[i][j] += self.X[i] * self.X[j]

Если нам нужно обучить сеть следующему образу, мы просто меняем вектор X и заново повторяем эту процедуру. Вы видите, в элементах матрице сохраняется сумма значений для всех образов, которым мы обучили сеть. Установка значения элемента в 0 при i==j это отражения устройства сети, когда выход некого нейрона не попадает на его же вход.

Распознавание образа

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

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

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

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

net = 0
for i in range(0, n):
    net += Y[i] * W[i][r]
s = signum(net)

А затем мы обновляем его состояние:

Y[r] = s

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

Пример

Посмотрим как наша реализация сети сможет распознать образы букв. Мы будем представлять их в виде «битовых полей» размера 7х7. Так, имея три эталонных образа и один образ для распознавания, эмуляция нейронной сети даёт следующий результат:

Known Shapes:
- @ @ @ @ @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -

@ @ @ @ @ @ @
- - - @ - - -
- - - @ - - -
- - - @ - - -
- - - @ - - -
- - - @ - - -
- - - @ - - -

@ - - - - - @
@ - - - @ @ -
@ - - @ - - -
@ @ @ - - - -
@ - - @ - - -
@ - - - @ @ -
@ - - - - - @

Teaching...

Modified shape:

@ @ - - - - -
@ - - - @ @ -
@ - - @ - - -
- - @ - - - -
@ - - @ - - -
@ - - - @ @ -
@ @ - - - - @

Shape recognizing...

Neuron   6 : -1  ->   1
Neuron  43 :  1  ->  -1
Neuron  21 : -1  ->   1
Neuron  22 : -1  ->   1
Neuron   1 :  1  ->  -1

Success. Shape recognized in 94 iterations:

@ - - - - - @
@ - - - @ @ -
@ - - @ - - -
@ @ @ - - - -
@ - - @ - - -
@ - - - @ @ -
@ - - - - - @

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

А теперь посмотрим, что будем если подать на вход образ, похожий и на П и на Т:

Teaching...

[ вырезано ]

Modified shape:
@ @ @ @ @ @ @
- @ - @ - @ -
- @ - @ - @ -
- @ - @ - @ -
- @ - @ - @ -
- @ - @ - @ -
- @ - @ - @ -

Shape recognizing...
Neuron  12 :  1  ->  -1
Neuron   6 :  1  ->  -1
Neuron  40 :  1  ->  -1
Neuron   0 :  1  ->  -1
Neuron  22 :  1  ->  -1
Neuron  17 :  1  ->  -1
Neuron  31 :  1  ->  -1

Fail. Shape not recognized in 273 iterations...
- @ @ @ @ @ -
- @ - @ - - -
- @ - - - @ -
- - - @ - @ -
- @ - - - @ -
- @ - @ - - -
- @ - @ - @ -

Однако запустив программу несколько раз мы сможем наблюдать и такой вариант, когда сеть всё же смогла распознать образ П (а не Т, поскольку входящий образ больше похож именно на П):

Shape recognizing...
Neuron   0 :  1  ->  -1
Neuron  22 :  1  ->   0
Neuron  17 :  1  ->  -1
Neuron   6 :  1  ->  -1
Neuron  31 :  1  ->  -1
Neuron  10 :  1  ->  -1
Neuron  38 :  1  ->  -1
Neuron  22 :  0  ->   1
Neuron  45 :  1  ->  -1
Neuron  24 :  1  ->  -1

Success. Shape recognized in 116 iterations:
- @ @ @ @ @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -
- @ - - - @ -

Заключение

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

Исходные коды программы доступны здесь.
(ссылка обновлена 15.12.2014)

Реклама

14 ответов на “Распознаём образы: Нейронная сеть Хопфилда

  1. Отличная статья!!!
    Таким как я — только-только научившимся кодить и интерисующимся нейросетями такие статьи очень помогают.
    P.S. Здоровья и удачи автору везде и во всем!!!

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

    Кому нужен код на php могу выслать(без классов, но с проверкой на схожесть эталонов и выводит картинку), + .doc описывающий доступно мат. теорию.

    Писать на : mramsela@yandex.ru

  3. Спасибо за подробную статью. Я автор python библиотеки работы с нейронными сетями http://code.google.com/p/neurolab/. Сейчас она еще не содержит сеть Хопфилда, но возможно в следующей версиях появится, в том числе и благодаря данной статье. К сожалению, сейчас в python отсутствует (по крайне мере в свободном доступе) какая-либо одна библиотека позволяющая однообразно работать с разными, базовыми архитекторами ИНС — что я и хотел бы изменить.

  4. Если не знаешь что писать в свой блог — напиши о сети Хопфилда. Без обид, просто в гугле набрал и получил кучу ссылок. — отсюда такая и мысль..Одни и теже примеры применения. Надо себе написать также в блог :))

Добавить комментарий

Заполните поля или щелкните по значку, чтобы оставить свой комментарий:

Логотип WordPress.com

Для комментария используется ваша учётная запись WordPress.com. Выход / Изменить )

Фотография Twitter

Для комментария используется ваша учётная запись Twitter. Выход / Изменить )

Фотография Facebook

Для комментария используется ваша учётная запись Facebook. Выход / Изменить )

Google+ photo

Для комментария используется ваша учётная запись Google+. Выход / Изменить )

Connecting to %s