Введение в нейронные сети на примере нейронной сети Хопфилда

МЕНЮ


Искусственный интеллект. Новости
Поиск
Регистрация на сайте
Сбор средств на аренду сервера для ai-news

ТЕМЫ


Новости ИИРазработка ИИВнедрение ИИРабота разума и сознаниеМодель мозгаРобототехника, БПЛАТрансгуманизмОбработка текстаТеория эволюцииДополненная реальностьЖелезоКиберугрозыНаучный мирИТ индустрияРазработка ПОТеория информацииМатематикаЦифровая экономика

Авторизация



RSS


RSS новости

Новостная лента форума ailab.ru


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

Теоретическое описание

Введение

Для начала, необходимо определить, что такое нейрон. В биологии нейрон - специализированная клетка, из которой состоит нервная система. Биологический нейрон имеет строение, показанное на рис.1.

Рис.1 Схема нейрона

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

  1. Задать архитектуру сети;
  2. Определить динамику отдельных элементов сети - нейронов;
  3. Определить правила, по которым нейроны будут взаимодействовать между собой;
  4. Описать алгоритм обучения, т.е. формирования связей для решения поставленной задачи.

В качестве архитектуры нейронной сети будет использоваться сеть Хопфилда. Данная модель, видимо, является наиболее распространенной математической моделью в нейронауке. Это обусловлено ее простотой и наглядность. Сеть Хопфилда показывает, каким образом может быть организована память в сети из элементов, которые не являются очень надежными. Экспериментальные данные показывают, что при увеличении количества вышедших из строя нейронов до 50%, вероятность правильного ответа крайне близка к 100%. Даже поверхностное сопоставление нейронной сети (например, мозга) и Фон-Неймановской ЭВМ показывает, насколько сильно различаются эти объекты: к примеру, частота изменения состояний нейронов («тактовая частота») не превышает 200Гц, тогда как частота изменения состояния элементов современного процессора может достигать нескольких ГГц (10^9Гц).
Формальное описание сети Хопфилда

Сеть состоит из N искусственных нейронов, аксон каждого нейрона связан с дендритами остальных нейронов, образуя обратную связь. Архитектура сети изображена на рис. 2.

Рис.2 Архитектура нейронной сети Хопфилда

Каждый нейрон может находиться в одном из 2-х состояний:

S(t)in{-1;+1}

где S(t) - состояние нейрона в момент t. «Возбуждению» нейрона соответствует +1, а «торможению» -1. Дискретность состояний нейрона отражает нелинейный, пороговый характер его функционирования и известный в нейрофизиологи как принцип «все или ничего».

Динамика состояния во времени i-ого нейрона в сети из N нейронов описывается дискретной динамической системой:

S_{i}(t+1)=sign[sumlimits_{j=1}^N J_{i,j}S_{i}(t)],quad i,jin1,..,N

где J_{i,j} - матрица весовых коэффициентов, описывающих взаимодействие дендритов i-ого нейрона с аксонами j-ого нейрона.

Стоит отметить, что J_{i,i}=0,quad i=1,..,N и случай sumlimits_{j=1}^{N}J_{i,j}S_{i}(t)=0 не рассматриваются.

Обучение и устойчивость к шуму

Обучение сети Хопфилда выходным образам zeta_{mu}^{in} сводится к вычислению значений элементов матрицы J_{i,j}. Формально можно описать процесс обучения следующим образом: пусть необходимо обучить нейронную сеть распознавать M образов, обозначенных {zeta_{mu}^{in},mu=1,..,M}. Входной образ overline{zeta_{mu}^{in}} представляет собой: overline{zeta_{mu}^{in}} = zeta_{mu}^{in} + acute{zeta} где acute{zeta} - шум, наложенный на исходный образ zeta_{mu}^{in}.
Фактически, обучение нейронной сети - определение нормы в пространстве образов || zeta_{mu}^{in} - overline{zeta_{mu}^{in}} ||. Тогда, очистка входного образа от шума можно описать как минимизацию этого выражения.

Важной характеристикой нейронной сети является отношение числа ключевых образов M, которые могут быть запомнены, к числу нейронов сети N: alpha = frac{M}{N}. Для сети Хопфилда значение alpha не больше 0.14.

Вычисление квадратной матрицы размера для ключевых образов производится по правилу Хебба:

J_{i,j} = {1 over N} cdot sumlimits_{mu=1}^{M}ig[zeta_{i,mu}^{in} cdot zeta_{j,mu}^{in} ig]}

где zeta_{j,mu}^{in} означает j -ый элемент образа zeta_{mu}^{in}.

Стоит отметить, что в силу коммутативности операции умножения, соблюдается равенство
J_{i,j}=J_{j,i}

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

S_{i}=overline{zeta_{mu}^{in}}

Уравнений (1), (2), (3), (4) достаточно для определения искусственной нейронной сети Хопфилда и можно перейти к ее реализации.

Реализация нейронной сети Хопфилда

Реализация нейронной сети Хопфилда, определенной выше будет производиться на языке C++. Для упрощения экспериментов, добавим основные определения типов, напрямую связанных с видом нейрона и его передаточной функции в класс simple_neuron, а производные определим далее.

Самыми основными типами, напрямую связанными с нейроном являются:

  1. тип весовых коэффициентов (выбран float);
  2. тип, описывающий состояния нейрона (введен перечислимый тип с 2 допустимыми значениями).

На основе этих типов можно ввести остальные базовые типы:

  1. тип, описывающий состояние сети в момент t (выбран стандартный контейнер vector);
  2. тип, описывающий матрицу весовых коэффициентов связей нейронов (выбран контейнер vector контейнеров vector).

Листинг 1. Определение новых типов

Обучение сети, или, вычисление элементов матрицы J_{i,j}=J_{j,i} в соответствии с (3) производится функцией learn_neuro_net, принимающей на вход список обучающих образов и возвращающей объект типа link_coeffs_t. Значения J_{i,j} вычисляются только для нижнетреугольных элементов. Значения верхнетреугольных элементов вычисляются в соответствии с (4). Общий вид метода learn_neuro_net показан в листинге 2.

Листинг 2. Обучение нейронной сети

Обновление состояний нейронов реализовано с помощью функтора neuro_net_system. Аргументом метода _do функтора является начальное состояние S_{i}(0), являющееся распознаваемых образом (в соответствии с (5)) - ссылка на объект типа neurons_line.

Метод функтора модифицирует передаваемый объект типа neurons_line до состояния нейронной сети в момент времени T. Значение жестко не фиксировано и определяется выражением:

S_{i}(T-1)=S_{i}(T)

т.е., когда состояние каждого нейрона не изменилось за 1 «такт».

Для вычисления (2) применены 2 алгоритма STL:

  1. std::inner_product для вычисления суммы произведений весовых коэффициентов и состояний нейронов (т.е. вычисление (2) для определенного i);
  2. std::transform для вычисления новых значений для каждого нейрона (т.е. вычисление пункта выше для каждого возможного i)

Исходный код функтора neurons_net_system и метода calculate класса simple_neuron показан в листинге 3.

Листинг 3. Функтор, реализующий работу нейронной сети

Для вывода в консоль входных и выходных образов создан тип neurons_line_print_descriptor, который хранит ссылку на образ и формат форматирования (ширину и высоту прямоугольника, в который будет вписан образ). Для этого типа переопределен оператор <<. Исходный код типа neurons_line_print_descriptor и оператора вывода в поток показан в листинге 4.

Листинг 4. Вывод в поток состояния нейронной сети

Пример работы нейронной сети

Для проверки работоспособности реализации, нейронная сеть была обучена 2 ключевым образам:

Рис.3 Ключевые образы

На вход подавались искаженные образы. Нейронная сеть корректно распознала исходные образы. Искаженные образы и распознанные образы показаны на рис.4, 5

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

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

Запуск программы производится из командной строки строчкой вида: AppName WIDTH HEIGHT SOURCE_FILE [LEARNE_FILE_N], где:

AppNaame - название исполняемого файла; WIDTH, HEIGHT - ширина и высота прямоугольника, в который будут вписываться выходной и ключевые образы; SOURCE_FILE - исходный файл с начальным образом; [LEARNE_FILE_N] - один или несколько файлов с ключывыми образами (через пробел).

Исходный код выложен на GitHub -> https://github.com/RainM/hopfield_neuro_net

В репозитории проект CMake, из которого можно сгенерировать проект Visual Studio (VS2015 компилирует проект успешно) или обычные Unix Makefile-ы.

Использованная литература 

  1. Г.Г. Малинецкий. Математические основы синергетики. Москва, URSS, 2009.
  2. Статья «Нейронная_сеть_Хопфилда» на Википедии.

Источник: habrahabr.ru

Комментарии: