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

Теория.

Совсем без теории конечно не обойтись и начнем мы с нейрона.

Все нейронные сети состоят из нейронов. А если конкретней из математической модели работы настоящего нейрона. Суть этой модели в том что есть много входов ( X ) по которым поступают какие то данные ( на примет или ). У каждого сигналавхода есть вес (сила сигнала W) . Все эти данные обрабатываются внутри нейрона, так называемая функция активации нейрона f(x) . И нейрон падает обработанные данные на выход.

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

Пишем код.

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

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

Теперь создадим саму сеть. Мы создадим все связи между слоями, если точнее — силу этих связей. Для этого мы будем использовать матрицы ( двухмерные массивы) которые будут хранить эти связи. Вы же помните что каждый нейрон связен с каждым нейроном следующего слоя ( например если в скрытом слое 100 нейронов, то для каждого нейрона входного слоя будет иметься 1х100 связей и т.д.)

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

numpy.random.rand() — создает массив заданной формы и заполняет его случайными значениями от 0 до 1.

Нейроны входного слоя просто передаю информацию поступившую на них( для них не используется функция активации) нейронам следующего слоя по связям. Если очень просто то это как устройство ввода или матрица в фотоаппарате. Далее мы эти и они поступают в нейрон следующего слоя. Нейрон используя функцию активации обрабатывает эти данные. Мы будем использовать Сигмоиду. И передает дальше.

Сигмооида — это гладкая монотонная возрастающая нелинейная функция, имеющая форму буквы «S», которая часто применяется для «сглаживания» значений некоторой величины. Формула : f(x) = 1 / (1+e ** -x )

В нейронных сетях применяют не только эту функцию, а например : Гиперболический тангенс , Ступенчатая функция , Гауссова функция.

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

Тут очень важный момент, почему матрицы ? На этой картинке простоя модель

А теперь представим эти данные в виде матрицы :

T — означает транспонированная матрица, не буду вдаваться в математику. Вы можете посмотреть что это значит в интернете.

Машинное обучение.

У нас есть каркас. Но наша сеть глупа как только что родившийся ребенок. И теперь нам надо ее обучить распознавать рукописный текст. Первым делам для этого нужны входные данные( много ) а так же проверочные выходные данные с которыми мы будем сверяться в ходе обучения.

Мы возьмем готовую базу MNIST (сокращение от «Modified National Institute of Standards and Technology») — объёмная база данных образцов рукописного написания цифр. База данных является стандартом, предложенным Национальным институтом стандартов и технологий США с целью калибрации и сопоставления методов распознавания изображений с помощью машинного обучения в первую очередь на основе нейронных сетей. Качаем с нашего сайта.

Смысл обучения нейронной сети сводиться к коррекции W весов связей( силы сигнала) между нейронами. Первым делом мы вычисляем ошибку выходных данных : e1 = t1 — o1 где t1 проверочное значение для нейрона выходного слоя, o1 — фактическое значение. Что бы посчитать ошибку для нейронов скрытого слоя мы воспользуемся методом . Суть проста : (первого нейрона скрытого слоя) = e1 (выходной) * (второй выходной нейрона) * w1.2(вес связи от него)

Формула для матриц

Ошибки нейронов мы посчитали, а на сколько же и как нам менять веса связей ? Не вдаваясь в подробности, будем использовать . То есть коррекция = lern_nodes * e выходного слой * сигмоида выходного слоя * (1 — сигмоида выходного слоя) * сигмоида скрытого слоя

Обучающие данные.

Нас с вами интересует два файл :

Данные предоставлены в удобной текстовой форме, разделенные запятой. Тренировочный набор содержит около 60.000 промаркированных образцов, тестовый поменьше — около 10.000 .

  • Первое значение это маркер от 0-9 , какая цифра изображена.
  • Далее следует пиксельный массив 28х28 . Всего 784 значения от 0 до 255.

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

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

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

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

Код полностью.

Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите .

Простая нейронная сеть в 9 строк кода на Python

Из статьи вы узнаете, как написать свою простую нейросеть на python с нуля, не используя никаких библиотек для нейросетей. Если у вас еще нет своей нейронной сети, вот всего лишь 9 строчек кода:

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

Диаграмма 1

Но для начала, что же такое нейронная сеть? Человеческий мозг состоит из 100 миллиарда клеток, называемых нейронами, соединенных синапсами. Если достаточное количество синаптичеких входов возбуждены, то и нейрон тоже становится возбужденным. Этот процесс также называется “мышление”.

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

Мы будем тренировать нейрон на решение задачи, представленной ниже.

Первые четыре примера назовем тренировочной выборкой. Вы сможете выделить закономерность? Что должно стоять на месте “?”

Диаграмма 2. Input — входный сигнал, Output — выходной сигнал.

Вероятно вы заметили, что выходной сигнал всегда равен самой левой входной колонке. Таким образом ответ будет 1.

Процесс обучения нейронной сети

Как же должно происходить обучение нашего нейрона, чтобы он смог ответить правильно? Мы добавим каждому входу вес, который может быть положительным или отрицательным числом. Вход с большим положительным или большим отрицательным весом сильно повлияет на выход нейрона. Прежде чем мы начнем, установим каждый вес случайным числом. Затем начнем обучение:

  1. Берем входные данные из примера обучающего набора, корректируем их по весам и передаем по специальной формуле для расчета выхода нейрона.
  2. Вычисляем ошибку, которая является разницей между выходом нейрона и желаемым выходом в примере обучающего набора.
  3. В зависимости от направления ошибки слегка отрегулируем вес.
  4. Повторите этот процесс 10 000 раз.

Диаграмма 3

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

Формула для расчета выхода нейрона

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

Затем мы нормализуем это, поэтому результат будет между 0 и 1. Для этого мы используем математически удобную функцию, называемую функцией Sigmoid:

Если график нанесен на график, функция Sigmoid рисует S-образную кривую.

Подставляя первое уравнение во второе, получим окончательную формулу для выхода нейрона:

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

Формула для корректировки веса

Во время тренировочного цикла (Диаграмма 3) мы корректируем веса. Но насколько мы корректируем вес? Мы можем использовать формулу «Взвешенная по ошибке» формула

Почему эта формула? Во-первых, мы хотим сделать корректировку пропорционально величине ошибки. Во-вторых, мы умножаем на входное значение, которое равно 0 или 1. Если входное значение равно 0, вес не корректируется. Наконец, мы умножаем на градиент сигмовидной кривой (диаграмма 4). Чтобы понять последнее, примите во внимание, что:

    1. Мы использовали сигмовидную кривую для расчета выхода нейрона.
    2. Если выходной сигнал представляет собой большое положительное или отрицательное число, это означает, что нейрон так или иначе был достаточно уверен.
    3. Из Диаграммы 4 мы можем видеть, что при больших числах кривая Сигмоида имеет небольшой градиент.
  1. Если нейрон уверен, что существующий вес правильный, он не хочет сильно его корректировать. Умножение на градиент сигмовидной кривой делает именно это.

Градиент Сигмоды получается, если посчитать взятием производной:

Вычитая второе уравнение из первого получаем итоговую формулу:

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

Написание Python кода

Хоть мы и не будем использовать библиотеки с нейронными сетями, мы импортируем 4 метода из математической библиотеки numpy. А именно:

  • exp — экспоненцирование
  • array — создание матрицы
  • dot — перемножения матриц
  • random — генерация случайных чисел

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

“.T” — функция транспонирования матриц. Итак, теперь мы готовы для более красивой версии исходного кода. Заметьте, что на каждой итерации мы обрабатываем всю тренировочную выборку одновременно.

Код также доступен на гитхабе. Если вы используете Python3 нужно заменить xrange на range.

Заключительные мысли

Попробуйте запустить нейросеть, используя команду терминала:

Итоговый должен быть похож на это:

У нас получилось! Мы написали простую нейронную сеть на Python!

Сначала нейронная сеть присваивала себе случайные веса, а затем обучалась с использованием тренировочного набора. Затем нейросеть рассмотрела новую ситуацию [1, 0, 0] и предсказала 0.99993704. Правильный ответ был 1. Так очень близко!

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

Конечно, это был только 1 нейрон, выполняющий очень простую задачу. А если бы мы соединили миллионы этих нейронов вместе?

Простейшие нейронные сети на Python в Visual Studio (Python neural networks in Visual Studio)

Из статьи вы узнаете, как написать простую нейросеть на Python в среде Visual Studio (VS). Для более глубокого понимания проблематики приводятся примеры различных версий кода — от простого из 7 строк до более профессионального.

Любая искусственная нейронная сеть состоит из слоёв. Первый слой — входной, последний — выходной. Любой слой, расположенный между входным и выходным — скрытый. Количество слоев и нейронов в них может быть разное.

Во входном слое расположены нейроны, которые принимают сигнал, но не обрабатывают его.

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

Результат приводится к диапазону [0 … 1] при помощи функции активации (нелинейной сигмоидальной функции).

– параметр наклона сигмоидальной функции S(d). Чем больше этот параметр, тем круче функция (угол касательной в точке перегиба функции будет больше).

Обучить нейронную сеть — значит, сообщить ей, чего мы от нее добиваемся. Допустим, мы хотим, чтобы для нашей сети при сигналах на входе 0 и 1 на выходе была 1.

В общем виде алгоритм обучения с учителем будет выглядеть следующим образом:

  1. Инициализировать синаптические веса маленькими случайными значениями.
  2. Выбрать очередную обучающую пару из обучающего множества; подать входной вектор на вход сети.
  3. Вычислить выход сети.
  4. Вычислить разность между выходом сети и требуемым выходом (целевым вектором обучающей пары).
  5. Подкорректировать веса сети для минимизации ошибки.
  6. Повторять шаги с 2 по 5 для каждой пары обучающего множества до тех пор, пока ошибка на всем множестве не достигнет приемлемого уровня.

Конкретный вид математических операций, выполняемых на этапе 5, определяет разновидность алгоритма обучения. Например, для однослойных сетей применяют простейший алгоритм, основанный на т. н. дельта-правиле (см. Обучение персептрона. Дельта-правило) , для сетей с любым количеством слоев широко используется Алгоритм обратного распространения ошибки.

Создание нейронной сети в Visual Studio (версия кода 1)

Запускаем редактор VS и создаем проект (File>New>Project>Python>Python Application)

Вставляем в исходный файл () код:

В приложении обучается сеть с 2-я входами, с 3-я нейронами на скрытом слое и одним нейроном на выходе.

Обучающая выборка для обучения из 3-х примеров:

  • На входе сигналы: [3,5],[5,1],[10,2];
  • На выходе сигналы: 75,82,93;

Запускаем приложение, получаем после обучения сигналы выходе, близкие к ожидаемым (заданным):

Если отладчик подчеркивает 1-й рядок кода, значит, у Вас еще не инсталлирован пакет (package) numpy. Его можно инсталлировать не выходя из проекта (Шаг 5. Установка пакетов в окружении Python). Для этого открываете контекстное меню в Solution Explore и выбираете в нем «Install Python Package»:

Откроется окно «Python Environments». В поисковом окошке набираете «numpy» и, затем, запускаете «Install numpy».

Откроется окно, в котором выбираете права администратора:

Инсталляция длится не более 5 минут.

Математическая разминка:

Какая цифра должна быть? Проверьте себя и поставьте эту задачу для нейронной сети.

Простая нейронная сеть (версия кода 2)

Постановка задачи. Обучить однослойную нейронную сеть с 3-х входами и с одним выходом на основе тренировочной выборки из 4-х примеров. После обучения системы определить результат на выходе для тестового примера.

Подробное описание приложения см. в первоисточнике Простая нейронная сеть в 9 строчек кода на Python

Вставляем в исходный файл следующий код:

Запускаем приложение, получаем следующий результат:

Усложняем приложение. Вставляем в исходный файл следующий код:

Запускаем приложение, получаем следующий результат:

Простая нейронная сеть (версия кода 3)

Ниже рассмотрены коды приложений для 2-х и 3-х уровневых нейронных сетей. Подробное описание обоих приложений и алгоритма к ним см. в первоисточнике Нейронная сеть в 11 строках Python (часть 1).

Код к 2-х уровневой нейронной сети:

Запускаем приложение, получаем следующий результат:

Код к 3-х уровневой нейронной сети:

Запускаем приложение, получаем следующий результат:

Как построить свою собственную нейронную сеть с нуля в Python

Опубликовано Шамаев Иван в 11.09.2019 11.09.2019

Руководство для начинающих, чтобы понять внутреннюю работу глубокого обучения

Beginner’s Guide of Deep Learning

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

Эта статья содержит то, что я узнал, и, надеюсь, это будет полезно и для вас!

Что такое нейронная сеть?

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

Нейронные сети состоят из следующих компонентов

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

На диаграмме ниже показана архитектура двухслойной нейронной сети ( )

Архитектура двухслойной нейронной сети

Создать класс нейросети в Python просто.

Обучение нейронной сети

Выход простой двухслойной нейронной сети:

Вы можете заметить, что в приведенном выше уравнении весовые коэффициенты и смещения являются единственными переменными, которые влияют на результат

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

Каждая итерация учебного процесса состоит из следующих шагов:

  • Расчет прогнозируемого выхода , известный как связь
  • Обновление весов и уклонов, известных как обратное распространение

Последовательный график ниже иллюстрирует процесс.

прогнозирование

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

Давайте добавим функцию обратной связи в наш код Python, чтобы сделать именно это. Обратите внимание, что для простоты мы приняли смещения равными 0.

Однако нам все еще нужен способ оценить «доброту» наших прогнозов (т. Е. Насколько далеки наши прогнозы)? Функция потерь позволяет нам делать именно это.

Функция потери

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

То есть ошибка суммы квадратов — это просто сумма разности между каждым прогнозируемым значением и фактическим значением. Разница возводится в квадрат, поэтому мы измеряем абсолютное значение разницы.

Наша цель в обучении — найти лучший набор весов и смещений, который минимизирует функцию потерь.

обратное распространение

Теперь, когда мы измерили ошибку нашего прогноза (потери), нам нужно найти способ распространить ошибку назад и обновить наши веса и отклонения.

Чтобы узнать соответствующую сумму, с помощью которой можно корректировать веса и смещения, нам необходимо знать производную функции потерь по весам и смещениям .

Напомним из исчисления, что производная функции — это просто наклон функции.

Алгоритм градиентного спуска

Если у нас есть производная, мы можем просто обновить веса и смещения, увеличивая / уменьшая ее (см. Диаграмму выше). Это известно как градиентный спуск .

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

Уф! Это было некрасиво, но оно позволяет нам получить то, что нам нужно — производную (наклон) функции потерь по отношению к весам, чтобы мы могли соответствующим образом корректировать веса.

Теперь, когда у нас это есть, давайте добавим функцию обратного распространения в наш код Python.

Для более глубокого понимания применения исчисления и правила цепочки в обратном распространении я настоятельно рекомендую этот урок от 3Blue1Brown.

Собираем все вместе

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

Наша нейронная сеть должна изучить идеальный набор весов для представления этой функции. Обратите внимание, что для нас не совсем просто вычислить вес только одним осмотром.

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

Давайте посмотрим на окончательный прогноз (выход) из нейронной сети после 1500 итераций.

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

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

Что дальше?

К счастью для нас, наше путешествие не закончено. Еще многое предстоит узнать о нейронных сетях и глубоком обучении. Например:

  • Какую другую функцию активации мы можем использовать, кроме функции Sigmoid?
  • Использование скорости обучения при обучении нейронной сети
  • Использование сверток для задач классификации изображений

Я скоро напишу больше на эти темы, так что следите за мной на Medium и следите за ними!

Последние мысли

Я, конечно, многому научился писать свою собственную нейронную сеть с нуля.

Хотя библиотеки глубокого обучения, такие как TensorFlow и Keras, позволяют легко создавать глубокие сети без полного понимания внутренней работы нейронной сети, я считаю, что для начинающего ученого-исследователя полезно получить более глубокое понимание нейронных сетей.

Как создать нейронную сеть многослойный перцептрон на Python

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

Это 12-я статья в серии о разработке нейронных сетей. С остальными статьями вы можете ознакомиться выше, в меню с содержанием.

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

Разработка понятного кода на Python для нейронных сетей

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

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

Полный код программы на Python приведен в конце статьи. Код выполняет как обучение, так и проверку. Данная статья посвящена обучению, а валидацию мы обсудим позже. В любом случае, во фрагменте программы, выполняющем проверку, не так много функционала, который не покрыт во фрагменте, выполняющем обучение.

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

Рисунок 1 – Демонстрация терминов на диаграмме конфигурации нейросети

Подготовка функций и переменных

Библиотека NumPy широко используется для расчетов в нейросети, а библиотека Pandas дает мне удобный способ импортировать данные обучения из файла Excel.

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

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

Функция np.random.uniform() заполняет наши две матрицы весов случайными значениями от –1 до +1 (обратите внимание, что матрица весов между скрытым и выходным слоями на самом деле представляет собой просто массив, поскольку у нас только один выходной узел). Оператор np.random.seed(1) приводит к тому, что случайные значения становятся одинаковыми при каждом запуске программы. Начальные значения весов могут оказать существенное влияние на конечную производительность обученной сети, поэтому, если вы пытаетесь оценить, как другие переменные улучшают или ухудшают производительность, вы можете раскомментировать эту инструкцию и тем самым устранить влияние случайной инициализации весовых коэффициентов.

И в конце я создаю пустые массивы для значений преактивации и постактивации в скрытом слое.

Импорт обучающих данных

Это та же процедура, которую я использовал в части 3. Я импортирую обучающие данные из Excel, отделяю целевые значения в столбце « output », удаляю столбец « output », преобразую обучающие данные в матрицу NumPy и сохраняю количество обучающих выборок в переменной training_count .

Обработка прямого распространения

Вычисления, которые создают выходное значение, и в которых данные перемещаются слева направо на типовой схеме нейронной сети, составляют фрагмент «прямого распространения» работы системы. Вот код «прямого распространения»:

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

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

Обратное распространение

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

У нас есть два слоя для циклов for : один для весовых коэффициентов между скрытым и выходным слоями и один для весовых коэффициентов между входным и скрытым слоями. Сначала мы генерируем сигнал ошибки (Sошибки, S_error ), который нам нужен для вычисления обоих градиентов, gradient_HtoO (от скрытого слоя к выходному) и gradient_ItoH (от входного слоя к скрытому), а затем мы обновляем весовые коэффициенты, вычитая градиент, умноженный на скорость обучения.

Обратите внимание, как веса между входным и скрытым слоями обновляются цикла для значений между скрытым и выходным слоями. Мы начинаем с сигнала ошибки, который ведет обратно к одному из скрытых узлов, затем распространяем этот сигнал ошибки на все входные узлы, которые подключены к одному конкретному скрытому узлу:

Рисунок 2 – Обратное распространение ошибки

После того, как все весовые коэффициенты (как ItoH (от входного слоя к скрытому), так и HtoO (от скрытого слоя к выходному)), связанные с этим одним скрытым узлом, были обновлены, мы возвращаемся к началу и начинаем снова для следующего скрытого узла.

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

Заключение

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

Машинное зрение на Python. Обучаем нейросеть распознавать цифры

Содержание статьи

Для каждого примера я приведу код на Python 3.7. Ты можешь запустить его и посмотреть, как все это работает. Для запуска примеров потребуется библиотека Tensorflow. Установить ее можно командой pip install tensorflow-gpu , если видеокарта поддерживает CUDA, в противном случае используй команду pip install tensorflow . Вычисления с CUDA в несколько раз быстрее, так что, если твоя видеокарта их поддерживает, это сэкономит немало времени. И не забудь установить наборы данных для обучения сети командой pip install tensorflow-datasets .

Все приведенные в этой статье примеры работают полностью автономно. Это важно, потому что существуют различные онлайн-сервисы AI, например компании Amazon, которые берут оплату за каждый запрос. Создав и обучив собственную нейронную сеть с помощью Python и Tensorflow, ты сможешь использовать ее неограниченно и независимо от какого-либо провайдера.

Как работает нейронная сеть

Как работает один нейрон? Сигналы со входов (1) суммируются (2), причем каждый вход имеет свой «коэффициент передачи» — w . Затем к получившемуся результату применяется «функция активации» (3).

Модель нейрона

Типы этой функции различны, она может быть:

  • прямоугольной (на выходе 0 или 1);
  • линейной;
  • в виде сигмоиды.

Еще в 1943 году Мак-Каллок и Питтс доказали, что сеть из нейронов может выполнять различные операции. Но сначала эту сеть нужно обучить — настроить коэффициенты w каждого нейрона так, чтобы сигнал передавался нужным нам способом. Запрограммировать нейронную сеть и обучить ее с нуля сложно, но, к счастью для нас, все необходимые библиотеки уже написаны. Благодаря компактности языка Python все действия можно запрограммировать в несколько строк кода.

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

Простейшая нейронная сеть

Сначала нужно подключить необходимые библиотеки, в нашем случае это tensorflow . Я также отключаю вывод отладочных сообщений и работу с GPU, они нам не пригодятся. Для работы с массивами нам понадобится библиотека numpy .

Теперь мы готовы создать нейросеть. Благодаря Tensorflow на это понадобится всего лишь четыре строчки кода.

Мы создали модель нейронной сети — класс Sequential — и добавили в нее два слоя: входной и выходной. Такая сеть называется «многослойный перцептрон» (multilayer perceptron), в общем виде она выглядит так.

Сеть multilayer perceptron

В нашем случае сеть имеет два входа (внешний слой), два нейрона во внутреннем слое и один выход.

Можно посмотреть, что у нас получилось:

Параметры сети

Обучение нейросети состоит в нахождении значений параметров этой сети.
Наша сеть имеет девять параметров. Чтобы обучить ее, нам понадобится исходный набор данных, в нашем случае это результаты работы функции XOR .

Функция fit запускает алгоритм обучения, которое у нас будет выполняться тысячу раз, на каждой итерации параметры сети будут корректироваться. Наша сеть небольшая, так что обучение пройдет быстро. После обучения сетью уже можно пользоваться:

Результат соответствует тому, чему сеть обучалась.

Network test:
XOR(0,0): [[0.00741202]]
XOR(0,1): [[0.99845064]]
XOR(1,0): [[0.9984376]]
XOR(1,1): [[0.00741202]]

Мы можем вывести все значения найденных коэффициентов на экран.

W1: [[ 2.8668058 -2.904025 ] [-2.871452 2.9036295]]
b1: [-0.00128211 -0.00191825]
W2: [[3.9633768] [3.9168582]]
b2: [-4.897212]

Внутренняя реализация функции model.predict_proba выглядит примерно так:

Рассмотрим ситуацию, когда на вход сети подали значения [0,1]:

L1 = X12.8668058 + 1-2.904025 + 1*2.9036295 + -0.00191825] = [-2.8727343 2.9017112]

Функция активации ReLu (rectified linear unit) — это просто замена отрицательных элементов нулем.

Теперь найденные значения попадают на второй слой.

L2 = X23.9633768 +2.9017112*3.9633768 + -4.897212 = 6.468379

Наконец, в качестве выхода используется функция Sigmoid , которая приводит значения к диапазону 0. 1:

Мы совершили обычные операции умножения и сложения матриц и получили ответ: XOR(0,1) = 1 .

С этим примером на Python советую поэкспериментировать самостоятельно. Например, ты можешь менять число нейронов во внутреннем слое. Два нейрона, как в нашем случае, — это самый минимум, чтобы сеть работала.

Но алгоритм обучения, который используется в Keras, не идеален: нейросети не всегда удается обучиться за 1000 итераций, и результаты не всегда верны. Так, Keras инициализирует начальные значения случайными величинами, и при каждом запуске результат может отличаться. Моя сеть с двумя нейронами успешно обучалась лишь в 20% случаев. Неправильная работа сети выглядит примерно так:

XOR(0,0): [[0.66549516]]
XOR(0,1): [[0.66549516]]
XOR(1,0): [[0.66549516]]
XOR(1,1): [[0.00174837]]

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

Можно сделать сеть поумнее: использовать четыре нейрона вместо двух, для этого достаточно заменить строчку кода model.add(Dense(2, input_dim=2, activation=’relu’)) на model.add(Dense(4, input_dim=2, activation=’relu’)) . Такая сеть обучается уже в 60% случаев, а сеть из шести нейронов обучается с первого раза с вероятностью 90%.

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

Продолжение доступно только участникам

Вариант 1. Присоединись к сообществу «Xakep.ru», чтобы читать все материалы на сайте

Членство в сообществе в течение указанного срока откроет тебе доступ ко ВСЕМ материалам «Хакера», увеличит личную накопительную скидку и позволит накапливать профессиональный рейтинг Xakep Score! Подробнее

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

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