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

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

Давайте начнем.

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

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

Идем дальше…

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

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

Основная функциональность

Это подводит нас к основным функциям сети. Для этого блока я выбрал свои функции активации, которые я буду использовать, и разработал функции для них. Я выбрал функцию Recified Linear Unit (relu) для вычисления значений на скрытом слое. Эта функция очень популярна в последнее время, и я считаю, что это потому, что она довольно проста и очень эффективна. Он просто решает, больше ли переданное ему значение, чем 0, и если это так, то он передает это значение, а если нет, то передает 0. Вы можете понять, что это может не работать как моя функция активации вывода по очевидным причинам, поэтому Я решил использовать функцию softmax для прогнозирования выходных значений. Функция softmax хороша тем, что выводит значения между интервалом [0, 1]. Поскольку все значения вместе должны быть равны единице, он выбирает значения с наибольшей вероятностью, чтобы сделать прогноз.

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

Простой не так ли?

"ОНО ЖИВОЕ"

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

Обратное распространение — здесь машина учится. Или, как сказал бы Вик Франкенштейн: «ОН ЖИВ!». Таким образом, после начального запуска сети выходные значения будут иметь определенное значение ошибки, связанное с ними, а затем эта частота ошибок или потерь отправляется обратно через сеть и через процесс, называемый градиентным спуском. чтобы минимизировать ошибку, насколько это возможно, и соответствующим образом скорректировать веса и смещения.

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

Наконец, после запуска вашей сети тонну раз, чтобы заставить ее угадывать как можно лучше, мы дадим ей новые данные с интеллектуальными параметрами, которые она получила, и посмотрим, как она работает! В моем конкретном проекте я заставил машину обычно прогнозировать с точностью 92%+ со скоростью обучения 0,0001. Для моей первой сети с нуля я не был разочарован, но оставил номер итерации и скорость обучения открытыми для модификации, чтобы посмотреть, сможете ли вы настроить ее и превзойти мои параметры.

Вывод

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

Спасибо за чтение!

-mt