Нейронная сеть Хопфилда.

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

Изучение нейронных сетей

Итак, сразу же поговорим об основных задачах, которые призвана решать нейронная сеть Хопфилда. И основным ее применением является восстановление образца, ранее сохраненного сетью, по подаваемому на ее вход искаженному образцу. Может это определение не выглядит не совсем понятным, но сейчас все встанет на свои места =) Пусть мы хотим сохранить при помощи сети Хопфилда цифры от нуля до девяти (о процессе сохранения мы поговорим чуть позже, пока не будем останавливаться на этом моменте). Рассмотрим, например, цифру 2, представленную в следующем виде:

Работа с сетью Хопфилда

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

Образец на входе сети

Вот, собственно, в этом и состоит задача нейронной сети Хопфилда ) Давайте теперь обсудим структуру сети и непосредственно процесс обучения — запоминания образцов.

Сеть Хопфилда является однослойной — если не брать в расчет входные элементы. Каждый из нейронов связан со всеми остальными, но не воздействует на себя самого.  В итоге получаем:

Ассоциативная сеть Хопфилда

Здесь мы рассмотрели сеть с четырьмя нейронами.

Нейроны могут принимать два разных значения, но в отличие от ранее рассмотренных сетей, нейроны сети Хопфилда могут находиться в состояниях -1 и 1 (а не 0 и 1). Конечно, можно использовать и уже ставшую привычной систему состояний (двоичную — 0 и 1), но для сетей Хопфилда более традиционной является такая функция активности:

    \[ f = \left[\begin{array}{c} 1 \\ -1 \]

Комбинированный ввод вычисляется по формуле:

    \[net_j = \sum_{i=1}^{N}{s_i w_{ij}}\]

Здесь s_i — состояние нейрона с номером i. Если комбинированный ввод элемента оказывается отрицательным, то состояние элемента становится -1, напротив, когда комбинированный ввод положительный — состояние элемента +1. Если же net_j = 0, то нейрон не изменяет своего состояния, то есть сохраняет предыдущее.

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

Обучение нейронной сети Хопфилда значительно отличается от привычных алгоритмов обучения (например, обучение по принципу обратного распространения ошибки). В случае сети Хопфилда процедура обучения для одного входного образца (процедура сохранения образца) представляет из себя просто расчет весовых коэффициентов по определенной формуле:

    \[W = x^Tx\]

Где W — это матрица весов, x — входной образец, а x^t — транспонированный вектор x (получается из исходного вектора заменой строк на столбцы). Если мы хотим сохранить несколько образцов (k), то необходимо произвести вычисления по этой формуле для каждого из образцов по отдельности, а затем сложить полученные матрицы W_k.

    \[W_k = W_1 + W_2 + ... + W_k\]

Возможно сейчас еще нет полного понимания работы данных сетей, но мы обязательно разберем какой-нибудь практический пример, и тогда все точно встанет на свои места =)

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

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

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

    \[E = (-1/2) * \sum_{j=1}^{N}{\sum_{i=1}^{N}{s_i s_j w_{ij}}}\]

При изменении состояния нейрона j на \Delta s_j энергия изменится на величину:

    \[\Delta E = -\Delta s_j \sum_{i=1}^{N}{s_i w_{ij}}\]

Под знаком суммы у нас тут комбинированный ввод элемента j. Таким образом, если комбинированный ввод положительный, то и изменение состояния нейрона j положительное (\Delta s_j > 0). Аналогично, если  \sum_{i=1}^{N}{s_i w_{ij}} < 0, то и \Delta s_j < 0. Поэтому изменение энергии всегда будет отрицательным (энергия будет уменьшаться в процессе работы сети), что и гарантирует нам то, что сеть является устойчивой.

Пожалуй, на этом закончим обсуждение теоретических аспектов и, как я и обещал, рассмотрим небольшой практический пример, который нам наглядно продемонстрирует обучение и работу нейронной сети Хопфилда =)

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

Пусть нашей задачей является сохранение образца x = [1, -1, 1, 1]. На первом этапе мы должны определить весовые значения сети Хопфилда, а во второй части примера мы убедимся, что сеть сможет восстановить сохраненный образец при подаче на вход искаженного вектора x_{test} = [-1, -1, 1, 1].

Определяем весовую матрицу по формуле

    \[W = x^Tx\]

:

    \[W = \left[ \begin{array}{c} 1 \\ -1 \\ 1 \\ 1 \\ \end{array}\right] \left[ \begin{array}{cccc} 1 & -1 & 1 & 1\\ \end{array}\right]  = \left[ \begin{array}{cccc} 1 & -1 & 1 & 1\\ -1 & 1 & -1 & -1\\ 1 & -1 & 1 & 1\\ 1 & -1 & 1 & 1\\ \end{array}\right] \]

Не забываем о том, что нам надо обнулить диагональные элементы матрицы:

    \[W = \left[ \begin{array}{cccc} 0 & -1 & 1 & 1\\ -1 & 0 & -1 & -1\\ 1 & -1 & 0 & 1\\ 1 & -1 & 1 & 0\\ \end{array}\right] \]

Весовые значения мы рассчитали, давайте подадим на вход вектор x_{test} и посмотрим, как поведут себя нейроны нашей сети.

Комбинированный ввод первого нейрона будет равен:

    \[net_1 = (-1) * 0 + (-1) * (-1) + 1 * 1 + 1 * 1 = 3\]

Поскольку net_1 > 0, то нейрон 1 будет находиться в состоянии +1.

Для второго нейрона:

    \[net_2 = (-1) * (-1) + (-1) * 0 + 1 * (-1) + 1 * (-1) = -1\]

Нейрон 2 окажется в состоянии -1.

    \[net_3 = (-1) * 1 + (-1) * (-1) + 1 * 0 + 1 * 1 = 1\]

Нейрон 3 — +1.

    \[net_4 = (-1) * 1 + (-1) * (-1) + 1 * 1+ 1 * 0 = 1\]

Нейрон 4 — +1.

Таким образом, мы получили такой вектор: [1, -1, 1, 1], что соответствует тому образцу, который мы запоминали в первой части примера. Как видите, наша сеть работает! =) Если теперь еще раз произвести расчет состояний нейронов в соответствии с теми состояниями, которые они приняли после прохождения вектора x_{test} по взвешенным связям, то мы увидим, что состояния не изменится, то есть сеть оказалась в устойчивом положении.

На рассмотрении этого примера мы и закончим сегодняшнюю статью. Надеюсь материал окажется понятным и полезным )

Понравилась статья? Поделись с друзьями!

Нейронная сеть Хопфилда.: 4 комментария
  1. Интересная статься, спасибо, аж захотелось поэкспериментировать. Повторил Ваш пример. Результат оказался верным, но долго не мог понять, почему промежуточные результаты не совпадают. А потом заметил, что у Вас в рассчете net2 опечатка, в самом начале не 1, а -1 поидее должно быть.

  2. Почти в каждой подобной статье ну ооочень не хватает кода к каждой формуле, а в конце — работающий простой исходник

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *