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

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

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

Хорошо, давайте углубимся (да, я знаю, ... ничего не могу с собой поделать!) В этот захватывающий материал.

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

Итак, что такое нейронная сеть?

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

Проще говоря, нейронная сеть пытается изучить функцию «f», которая может соединить вход X с выходом Y (проще, но не так привлекательно, правда?) Это можно представить как:

Здесь «нейрон» вычисляет эту функцию «f», которая может быть линейной или нелинейной.

ЛОГИСТИЧЕСКАЯ РЕГРЕССИЯ

Перейдем к использованию нейронной сети для двоичной классификации. В этом случае выход Y может принимать значение 0 или 1.

Учитывая входной вектор признаков X, мне нужен алгоритм, который может выводить прогноз, ŷ, который является оценкой Y.

По сути, ŷ - это вероятность того, что Y равно 1, с учетом входных характеристик X.

Как мы генерируем этот вывод ŷ Другими словами, какую функцию мы можем использовать для подключения ŷ к X с помощью некоторых параметров w и b?

Мы могли бы подумать об использовании линейной функции, такой как ŷ = w * X + b (технически это должно быть w transpose (wT), (поскольку X и w являются размерными векторами, но давайте просто пропустим эту «деталь» ради Это не поможет нам в оценке этого сценария, поскольку ŷ линейно связана с X, поэтому может принимать любое значение.

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

Сигмовидная функция определяется как:

который представлен как:

Назовем z нашим линейным выражением, о котором мы упоминали ранее, поэтому

z= wT+b

а значит, применив к нему сигмовидную функцию, мы получим:

ŷ = σ (z) = σ(wT*X + b)

Отлично, мы подошли к модели логистической регрессии!

Напомним, что мы до сих пор определили:

У нас есть вход, определенный набором обучающих примеров X с его метками Y, и выход ŷ как сигмоид линейной функции. (ŷ = σ (wT * X + b)).

Нам нужно изучить параметры w и b, чтобы на обучающем наборе результат ŷ (прогноз на обучающем наборе) был близок к наземным меткам истинности Y.

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

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

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

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

Если y = 1, то

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

С другой стороны, если y = 0, то

Чтобы минимизировать потери, нам нужно, чтобы ŷ было маленьким, поэтому близко к 0.

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

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

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

Как только мы это сделаем, мы обновляем параметры w и b, используя градиентный спуск, который вычисляет производные функции стоимости по w и b как:

Хорошо, время для примера! Давайте использовать сеть с двумя входами.

Наши входные данные - это x1, x2 с соответствующими параметрами w1, w2 и b. Затем мы можем вычислить «z» как линейную функцию от них, а затем применить к нему сигмовидную функцию (названную «a» на графике ниже) и, наконец, вычислить функцию потерь «a» по отношению к y.

Мы изобразили прямой проход логистической регрессии.

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

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

Таким образом, мы находим параметры w1, w2 и b, которые минимизируют ошибку между нашим предсказанием и истинностью.

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

Формула прямого распространения:

Для обратного распространения:

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

________________________

НЕЙРОННАЯ СЕТЬ:

В логистической регрессии мы увидели, как эта модель

соответствует следующему расчетному графу:

Нейронная сеть (с одним скрытым слоем) выглядит так:

где каждый узел («нейрон») соответствует предыдущему двухэтапному вычислению «z» и «a».

Так что подумайте о чем-то вроде этого:

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

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

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

В этом случае мы оптимизируем следующие параметры:

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

Прежде чем перейти к более сложной нейронной сети (глубокой нейронной сети), я хочу подробнее рассказать о функции активации и инициализации параметров w и b.

_ _ _ _ _ _ _

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

До сих пор мы использовали сигмовидную функцию в качестве функции активации (это когда мы делаем a = σ (z), помните?), Которая, как вы помните, определяется этой кривой:

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

Для них у нас есть лучший вариант: функция tanh (z):

Это «центрировано» вокруг 0 ​​и принимает значения от -1 до 1:

Хотя для скрытых слоев чаще всего используется функция ReLU (выпрямленная линейная единица):

Это соответствует линейной кривой для положительных значений и 0 везде:

Вариантом этого является функция LeakyReLU:

Это позволяет получить небольшой ненулевой градиент, когда устройство неактивно:

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

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

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

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

_ _ _ _ _ _ _

Инициализация параметров:

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

Отличный вопрос! Короткий ответ: случайная инициализация.

Более длинный ответ:

Попробуем облегчить задачу: смещение b можно инициализировать нулем. Это не имело бы значения.

Напротив, для весов w все будет сложно (или даже проблематично!), Если мы не инициализируем их правильно.

Фактически, нам нужно инициализировать веса маленькими случайными значениями!

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

Чтобы сделать это более интуитивно понятным, давайте посмотрим на кривую функции tanh. Большое число (в абсолютном выражении) будет либо близко к +1, либо к -1. Глядя на график, вы видите, что в этом положении наклон практически близок к нулю. Помните, что такое производная переменной? Это наклон касательной к кривой. А производная - это то, что мы используем в градиентном спуске для обновления наших параметров.

Итак, наклон ~ 0 означает производную ~ 0, что означает очень небольшое изменение вариации, что означает медленное обучение!

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

_______________________

Если вы зашли так далеко - спасибо!

Последний этап - создание глубокой нейронной сети. Ну наконец то!

ГЛУБОКАЯ НЕЙРОННАЯ СЕТЬ:

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

Логистическая регрессия, с которой мы начали, в основном была просто «мелкой» сетью.

Ниже представлена ​​глубокая нейронная сеть с 4 слоями (3 скрытых слоя и один выходной слой):

Вот немного номенклатуры:

Мы вычисляем, как и раньше, обновление прямого, обратного распространения и градиентного спуска для каждого слоя «l», чтобы получить параметры w и b (в каждом слое), которые минимизируют окончательную функцию стоимости.

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

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

Существует теория, называемая «теорией цепей», которая гласит:

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

Хороший хедз-ап, когда вы создаете свою собственную модель нейронной сети!

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

До следующего раза!

Этот блог основан на лекциях Эндрю Нг на DeepLearning.ai