Нежное введение в нейронные сети

Нейронные сети III: общая картина

Эта серия постов о нейронных сетях является частью коллекции заметок во время Facebook PyTorch Challenge, предшествующей Программе глубокого обучения наностепеней в Udacity.

Содержание

  1. Введение
  2. Сети как функции
  3. Давайте увеличим размеры
  4. Размер партии

1. Введение

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

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

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

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

2. Превратите сеть в функцию

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

Во-первых, у нас есть ввод двух измерений. Это означает, что у нас есть 2 разных понятия, например, температура и давление. Наши входные нейроны отображают эти 2 входных измерения в 3 скрытых измерения, которые представляют собой количество нейронов в скрытом слое. Таким образом, размеры этой матрицы должны быть (2x3). Кроме того, он не представлен для более четкой визуализации, но у нас есть термин «b», чтобы добавить смещение после умножения матрицы. Это приводит к этой ситуации:

Теперь у нас есть все инструменты, необходимые для доступа к скрытому слою. Нам просто нужно применить умножение матриц:

Результатом этого будет:

Помните, что каждый входной вес соединяет каждый вход i с каждым нейроном j. Вот почему обозначение Wij, соединяющее i с j.

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

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

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

Теперь у нас есть все инструменты для применения веса нашего скрытого слоя. Уравнение, которое необходимо выполнить, тогда:

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

3. Увеличим размеры

Мы прошли весь прямой проход для одного наблюдения двух измерений. Так, например, у нас была Temperature=20ºC, P=1bar. Но кто может чему-то научиться с помощью одного лишь наблюдения? Нам нужно знать больше, чтобы улучшить свои знания о том, что нас окружает, и уметь находить закономерности в этом. Если мы хотим научиться играть в шахматы, нам обязательно нужно попробовать это несколько раз. Усложняет ли этот факт процесс? Конечно, нет! Давайте рассмотрим это.

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

Таким образом, наш ввод выглядит следующим образом:

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

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

И, наконец, применяя уравнение 2 для расчета выхода:

4. Размер партии

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

В чем разница?

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

Мини-пакет SGD принимает, как показано в разделе 3, пакет входных данных и передает их все вместе в прямом проходе, усредняя ошибки каждого из них в одну ошибку для мини-пакета.

В чем преимущество использования мини-пакета?

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

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

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

Это ядро kaggle — отличный источник для лучшего понимания того, как размер пакета влияет на оптимизатор.