Рубрики
Без рубрики

Введение в нейронные сети с помощью Scikit-Learn

Автор оригинала: Scott Robinson.

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

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

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

Нервная Система Человека

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

нейрон

Персептроны

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

персептрон

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

Искусственная Нейронная Сеть (Многослойный Персептрон)

Теперь, когда мы знаем, что такое однослойный персептрон, мы можем распространить это обсуждение на многослойные персептроны, или более известные как искусственные нейронные сети. Однослойный персептрон может решать простые задачи, в которых данные линейно разделимы на ” n “измерений, где” n ” – количество объектов в наборе данных. Однако в случае нелинейно разделимых данных точность однослойного персептрона значительно снижается. С другой стороны, многослойные персептроны могут эффективно работать с нелинейно разделяемыми данными.

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

скрытый слой нейронной сети

Нейронная сеть работает в две фазы: Прямое и обратное распространение.

Обратная связь

Ниже приведены шаги, выполняемые во время фазы обратной связи:

  1. Значения, полученные во входном слое, умножаются на веса. Смещение добавляется к суммированию входных данных и весов, чтобы избежать нулевых значений.
  2. Каждый нейрон в первом скрытом слое получает различные значения от входного слоя в зависимости от веса и смещения. Нейроны имеют функцию активации, которая действует на значение, полученное от входного слоя. Функция активации может быть многих типов, таких как шаговая функция, сигмовидная функция, relu функция или tanh функция. Как правило, функция relu используется в нейронах скрытого слоя, а сигмовидная функция используется для нейрона выходного слоя.
  3. Выходы нейронов первого скрытого слоя умножаются на весы второго скрытого слоя; результаты суммируются и передаются нейронам последующих слоев. Этот процесс продолжается до тех пор, пока не будет достигнут внешний слой. Значения, вычисленные на внешнем слое, являются фактическими выходами алгоритма.

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

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

Фаза обратного распространения состоит из следующих этапов:

  1. Погрешность вычисляется путем количественной оценки разницы между прогнозируемым выходом и желаемым выходом. Эта разница называется “потерей”, а функция, используемая для вычисления разницы, называется “функцией потерь”. Функции потерь могут быть различных типов, например, среднеквадратичная ошибка или функции перекрестной энтропии. Помните, что нейронные сети-это контролируемое обучение алгоритмы, которые нуждаются в желаемых выходах для заданного набора входных данных, что позволяет им учиться на данных.
  2. После того как ошибка вычислена, следующий шаг-минимизировать эту ошибку. Для этого вычисляется частичная производная функции ошибки по всем весам и смещениям. Это называется градиентным спуском. Производные могут быть использованы для нахождения наклона функции ошибки. Если наклон положительный, то значение весов может быть уменьшено, а если наклон отрицательный, то значение веса может быть увеличено. Это уменьшает общую ошибку. Функция, которая используется для уменьшения этой ошибки, называется функцией оптимизации.

Этот один цикл прямого и обратного распространения называется одной “эпохой”. Этот процесс продолжается до тех пор, пока не будет достигнута разумная точность. Не существует стандарта разумной точности, в идеале вы стремились бы к 100% точности, но это чрезвычайно трудно достичь для любого нетривиального набора данных. Во многих случаях точность 90%+ считается приемлемой, но это действительно зависит от вашего варианта использования.

Реализация нейронной сети с помощью Scikit-Learn

Теперь мы знаем, что такое нейронные сети и какие различные шаги нам нужно выполнить, чтобы построить простую, плотно связанную нейронную сеть. В этом разделе мы попытаемся построить простую нейронную сеть, которая предсказывает класс, к которому относится данное растение ириса. Мы будем использовать библиотеку Python Scikit-Learn для создания нашей нейронной сети, которая выполняет эту задачу классификации. Инструкции по загрузке и установке библиотеки Scikit-Learn доступны по адресу: http://scikit-learn.org/stable/install.html

Примечание : Скрипты, поставляемые с этим учебником, были выполнены и протестированы в записной книжке Python Jupyter.

Набор данных

Набор данных, который мы собираемся использовать для этого урока, – это популярный набор данных Iris, доступный по адресу https://archive.ics.uci.edu/ml/datasets/iris . Подробная информация о наборе данных доступна по вышеупомянутой ссылке.

Давайте сразу перейдем к коду. Первым шагом является импорт этого набора данных в нашу программу. Для этого мы будем использовать библиотеку Python pandas .

Выполните следующую команду, чтобы загрузить набор данных iris в фрейм данных Python:

import pandas as pd

# Location of dataset
url = "https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data"

# Assign colum names to the dataset
names = ['sepal-length', 'sepal-width', 'petal-length', 'petal-width', 'Class']

# Read dataset to pandas dataframe
irisdata = pd.read_csv(url, names=names)

Вышеприведенный скрипт просто загружает данные iris, присваивает столбцам набора данных имена ‘sepal-length’, ‘sepal-width’, ‘petal-length’, ‘petal-width’ и ‘Class’, а затем загружает их в фрейм данных irisdata .

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

irisdata.head()

Выполнение приведенного выше скрипта приведет к отображению первых пяти строк нашего набора данных, как показано ниже:

Ирис-сетоза 0 0.2 3.5 1.4 5.1
Ирис-сетоза 1 0.2 3.0 1.4 4.9
Ирис-сетоза 2 0.2 3.2 1.3 4.7
Ирис-сетоза 3 0.2 3.1 1.5 4.6
Ирис-сетоза 4 0.2 3.6 1.4 5.0

Предварительная обработка

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

# Assign data from first four columns to X variable
X = irisdata.iloc[:, 0:4]

# Assign data from first fifth columns to y variable
y = irisdata.select_dtypes(include=[object])

Чтобы увидеть, как выглядит y , выполните следующий код:

y.head()
Ирис-сетоза 0
Ирис-сетоза 1
Ирис-сетоза 2
Ирис-сетоза 3
Ирис-сетоза 4

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

y.Class.unique()

Выход:

array(['Iris-setosa', 'Iris-versicolor', 'Iris-virginica'], dtype=object)

У нас есть три уникальных класса “Iris-setosa”, “Iris-versicolor” и “Iris-virginica”. Преобразуем эти категориальные значения в числовые. Для этого мы будем использовать класс Scikit-Learn LabelEncoder .

Выполните следующий сценарий:

from sklearn import preprocessing
le = preprocessing.LabelEncoder()

y = y.apply(le.fit_transform)

Теперь, если вы снова проверите уникальные значения в серии y , вы увидите следующие результаты:

array([0, 1, 2], dtype=int64)

Вы можете видеть, что категориальные значения были закодированы в числовые значения, то есть 0, 1 и 2.

Тестовый раскол поезда

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

Чтобы создать тренировочные и тестовые разбиения, выполните следующий сценарий:

from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)

Приведенный выше сценарий разбивает 80% набора данных на наш обучающий набор, а остальные 20% – на тестовые данные.

Масштабирование объектов

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

Следующий сценарий выполняет масштабирование объектов:

from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(X_train)

X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)

Обучение и прогнозы

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

from sklearn.neural_network import MLPClassifier
mlp = MLPClassifier(hidden_layer_sizes=(10, 10, 10), max_iter=1000)
mlp.fit(X_train, y_train.values.ravel())

Да, с помощью Scikit-Learn вы можете создать нейронную сеть с этими тремя строками кода, которая выполняет большую часть работы за вас. Давайте посмотрим, что происходит в приведенном выше сценарии. Первым шагом является импорт класса MLP Classifier из библиотеки sklearn.neural_network . Во второй строке этот класс инициализируется двумя параметрами.

Первый параметр, hidden_layer_sizes , используется для установки размера скрытых слоев. В нашем скрипте мы создадим три слоя по 10 узлов каждый. Стандартной формулы для выбора количества слоев и узлов нейронной сети не существует, и она довольно сильно варьируется в зависимости от конкретной задачи. Лучший способ-попробовать разные комбинации и посмотреть, что работает лучше.

Второй параметр MLP Classifier определяет количество итераций или эпох, которые вы хотите выполнить в своей нейронной сети. Помните, что одна эпоха-это комбинация одного цикла прямой и обратной фазы распространения.

По умолчанию функция активации “relu” используется с оптимизатором затрат “adam”. Однако вы можете изменить эти функции с помощью параметров activation и solver соответственно.

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

Последний шаг-сделать прогнозы по нашим тестовым данным. Для этого выполните следующий сценарий:

predictions = mlp.predict(X_test)

Оценка алгоритма

Мы создали наш алгоритм и сделали некоторые прогнозы на тестовом наборе данных. Сейчас самое время оценить, насколько хорошо работает наш алгоритм. Для оценки алгоритма наиболее часто используются такие показатели, как матрица путаницы, точность, отзыв и оценка f1. Методы confusion_matrix и classification_report библиотеки sklearn.metrics могут помочь нам найти эти оценки. Следующий скрипт генерирует отчет об оценке для нашего алгоритма:

from sklearn.metrics import classification_report, confusion_matrix
print(confusion_matrix(y_test,predictions))
print(classification_report(y_test,predictions))

Этот код выше генерирует следующий результат:

[[11  0  0]
   0  8  0]
   0  1 10]]
             precision   recall   f1-score   support
          0       1.00     1.00       1.00        11
          1       0.89     1.00       0.94         8
          2       1.00     0.91       0.95        11

avg / total       0.97     0.97       0.97        30

Из матрицы путаницы видно, что наша нейронная сеть неправильно классифицировала только одно растение из 30, на которых мы тестировали сеть. Кроме того, оценка f1 0,97 очень хороша, учитывая тот факт, что у нас было всего 150 экземпляров для тренировки.

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

учить больше

Эта статья едва царапает поверхность того, что возможно с нейронными сетями и библиотекой Scikit-Learn Python. Если вы хотите лучше понять эти темы, то я бы рекомендовал вам ознакомиться со следующими ресурсами:

    • Отлично подходит для теории нейронных сетей и многих других тем ML
    • Использует Scikit-Learn, Python, TensorFlow и многое другое
    • Преподает множество инструментов науки о данных, таких как Pandas, Matplotlib и Numpy
    • Использует Scikit-Learn и TensorFlow

Вывод

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