Как сделать нейросеть на python

Добавил пользователь Alex
Обновлено: 04.10.2024

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

Слишком сжато? Давайте разобьём его на более простые части.

Часть 1: Небольшая игрушечная нейросеть

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

Обратное распространение, в самом простом случае, рассчитывает подобную статистику для создания модели. Давайте попробуем.

Нейросеть в два слоя

Выходные данные после тренировки:
[[ 0.00966449]
[ 0.00786506]
[ 0.99358898]
[ 0.99211957]]

Переменные и их описания.

И это работает! Рекомендую перед прочтением объяснения поиграться немного с кодом и понять, как он работает. Он должен запускаться прямо как есть, в ipython notebook. С чем можно повозиться в коде:

  • сравните l1 после первой итерации и после последней
  • посмотрите на функцию nonlin.
  • посмотрите, как меняется l1_error
  • разберите строку 36 – основные секретные ингредиенты собраны тут (отмечена . )
  • разберите строку 39 – вся сеть готовится именно к этой операции (отмечена . )

Разберём код по строчкам

Импортирует numpy, библиотеку линейной алгебры. Единственная наша зависимость.

Эта функция также умеет выдавать производную сигмоиды (deriv=True). Это одно из её полезных свойств. Если выход функции – это переменная out, тогда производная будет out * (1-out). Эффективно.

Инициализация массива входных данных в виде numpy-матрицы. Каждая строка – тренировочный пример. Столбцы – это входные узлы. У нас получается 3 входных узла в сети и 4 тренировочных примера.

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

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

Первый слой, l0, это просто данные. В X содержится 4 тренировочных примера. Мы обработаем их все и сразу – это называется групповой тренировкой [full batch]. Итого мы имеем 4 разных строки l0, но их можно представить себе как один тренировочный пример – на этом этапе это не имеет значения (можно было загрузить их 1000 или 10000 без всяких изменений в коде).

В строке содержится два шага. Первый делает матричное перемножение l0 и syn0. Второй передаёт вывод через сигмоиду. Размерности у них следующие:

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

Мы загрузили 4 тренировочных примера, и получили 4 догадки (матрица 4х1). Каждый вывод соответствует догадке сети для данного ввода.

А вот и секретный ингредиент. Эту строку нужно разбирать по частям.

Первая часть: производная

l1 представляет три этих точки, а код выдаёт наклон линий, показанных ниже. Заметьте, что при больших значениях вроде x=2.0 (зелёная точка) и очень малые, вроде x=-1.0 (фиолетовая) линии имеют небольшой уклон. Самый большой угол у точки х=0 (голубая). Это имеет большое значение. Также отметьте, что все производные лежат в пределах от 0 до 1.

image

Полное выражение: производная, взвешенная по ошибкам

Математически существуют более точные способы, но в нашем случае подходит и этот. l1_error – это матрица (4,1). nonlin(l1,True) возвращает матрицу (4,1). Здесь мы поэлементно их перемножаем, и на выходе тоже получаем матрицу (4,1), l1_delta.

Умножая производные на ошибки, мы уменьшаем ошибки предсказаний, сделанных с высокой уверенностью. Если наклон линии был небольшим, то в сети содержится либо очень большое, либо очень малое значение. Если догадка в сети близка к нулю (х=0, у=0,5), то она не особенно уверенная. Мы обновляем эти неуверенные предсказания и оставляем в покое предсказания с высокой уверенностью, умножая их на величины, близкие к нулю.

Мы готовы к обновлению сети. Рассмотрим один тренировочный пример. В нём мы будем обновлять веса. Обновим крайний левый вес (9.5)

нейрон

Для крайнего левого веса это будет 1.0 * l1_delta. Предположительно, это лишь незначительно увеличит 9.5. Почему? Поскольку предсказание было уже достаточно уверенным, и предсказания были практически правильными. Небольшая ошибка и небольшой наклон линии означает очень небольшое обновление.

image

Но поскольку мы делаем групповую тренировку, указанный выше шаг мы повторяем для всех четырёх тренировочных примеров. Так что это выглядит очень похоже на изображение вверху. Так что же делает наша строчка? Она подсчитывает обновления весов для каждого веса, для каждого тренировочного примера, суммирует их и обновляет все веса – и всё одной строкой.

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

Часть 2: задачка посложнее

Попробуем предсказать выходные данные на основе трёх входных столбцов данных. Ни один из входных столбцов не коррелирует на 100% с выходным. Третий столбец вообще ни с чем не связан, поскольку в нём всю дорогу содержатся единицы. Однако и тут можно увидеть схему – если в одном из двух первых столбцов (но не в обоих сразу) содержится 1, то результат также будет равен 1.

Это нелинейная схема, поскольку прямого соответствия столбцов один к одному не существует. Соответствие строится на комбинации входных данных, столбцов 1 и 2.

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

image

image

Стратегия

ML_Deep_23.5_site-5020-5727b5.jpg

Для начинающего Data Scientist-а очень важно понять внутреннюю структуру нейронной сети. Это руководство поможет вам создать собственную сеть с нуля, не используя для этого сложных учебных библиотек, к коим относится, например, TensorFlow. Материал написан на основании статьи американского учёного Джеймса Лоя (Технологический университет штата Джорджия).

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

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

Итак, нейронные сети включают в себя следующие компоненты: — х, входной слой; — ŷ, выходной слой; — набор весов и смещений между каждым слоем W и b; — произвольное количество скрытых слоев; — выбор функции активации для любого скрытого слоя σ (в данной статье будем использовать функцию активации Sigmoid). На диаграмме, представленной ниже, отображена архитектура 2-слойной нейронной сети (учтите, что входной уровень, как правило, исключается во время подсчёта числа слоев).

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

2-20219-934615.jpg

Выход ŷ простой 2-слойной нейронной сети: В уравнении, которое приведено выше, веса W и смещения b — единственные переменные, влияющие на выход ŷ. Разумеется, правильные значения для смещений и весов определяют точность предсказаний. А сам процесс тонкой настройки смещений и весов на основании входных данных называют обучением нейронной сети.

В обучающем процессе каждая итерация включает ряд шагов: 1) вычисление прогнозируемого выхода ŷ (прямого распространения); 2) обновление смещений и весов (обратное распространение).

3-20219-f6b69d.jpg

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

Прямое распространение

4-20219-934615.jpg

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

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

5-20219-fd1901.jpg

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

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

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

6-20219-f71efd.jpg

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

7-20219-63969f.jpg

Однако мы не сможем непосредственно посчитать производную функции потерь по отношению к смещениям и весам, ведь уравнение функции потерь не включает в себя смещения и веса. На помощь приходит правило цепи: Да, это было громоздко, зато позволило нам получить то, что необходимо — производную функции потерь (наклон) по отношению к весам. А значит, можно регулировать веса.

Теперь добавим в наш код функцию обратного распространения (backpropagation):

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

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

10-20219-9bcfb1.jpg

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

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

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

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

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

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


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

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

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

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


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

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

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

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

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


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

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


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

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

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


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

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

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

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

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

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


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

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

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


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

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

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

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

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


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

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


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


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

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

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

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

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

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

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

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

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


Эта нейронная сеть, как и все нейронные сети, должна будет узнать, какие важные функции имеются в данных для получения результата. В частности, этой нейронной сети будет предоставлена ​​входная матрица с шестью выборками, каждая с тремя характеристическими столбцами, состоящими только из нулей и единиц. Например, одна выборка в обучающем наборе может быть [0, 1, 1]. Выход для каждого образца будет один или ноль. Выходные данные будут определяться числом в первом столбце признаков образцов данных. Используя приведенный выше пример, вывод для [0, 1, 1] будет 0, потому что первый столбец содержит ноль. Пример диаграммы будет приведен ниже, чтобы продемонстрировать выход для каждого входного образца.



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

Как упоминалось ранее, нейронные сети нуждаются в данных, чтобы учиться. Мы создадим нашу матрицу входных данных и соответствующую матрицу выходов с Numpy's .array() функция. Каждый образец на входе состоит из трех столбцов объектов, состоящих из 0 и 1, которые выдают один выходной сигнал либо 0, либо 1. Мы хотим, чтобы нейронная сеть узнала, что выходные данные определяются первым столбцом объектов в каждом образце.


Сигмовидная функция может быть записана как:


И производная сигмоидальной функции может быть записана как:

Производная - это просто причудливое слово для наклона или касательной к данной точке. Посмотрите на кривую сигмоидальной функции на графике выше. гдех = 0, уклон намного больше, чем уклон, гдех = 4илих = -4, Количество, которое вес (ы) обновляется на основе производной Если уклон является более низким значением, нейронная сеть уверена в своем прогнозе, и требуется меньшее перемещение весов. Если наклон имеет более высокое значение, то предсказания нейронной сети ближе к 0,50 или 50% (самое высокое значение наклона, возможное для сигмоидальной функции, составляетх = 0а такжеу = 0,5,Yэто прогноз.). Это означает, что нейронная сеть не очень уверена в своих предсказаниях и нуждается в большем обновлении весов.

Мы можем найти производную сигмоидальной функции с шагами ниже:


Затем мы можем использовать классный трюк, чтобы продолжить упрощение: добавить один и вычесть один изе ^ -x, Добавление одного и вычитание одного ничего не изменит, потому что они уничтожают друг друга. Это причудливый способ добавления нуля.


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


Теперь мы можем упростить и получить сигмоидные функции с упрощенной производной.


Если мы напишем сигмовидную функцию какS (X)тогда производная может быть записана как:

знак равноS (X) ⋅ (1-S (х))

В процессе обучения нашей нейронной сети входные данные будут передаваться через вес и функции сети. Результатом этой функции прямой связи будет вывод скрытого слоя или наилучшее предположение скрытого слоя с указанными им весами. Каждый объект во входных данных будет иметь собственный вес для подключения к скрытому слою. Начнем с того, что берем сумму каждой функции, умноженную на соответствующий вес. После того, как мы умножили матрицы ввода и веса, мы можем взять результаты и передать их через сигмовидную функцию, чтобы получить сжатие до вероятности между (0–1). Функция прямого распространения может быть записана так, гдеxᵢа такжеwᵢИндивидуальные особенности и веса в матрицах:


Чтобы повторить, скрытый слой будет рассчитан с помощью следующих шагов:

  • Умножьте каждый столбец функции на его вес
  • Сумма продуктов функций и весов
  • Передайте сумму в сигмоидную функцию, чтобы получить вывод $ \ hat y $

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


Вышеуказанный процесс приведет к предсказанию скрытого слоя. Каждый ряд вΣxwматрица будет введена в сигмовидную функцию. Цвета представляют отдельные процессы для каждой строки в ∑без гарантийматрица.Заметка:этот расчет представляет толькоодна итерация обученияитаксечение ■Матрица не будет очень точной. При таком вычислении скрытого слоя с последующим использованием обратного распространения для многих итераций результат будет намного более точным.

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


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


Теперь мы можем умножить ошибку и производную от прогноза скрытого слоя. Мы знаем, что производная сигмоидальной функцииS (x) (1 - S (x)), Следовательно, производная для каждого из прогнозов скрытого слоя будет [(ŷ) (1 - ŷ)], Например, первая строка в матрице прогнозирования скрытого слоя содержит значение $ 0,62 $. Мы можем заменитьсечение ■с $ 0,62 $, и результат будет производной от прогноза.0,62 * (1–0,62) = 0,2356, Повторяя этот процесс для каждой строки всечение ■матрица даст вам матрицу производных 4x1, которую вы затем умножите на матрицу ошибок.


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



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


Процесс обучения следует приведенному ниже уравнению для каждого веса в нашей нейронной сети:

  • xᵢ- Функция во входных данных
  • wᵢ- Вес, который обновляется
  • Xᵀ- транспонированные входные данные
  • Y- правильный вывод
  • сечение ■- Прогнозируемый выход
  • (у -сечение ■) - Ошибка
  • Σxᵢwᵢ - сумма произведений входных характеристик и весов
  • S (Σxᵢwᵢ)- сигмовидная функция


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

Мы создадим наш объект NN из класса NeuralNetwork и передадим входную матрицу и выходную матрицу.

Затем мы можем позвонить .train() функционировать на нашем объекте нейронной сети.

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


Я надеюсь, что это было хорошее небольшое введение в нейронные сети, использующие Python и объектно-ориентированный подход.

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

Шаг 1: импорт NumPy, Scikit-learn и Matplotlib

import numpy as np
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt

Для этого проекта мы используем три пакета. NumPy будет служить для создания векторов и матриц, а также математических операций. Scikit-learn возьмет на себя обязанность по масштабированию данных, а Matpotlib предоставит график изменения показателей ошибки в процессе обучения сети.

Шаг 2: создание обучающей и контрольной выборок

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

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

Шаг 3: масштабирование данных

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

В наших обучающей и контрольной выборках значения расположены в относительно небольшом диапазоне, поэтому можно и не применять масштабирование признаков. Однако данная процедура все-таки включена, чтобы вы могли использовать собственные числа без особых изменений кода. Масштабирование признаков реализуется в Python очень легко, в чем помогает пакет Scikit-learn и его класс MinMaxScaler . Просто создайте объект MinMaxScaler и используйте функцию fit_transform с исходными данными в качестве входа. В результате эта функция вернет те же данные уже в масштабированном виде. В названном пакете есть и другие функции масштабирования, которые стоит попробовать.

Шаг 4: Создание класса нейронной сети

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

Шаг 4.1: создание функции инициализации

Функция _init_ вызывается при создании класса, что позволяет правильно инициализировать его переменные.

Читайте также: