Введение в искусственные нейронные сети в Python

Оглавление

Представленная реализация на языке Python может быть найдена в репозитории на Github.

Биология вдохновляет искусственную нейронную сеть

Искусственная нейронная сеть (ИНС) - это попытка моделирования возможностей биологической нервной системы по обработке информации. Человеческий организм состоит из триллионов клеток, а клетки нервной системы, называемые нейронами, специализированы для передачи "сообщений" с помощью электрохимических процессов. Узлы ANN эквивалентны узлам наших нейронов, узлы которых соединены между собой синаптическими весами (или просто весами) - эквивалент синаптических связей между аксонами и дендритами биологического нейрона.

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

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

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

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

Что может делать искусственная нейронная сеть?

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

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

Анны успешно применяются в самых разных областях, таких как:

  • Классификация данных - Этот цветок - роза или тюльпан?
  • Определение аномалий - Является ли конкретная активность пользователя на сайте потенциально мошенническим поведением?
  • Распознавание речи - Эй, Siri! Можешь рассказать мне анекдот?
  • Генерация аудио - Jukedeck, можешь сочинить бодрящую народную песню?
  • Анализ временных рядов - Хорошее
  • ли сейчас время для начала инвестирования в фондовый рынок?

И список можно продолжать...

Начальная модель ИНС

Модель нейрона Мак-Каллоха-Питтса (модель 1943 года)

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

McCulloch-Pitts Model of Neuron

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

На рисунке ниже представлена общая модель нейрона Мак-Каллоха-Питтса.

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

При подаче на сеть первого набора входных сигналов, т.е. (0, 0), он умножается на веса сети, получая сумму следующим образом: (0*1) + (0*1) = 0 (refer eq. 1). Здесь сумма 0 меньше порогового значения 0,5, следовательно, на выходе будет 0 (см. рис. 2).

Тогда как для второго набора входов (1,0) сумма (1*1) + (0*1) = 1 больше порога 0,5, следовательно, на выходе будет 1.

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

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

Перцептронная модель

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

perceptron model artificial neural networks

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

artificial neural networks equation

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

Многослойная перцептронная модель

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

Multilayer perceptron model

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

Многослойный перцептрон состоит из трех основных компонентов:

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

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

Фаза обучения нейронной сети

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

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

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

Процесс обучения состоит из трех (общих) этапов:

1. Инициализация весов

Веса в сети инициализируются небольшими случайными числами (например, в диапазоне от -1 до 1 или от -0,5 до 0,5). Каждый блок имеет смещение, связанное с ним, и смещения аналогично инициализируются небольшими случайными числами.

def initialize_weights():
    # Generate random numbers
    random.seed(1)

    # Assign random weights to a 3 x 1 matrix
    synaptic_weights = random.uniform(low=-1, high=1, size=(3, 1))
    return synaptic_weights

2. Распространить вход вперед

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

artificial neural networks

Наши сигмоидальные функции полезности определяются следующим образом:

def sigmoid(x):
    return 1 / (1 + exp(-x))


def sigmoid_derivative(x):
    return x * (1 - x)

3. Распространение ошибки

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

Для нейрона j (также обозначаемого как unit j) выходного слоя ошибка вычисляется следующим образом:

Errj = Oj*(1 – Oj )*( Tj – Oj ) ……………….. (5)

Где Tj - ожидаемый выход, Oj - прогнозируемый выход, а Oj *(1 – Oj) - производная сигмоидальной функции.

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

Wij = Wij + (l*Errij*Oj ) ………………………. (6)
bi = bj + (l* Errij) ……………………………….  (7)

Выше, l - скорость обучения, константа, обычно изменяющаяся в пределах от 0 до 1. Она определяет скорость изменения значений весов и смещения. Если скорость обучения велика, то веса и смещение будут резко меняться с каждой эпохой. Если же она слишком мала, то изменения будут происходить очень медленно.

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

  • Ошибка минимизирована до минимально возможного значения
  • Обучение прошло максимальное количество итераций
  • Дальнейшее уменьшение значения ошибки не происходит
  • Ошибка обучения практически совпадает с ошибкой проверки

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

def learn(inputs, synaptic_weights, bias):
     return sigmoid(dot(inputs, synaptic_weights) + bias)

def train(inputs, expected_output, synaptic_weights, bias, learning_rate, training_iterations):
     for epoch in range(training_iterations):
          # Forward pass -- Pass the training set through the network.
          predicted_output = learn(inputs, synaptic_weights, bias)

        # Backaward pass
        # Calculate the error
        error = sigmoid_derivative(predicted_output) * (expected_output - predicted_output)

        # Adjust the weights and bias by a factor
        weight_factor = dot(inputs.T, error) * learning_rate
        bias_factor = error * learning_rate

        # Update the synaptic weights
        synaptic_weights += weight_factor

        # Update the bias
        bias += bias_factor

        if ((epoch % 1000) == 0):
            print("Epoch", epoch)
            print("Predicted Output = ", predicted_output.T)
            print("Expected Output = ", expected_output.T)
            print()
    return synaptic_weights

Собираем все воедино

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

# Initialize random weights for the network
    synaptic_weights = initialize_weights()

    # The training set
    inputs = array([[0, 1, 1],
                    [1, 0, 0],
                    [1, 0, 1]])

    # Target set
    expected_output = array([[1, 0, 1]]).T

    # Test set
    test = array([1, 0, 1])

    # Train the neural network
    trained_weights = train(inputs, expected_output, synaptic_weights, bias=0.001, learning_rate=0.98,
                            training_iterations=1000000)

    # Test the neural network with a test example
    accuracy = (learn(test, trained_weights, bias=0.01)) * 100

    print("accuracy =", accuracy[0], "%")

Заключение

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

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

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

Попробуйте сами

Лучший способ обучения - это самостоятельная попытка, поэтому вот несколько вопросов, на которые вы можете попробовать ответить, используя концепции, которые мы изучили в этой заметке:

  1. Можно ли построить XOR-модель, изменяя веса и пороги?
  2. Попробуйте добавить в нейронную сеть более одного скрытого слоя и посмотрите, как изменится этап обучения.

До встречи в следующем посте!

Вернуться на верх