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

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

ПРИМЕЧАНИЕ: если вы хотите загрузить полный код, используемый в этой статье, вы можете найти его здесь

Абстракция высокого уровня того, что делает персептрон

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

Чтобы дать вам лучшее представление, подумайте о том, как ребенок может научиться различать собаку и кошку. Допустим, мы представляем ему 100 различных изображений кошек и собак, рассказывая ему, что представляет собой каждое из них, и он сможет различать каждое из них на основе особенностей, которые он видит. Например, он заключает, что у кошек короткие уши, а у собак длинные. Теперь, конечно, человеческий разум не смотрит на кошку и не говорит: «Если уши имеют длину от 2,345 до 3,67 см, это кошка», но именно так это может увидеть персептрон.

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

x и w: каждый X, представленный нижним индексом «i», здесь представляет функцию, поэтому здесь у нас есть «m» количество функций, опять же в сценарии «кошка-собака» это может быть длина уха. Каждая функция связана с весом, с математической точки зрения, вес каждой функции — это ее коэффициент. «Вес», как следует из названия, можно рассматривать как представление уровня влияния, которое оказывает эта функция. «Обучающая часть» любого алгоритма машинного обучения — это процесс нахождения оптимального значения каждого веса.

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

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

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

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

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

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

Реализация бинарного классификатора персептрона в Python

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

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

  • Numpy: это одна из наиболее распространенных библиотек, используемых в приложениях для работы с данными. Она позволяет нам создавать «массивы numpy», похожие на списки, но их реализация позволяет нам выполнять вычисления с этими массивами.
  • Случайно: мы будем использовать случайный выбор для инициализации наших весов.
  • Pandas: pandas также является очень мощной библиотекой для работы с данными, но в нашем случае мы будем использовать pandas просто для импорта нашего примера набора данных.
  • Matplotlib: наконец, мы будем использовать matplotlib для визуализации концепций.

Пример набора данных:

В этом примере мы будем использовать набор данных «цветок ириса». Эти данные содержат 3 разных цветка с 50 различными образцами для каждого типа цветка, содержащими 4 признака, которые численно описывают цветок (например, длину лепестка). Давайте импортируем и просмотрим этот набор данных, чтобы лучше понять, с чем мы имеем дело.

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

Импортировав образцы данных и библиотеки, мы можем приступить к работе с нашей моделью:

здесь мы определяем новый класс «персептрон», инициализируя скорость обучения (eta) и количество итераций (n_iter). Эти два значения называются гиперпараметрами, скорость обучения — это число с плавающей запятой от 0 до 1, а количество итераций — целое число. Оптимальное значение этих двух переменных зависит от самой проблемы. Оптимизация гиперпараметров — это тема для отдельной статьи, а пока все, что нам нужно знать об этих двух, это следующее:

  • Скорость обучения (эта): интуиция здесь такова, что если скорость обучения слишком высока, наша модель выйдет за рамки допустимого.
  • Количество итераций (n_iter): это количество итераций, которые наш алгоритм будет выполнять с обучающими данными.

Теперь давайте возьмем блок-схему, которую мы обсуждали ранее, и переведем ее в код Python:

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

Функция подгонки состоит из двух вложенных циклов. Внешний цикл — это то, сколько раз алгоритм будет работать с нашим тренировочным набором, а внутренний цикл — это фактический «обход тренировочного набора». Здесь параметр «X» представляет собой двумерный массив numpy, содержащий значения функций, а «y» — это метка для каждой строки функций. Мы используем встроенное ключевое слово python zip(X, y), чтобы в основном просмотреть каждый помеченный образец.

Наиболее неотъемлемым компонентом нашего процесса обучения является обновление веса. Обновление определяется как:

Это можно рассматривать как математическое представление того, насколько правильным или неправильным было предсказание нашей модели. Чтобы лучше понять это, мы можем рассмотреть четыре возможных результата этого уравнения. Как мы упоминали ранее, каждый цветок выражается числовым значением либо 1, либо -1, где -1 — это «сетоза», а 1 — «разноцветный».

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

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

  • (1)-(-1) = 2
  • (-1)-(1) = -2

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

  • (1)-(1) = 0
  • (-1)-(-1) = 0

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

Обучение нашего персептрона

надеюсь, теперь у вас есть представление о том, что делает модель, вы также можете обратиться к комментариям в коде, если что-то неясно. Итак, приступим к обучению:

сначала мы инициализируем наш персептрон как новый объект. Мы уже импортировали наш набор данных, но здесь мы определяем его в формате, который может быть понят нашей функцией fit() (принимая функции в столбцах с индексами 0 и 2 как двумерный массив numpy и 4-й index, который является классом образца в отдельном массиве numpy). Мы также используем функцию np.where, чтобы изменить строковые значения класса на 1 (лишай) и -1 (сетоза). Затем мы можем запустить функцию fit() для наших значений X и y, чтобы обучить наш персептрон, наконец, после определенного количества итераций у нас должен быть пустой массив, содержащий наш оптимальный вес, и теперь мы можем вызывать predict() на немаркированном образце, и наш персептрон классифицирует его.

Ошибки построения

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

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

Резюме и выводы

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

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

Надеюсь, вы нашли это познавательным!

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

2015. Глава 2. Обучение простым алгоритмам машинного обучения для классификации. В С. Рашка, Машинное обучение Python (стр. 63–83). Издательство Пакет.