Из Paperspace Айюша Катурии, составленного Heart of the Machine.
Эта статья является вводной статьей о методе оптимизации глубокого обучения — градиентном спуске. В длинном сообщении в блоге автор кратко представляет концепцию, преимущества и две основные проблемы градиентного спуска. Текст также снабжен большим количеством ярких трехмерных изображений.Если вам интересно, пожалуйста, посмотрите?
В значительной степени глубокое обучение на самом деле решает множество надоедливых проблем оптимизации. Нейронная сеть — это просто очень сложная функция с миллионами параметров, которые представляют собой математическое решение задачи. Взяв в качестве примера классификацию изображений, AlexNet представляет собой математическую функцию, которая принимает в качестве входных данных массив значений RGB, представляющих изображение, и выдает набор оценок классификации.
По сути, обучая нейронную сеть, мы минимизируем функцию потерь. Значение этой функции потерь измеряет, насколько далека от совершенства производительность нашей сети в заданном наборе данных.
функция потерь
Для простоты предположим, что наша сеть имеет только два параметра. На самом деле их около миллиарда, но мы остановимся на примере с двумя параметрами в этом посте, чтобы не сойти с ума, пытаясь визуализировать его. Схема большой функции потерь может выглядеть так.
Схема функции потерь
Почему я говорю, что это отличная функция потерь? Потому что функции потерь с таким профилем, как у Деда Мороза, не существует. Тем не менее, это по-прежнему хороший учебный инструмент для всестороннего понимания некоторых наиболее важных идей градиентного спуска. Итак, давайте начнем здесь.
Ось x и ось y представляют два веса соответственно, а ось z представляет значение функции потерь с учетом двух конкретных весов. Наша цель — найти удельный вес с наименьшими потерями, эта точка называется точкой минимума функции потерь.
В начале вы инициализировали веса случайным образом, поэтому ваша нейронная сеть может вести себя как пьяная, классифицируя изображения кошек как людей. Эта ситуация соответствует точке А на контуре функции потерь, где производительность сети очень низкая, поэтому потери также велики.
Нам нужно найти способ перейти в точку «долины» B, где значение функции потерь минимально. Так что же нам делать?
градиентный спуск
При инициализации весов мы находимся в точке А на графике функции потерь. Первое, что нужно сделать, это посмотреть на все возможные направления в плоскости x-y и посмотреть, в каком направлении значение функции потерь падает быстрее всего. Это направление, в котором мы должны двигаться, прямо противоположно направлению градиента. Градиент — это еще один термин для многомерной производной, которая дает направление наискорейшего подъема.
Чтобы понять эту концепцию, посмотрите на диаграмму ниже. В любой точке поверхности мы можем задать касательную к ней плоскость. В более высоких измерениях мы всегда можем определить гиперплоскость, но здесь мы придерживаемся трехмерного пространства. Тогда в этой плоскости существует бесконечное количество направлений. Среди них есть только одно направление, заставляющее функцию расти быстрее всего, которое задается градиентом, а противоположное направление — это направление наискорейшего спуска. Отсюда и название алгоритма, мы спускаемся в направлении градиента, поэтому он называется градиентным спуском.
Теперь, когда у нас есть направление для движения вперед, мы должны определить размер шагов, которые нам нужно сделать, и параметром, который управляет размером нисходящего шага, является скорость обучения. Чтобы сохранить минимум, мы должны тщательно выбирать скорость обучения.
Если двигаться слишком быстро, мы можем пересечь минимум, прыгая по гребням «долины», и никогда не достичь минимума. Если движение слишком медленное, обучение может занять слишком много времени, чтобы вообще быть выполнимым, а слишком низкая скорость обучения может легко привести алгоритм к минимуму, который мы обсудим позже в этой статье.
Получив градиенты и скорость обучения, мы начинаем действовать, затем пересчитываем градиенты, где бы мы ни оказались, и повторяем процесс.
Направление градиента говорит нам, в каком направлении самый быстрый подъем, а его величина говорит нам, насколько крутым является самый крутой подъем/спуск. Итак, в минимуме профиль поверхности почти плоский и мы ожидаем получить почти нулевой уклон. На самом деле градиент точки минимума равен 0.
На практике мы можем никогда точно не достичь минимума, но мы можем колебаться в плоской области вокруг минимума. Когда мы колеблемся в этой области, величина убытка почти настолько мала, насколько это возможно, и не сильно меняется, потому что мы прыгаем вокруг истинного минимума. Обычно мы останавливаем итерации, когда значение потерь не улучшается в пределах заданного числа, например 10 или 20 итераций. Когда это происходит, мы говорим, что обучение конвергентно или что конвергенция достигнута.
распространенные ошибки
Позволю себе немного отойти от темы. Если вы ищете визуализацию градиентного спуска, вы, скорее всего, увидите траекторию, которая начинается в точке и заканчивается в минимальной точке, как показано на анимации выше. Однако это описание градиентного спуска не является точным. Траектория, которую мы получаем, полностью ограничена плоскостью x-y, которая содержит веса.
Как показано на анимации выше, градиентный спуск не включает движение в направлении оси Z. Потому что веса, описываемые только направлениями осей x и y, являются свободными параметрами. Фактическая полученная траектория определяется в плоскости x-y, как показано на следующем рисунке:
Каждая точка на плоскости x-y представляет уникальную комбинацию весов, и мы хотим иметь набор весов, описываемых минимальным значением.
основное уравнение
Основное уравнение, описывающее правило обновления градиентного спуска:
Обновление выполняется на каждой итерации. Здесь w — весовой вектор, лежащий в плоскости x-y. Мы вычитаем из этого вектора скорость обучения, умноженную на градиент функции потерь по отношению к весам. Градиент — это вектор, задающий направление, в котором функция потерь возрастает быстрее всего. Направление самого быстрого спуска прямо противоположно направлению градиента, поэтому вектор градиента вычитается из вектора весов.
Если представление векторов для вас немного сложно, то практически одни и те же правила обновления применяются ко всем весам сети одновременно. Единственное изменение заключается в том, что теперь мы выполняем обновление для каждого веса отдельно, а градиент в приведенном выше уравнении заменяется проекцией вектора градиента вдоль направления конкретного веса.
Обновите все веса одновременно.
Перед выполнением вычитания мы умножаем вектор градиента на скорость обучения. Это шаг, который мы обсуждали ранее. Имейте в виду, что даже если мы сохраним скорость обучения постоянной, размер шага будет варьироваться из-за размера градиента, то есть крутизны профиля функции потерь. По мере приближения к минимуму градиент будет приближаться к 0, и мы будем приближаться к минимуму все меньшими и меньшими шагами.
Теоретически это нормально, потому что мы хотим, чтобы алгоритм делал меньшие шаги при приближении к минимуму. Слишком большой размер шага может привести к пропуску минимумов и скачкам вперед и назад между гребнями минимумов.
Обычный метод, используемый в градиентном спуске, заключается в использовании переменной скорости обучения вместо фиксированной скорости обучения. Первоначально мы можем использовать большую скорость обучения. Но позже, по мере приближения к точке минимума, нам нужно притормозить. Одним из способов реализации этой стратегии является имитация отжига или снижение скорости обучения. В этом случае скорость обучения постепенно снижается в зависимости от количества итераций, которое может выполнить заинтересованная сторона.
Одна из задач градиентного спуска: локальные минимумы
Пока что история с градиентным спуском звучит очень хорошо. Теперь позвольте мне приоткрыть завесу над этим. Помните, я говорил ранее, что есть хорошая функция потерь, но этой функции потерь не существует? Их действительно не существует.
Во-первых, нейронные сети — это сложные функции, и мы вводим множество нелинейных преобразований в гипотетические функции. Результирующая функция потерь выглядит не очень хорошо, опять же, есть только одна минимальная точка, к которой мы можем сойтись. На самом деле, эта идеальная функция потерь называется «выпуклой функцией» (функция, которая всегда изгибается вверх), а функцию потерь глубокой сети трудно назвать выпуклой. На самом деле они, скорее всего, будут выглядеть так:
На изображении выше есть точки локальных минимумов с градиентом 0. Однако точка глобального минимума, которую мы хотим достичь, недостижима. Теперь, если вы инициализируете веса в точке A, вы сойдетесь к локальному минимуму, и, как только вы сойдетесь к этому минимуму, градиентный спуск не сможет вывести вас отсюда.
Градиентный спуск управляется градиентами, которые стремятся к 0 в любой точке минимума. Локальные минимумы называются локальными минимумами, потому что значение функции потерь в этой точке является наименьшим в данной области. Глобальный минимум называется глобальным минимумом, потому что значение функции потерь в этой точке является наименьшим во всей области.
Что еще хуже, поскольку трехмерный профиль функции потерь, который мы рассматриваем, никогда не встречается на практике, профиль функции потерь может быть более сложным. На практике наша нейронная сеть будет иметь около 1 миллиарда весов, что дает нам функцию примерно (1 миллиард + 1) измерений.
На самом деле, трудно представить, как будет выглядеть функция с таким количеством измерений. Тем не менее, область глубокого обучения сейчас полна талантов, и люди придумали способы визуализации профиля функции потерь в 3D. В недавней статье предлагается метод под названием «Нормализация фильтра», который объясняет вещи, выходящие за рамки этой статьи. Тем не менее, это позволяет нам увидеть основную сложность функции потерь, с которой мы имеем дело. Например, на рисунке ниже представлена трехмерная архитектура функции потерь, построенная VGG-56 на основе набора данных CIFAR-10.
Как видите, везде есть локальные минимумы.
Испытание градиентного спуска 2: седловые точки
Основной урок, который мы усвоили об ограничениях градиентного спуска, заключается в том, что как только вы достигаете области, где градиент равен 0, из нее мало что можно выбрать, независимо от качества минимумов. Еще одна проблема, с которой мы сталкиваемся, — это седловые точки, которые имеют следующую форму:
Вы также можете увидеть седловую точку, где встречаются два пика на предыдущем рисунке.
Седловая точка получила свое название из-за своей формы, напоминающей седло. Хотя это точка минимума в направлении х, она является точкой локального максимума в другом направлении, и, если она станет более плоской вдоль направления х, градиентный спуск будет колебаться по оси х и не может продолжаться согласно закону у. ось идет вниз, что создает иллюзию того, что мы сошлись в точке минимума.
Случайность в помощь
Так как же нам избавиться от локальных минимумов и седловых точек, пытаясь сходиться к глобальному оптимуму? Ответ заключается в использовании стохастического градиентного спуска.
До сих пор мы выполняли градиентный спуск с использованием функции потерь, полученной путем суммирования значений потерь для всех возможных выборок на обучающем наборе. Если мы попадаем в локальные минимумы или седловые точки, мы застреваем. Один из способов помочь градиентному спуску решить эти дилеммы — стохастический градиентный спуск.
В стохастическом градиентном спуске вместо вычисления градиента функции потерь путем суммирования всех функций потерь мы предпринимаем шаги, вычисляя градиент потерь только для одного случайно выбранного (без замены) примера. Каждый образец в стохастическом градиентном спуске выбирается случайным образом, в отличие от более ранних методов, которые обрабатывают все образцы в одной партии, отсюда и название пакетного градиентного спуска.
Соответственно были изменены и правила обновления.
Это означает, что функция потерь, которую мы используем на каждом шаге, отличается от фактической функции потерь (это сумма функций потерь для каждого образца). Градиент этой «функции потерь для одной выборки» в конкретной точке может фактически указывать в несколько ином направлении, чем градиент «функции потерь для всей выборки».
То есть, хотя градиент «функции потерь для всей выборки» может подтолкнуть нас к локальному минимуму или заманить нас в седловую точку, градиент этой «функции потерь для одной выборки» может указывать в другом направлении и потенциально помогите нам избежать таких ситуаций.
Следует также учитывать локальную точку минимума «функции потери всех выборок». Если бы мы использовали пакетный градиентный спуск, мы бы застряли здесь, потому что градиент всегда указывал бы на локальный минимум. Однако, если мы используем стохастический градиентный спуск, эта точка может не находиться около локального минимума контура «функции потерь одной выборки», что отдаляет нас от точки локального минимума.
Даже если мы застряли на локальном минимуме «функции потерь одной выборки», ситуация потерь «функции потерь одной выборки» может быть другой для следующей случайной точки выборки, что позволяет нам продолжать движение.
Когда он сходится, он сходится к минимуму почти всех «функций потерь одной выборки». Опыт также показал, что седловая точка крайне неустойчива и может быть сброшена легким толчком.
Значит ли это, что этот одновыборочный стохастический градиентный спуск следует использовать на практике?
размер партии
ответ отрицательный. Хотя стохастический градиентный спуск теоретически может дать нам наилучшие результаты, это не очень жизнеспособный вариант с вычислительной точки зрения. Когда мы выполняем градиентный спуск, используя функцию, полученную путем сложения всех отдельных функций потерь, градиенты всех отдельных функций потерь можно вычислять параллельно, в то время как при стохастическом градиентном спуске вычисления градиента должны выполняться последовательно одно за другим.
Так что то, что мы делаем, является балансирующим актом. Вместо использования всего набора данных или отдельных выборок мы формируем мини-партию с фиксированным количеством выборок (например, 16, 32 или 128) для построения функции потерь. Этот термин отличается от одновременной обработки всех образцов, которую часто называют пакетным градиентным спуском. Размер мини-пакета выбран, чтобы гарантировать, что у нас будет достаточно случайности, чтобы избавиться от локальных минимумов, используя при этом достаточную вычислительную мощность параллельных вычислений.
Еще раз о локальных минимумах: они не так плохи, как вы думаете
Не спешите спорить с локальными минимумами, недавние исследования показывают, что локальные минимумы не обязательно плохи. В случае потерь нейронной сети просто слишком много минимумов, и хорошие локальные минимумы могут быть такими же хорошими, как и глобальные минимумы.
Почему я сказал да? Потому что вы все еще можете застрять в локальных минимумах, вызванных нестабильными обучающими выборками. Хорошие локальные минимумы или оптимальные локальные минимумы, как упоминается в литературе, также могут быть в изобилии в многомерной функции потерь данной нейронной сети.
Вы также можете заметить, что многие нейронные сети выполняют задачи классификации. Если локальный минимум соответствует правильной оценке метки 0,7–0,8, а глобальный минимум дает правильную оценку метки 0,95–0,98, то предсказанные метки, выводимые обоими, будут одинаковыми.
Идеальное свойство минимума состоит в том, что он должен быть на плоской стороне. Зачем? Потому что плоские минимумы легко сходятся и с меньшей вероятностью пересекают минимумы или прыгают между гребнями минимумов.
Что еще более важно, мы ожидаем, что поверхность потерь для тестового набора будет немного отличаться от поверхности потерь для тренировочного набора, на котором мы тренируемся. Для плоских и широких минимумов потери не сильно меняются из-за этого изменения, но не для относительно узких минимумов. Один момент, на который мы хотели бы обратить внимание, заключается в том, что более плоские минимумы лучше обобщают и поэтому желательны.
Пересмотр скорости обучения
В последнее время наблюдается всплеск исследований по планированию скорости обучения для субоптимальных минимумов функций потерь. Даже если скорость обучения снижается, можно застрять в локальных минимумах. Традиционно обучение либо завершается после фиксированного количества итераций, либо останавливается после фиксированного количества итераций (скажем, 10), если нет улучшения значения потерь. Это состояние упоминается в литературе как ранняя остановка.
Использование более высокой скорости обучения также помогает нам пропускать некоторые локальные минимумы на ранних этапах обучения.
Люди также комбинируют раннюю остановку со снижением скорости обучения, когда скорость обучения начинает снижаться без какого-либо улучшения функции потерь после 10 итераций и в конечном итоге останавливается, когда скорость обучения падает ниже определенного порога.
В последние годы стали популярными повторяющиеся скорости обучения, при которых скорость обучения медленно увеличивается, а затем медленно снижается, продолжая циклически.
Так называемый стохастический градиентный спуск с теплыми перезапусками в основном отжигает скорость обучения до нижней границы, а затем восстанавливает скорость обучения до ее начального значения.
У нас также есть разные планы снижения скорости обучения, например, от экспоненциального затухания до косинусного затухания.
В недавней статье был представлен метод, называемый «стохастическим взвешенным усреднением». Авторы предлагают метод, который сначала сходится к минимальному значению, кэширует веса, а затем восстанавливает скорость обучения до более высокого значения. Эта более высокая скорость обучения затем подталкивает алгоритм от минимума к случайным точкам на поверхности потерь. Затем снова заставьте алгоритм сходиться к другому минимуму. Это повторяется несколько раз, и, наконец, они усредняют прогнозы из всех кэшированных наборов весов, чтобы получить окончательный прогноз.
в заключении
Итак, это вводная статья о градиентном спуске, которая является движущей силой работы по оптимизации в глубоком обучении, потому что основополагающая статья об обратном обучении показала, что можно обучать нейронные сети, вычисляя градиенты. Однако в градиентном спуске есть одна недостающая часть, о которой мы не говорили в этом посте, и это касается патологического искривления. Для решения этой ключевой проблемы используются расширения классического стохастического градиентного спуска, такие как Momentum, RMSProp и Adam.
Однако я чувствую, что того, что мы сделали, достаточно для одной статьи, а об остальном позаботится другая статья.
Оригинальная ссылка:blog.paper space.com/intro-to-op…