Недавно я углубился в эту область, пройдя специализацию Эндрю Нг по глубокому обучению (настоятельно рекомендуется!). Я многому научился, поэтому решил написать статью, чтобы объединить то, что я узнал по специальности, и некоторые из моих собственных знаний.

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

В этой статье я расскажу о нейронных сетях. Начало статьи будет более общим, и по мере продвижения по статье концепции будут становиться все более и более техническими. Итак, приступим!

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

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

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

Различные типы нейронных сетей

ИНС. Искусственные нейронные сети - это классическая форма нейронных сетей, о которой мы поговорим далее в этой статье. На данный момент эти нейронные сети состоят из трех основных разделов - входного слоя, скрытых слоев и выходного слоя.

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

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

Обзор ИНС

Прежде чем углубиться в ИНС, я хочу обсудить, почему эти модели называются «нейронными сетями».

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

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

Теперь вы можете понять, почему нейронные сети названы так. Но раньше я сказал, что они «вольно» смоделированы по нейронам.

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

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

Персептроны

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

  • Входы
  • Параметры (веса и смещения)
  • Взвешенная сумма
  • Функции активации

Входы

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

Параметры

Итак, каковы параметры? Параметры - это основа глубокого обучения. Когда люди говорят, что модель «обучается», на самом деле они имеют в виду, что параметры постоянно обновляются.

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

Есть два основных параметра модели: веса и смещения.

Веса отвечают за указание значимости каждой входной функции. Каждый вес умножается на каждую характеристику.

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

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

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

Тогда будет добавлена ​​единица смещения, в данном случае 10. Теперь модель может вывести 10.

Взвешенная сумма

Следующая часть перцептрона - это взвешенная сумма.

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

Функции активации

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

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

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

Некоторые функции активации:

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

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

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

Теперь вы понимаете, как работает отдельный перцептрон. Итак, давайте все вместе.

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

Возвращаясь к идее «черного ящика», теперь становится ясно, почему многие люди не понимают, что происходит в скрытых слоях. Случайные значения выводятся из каждого перцептрона и передаются на следующий уровень. И, в конце концов, возвращаются правильные результаты.

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

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

В примере с ценой на жилье, если у нас есть 10 функций и 1000 обучающих примеров, X будет матрицей (10, 1000), а y будет вектором (1, 1000).

Прямое распространение - это когда входные данные передаются в нейронную сеть, «распространяются вперед по слоям» и получают выходные данные.

Но что именно умножается на то, что в нейронной сети?

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

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

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

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

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

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

Давайте быстро рассмотрим мини-пример.

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

Теперь добавьте к нему вектор смещения, но как именно добавить вектор (5, 1) к матрице (5, 1000)?

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

Как только это будет рассчитано, просто примените покомпонентную функцию активации, и у вас есть свои результаты!

Это происходит снова и снова на каждом слое, пока вы не получите окончательные результаты модели.

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

Теперь мы можем видеть все вычисления, которые происходят на каждом уровне сети.

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

Теперь мы поняли, как модель может делать прогнозы. Но как модель «учится»?

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

Функция затрат

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

Эта функция стоимости аналогична функции стоимости модели логистической регрессии. Некоторые обозначения:

По сути, функция сравнивает каждое отдельное значение, выводимое в последнем слое, с «реальным» значением для каждого отдельного обучающего примера, отсюда и символы суммирования для m и k. Логарифм используется для наказания модели на основе выходных данных.

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

Вот тут-то и светится логарифм. Вот график следующей функции

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

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

Теперь вывод функции стоимости зависит от значений весов и смещения, поскольку они отвечают за прогнозы модели (как мы видели при прямом распространении). Цель модели - найти идеальные значения параметров, которые минимизируют функцию стоимости.

Градиентный спуск

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

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

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

Что именно это нам говорит? Градиент представляет собой направление наискорейшего подъема.

Боковое примечание: это верно, поскольку скалярное произведение между градиентом и вектором направления максимизируется, когда градиент находится в том же направлении, что и вектор направления.

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

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

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

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

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

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

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

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

Нахождение частных производных

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

Это найдет частные производные для второго слоя. Чтобы найти его для первого слоя, снова примените цепное правило.

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

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

TL;DR

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

Если вам понравилась эта статья:

  • Смело хлопайте 👏
  • Свяжитесь со мной в LinkedIn или загляните на мой сайт, чтобы узнать обо мне больше!