Настраивать

Начнем с набора данных MNIST. Поскольку мы делаем это часто, мы определим функцию для этого.

Давайте теперь вычислим среднее значение и стандартное отклонение наших данных.

Обратите внимание, что мы нормализуем набор проверки с train_mean, а не valid_mean, чтобы сохранить набор для обучения и проверки в одном масштабе.

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

Затем давайте инициализируем нашу нейронную сеть.

Проблемы с инициализацией

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

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

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

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

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

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

Выбор правильного коэффициента масштабирования - Xavier init

Каким должно быть значение коэффициента масштабирования?

Ответ (1 / ⎷вход). Этот метод инициализации известен как инициализация Xavier. Если вы хотите узнать о математике, стоящей за этим, вы можете прочитать исходную статью или одну из справочных статей, упомянутых в конце этой статьи. Хороший совет при чтении исследовательских работ - поиск статей, в которых они резюмируются.

И деление на ⎷input действительно работает. Обратите внимание, что если мы хотим сохранить градиенты при обратном проходе, мы должны разделить их на output.

Документ по инициализации Xavier также предоставляет ряд хороших визуализаций, как показано ниже.

Проблема с Xavier init

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

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

Решение этой проблемы было предложено в статье Углубляясь в выпрямители: превосходя человеческий уровень по классификации ImageNet.

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

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

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

Если вы хотите узнать больше о глубоком обучении, ознакомьтесь с серией моих статей об этом:



Использованная литература:

  1. Глубокое обучение с самого начала, fast.ai
  2. Понимание инициализации Xavier в глубоких нейронных сетях.
  3. Как инициализировать глубокие нейронные сети?
  4. Примечания по инициализации веса для глубоких нейронных сетей
  5. Дисперсия произведения нескольких случайных величин