Распознаём образы: Нейронная сеть Хопфилда
Опубликовано в Статьи | 29-07-2009
Допустим, у нас имеется некоторое количество эталонных образов – изображений, либо ещё чего-нибудь. Нам дают некий искажённый образ, и наша задача состоит в том, чтобы «распознать» в нём один из эталонных. Каким образом человек это сделает – вопрос сложный. А вот каким образом с данной задачей справится искусственная нейронная сеть – мы вполне можем себе представить. Тем более, если это .
В этой статье я убрал всю математику и большую часть терминологии, что может показаться невежественным, однако, полагаю, так легче понять основную идею. Так же будет разработан пример на 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: - @ @ @ @ @ - - @ - - - @ - - @ - - - @ - - @ - - - @ - - @ - - - @ - - @ - - - @ - - @ - - - @ -
Заключение
В данной статье была продемонстрирована простая реализация нейронной сети Хопфилда, формирующую ассоциативную память. Как было показано, вся работа сводится к вычислению весовых коэффициентов сети. Здесь опущена вся математика, так что заинтересованному читателю предлагается самостоятельно обратиться к соответствующей литературе за дополнительной информацией.
Исходные коды программы доступны .