Документация Engee

Правила оптимизации

Flux содержит множество правил оптимизации для использования с функцией train! и другими обучающими функциями.

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

Подробную информацию о работе нового интерфейса можно найти в документации по Optimisers.jl.

Подробную информацию о том, как работал старый «неявный» интерфейс, можно найти в руководстве по Flux 0.13.6.

Справка по оптимизатору

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

# Flux.Optimise.DescentType

Descent(η = 0.1)

Классический оптимизатор градиентного спуска со скоростью обучения η. Для каждого параметра p и его градиента δp выполняет p -= η*δp

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

Примеры

opt = Descent()

opt = Descent(0.3)

ps = Flux.params(model)

gs = gradient(ps) do
    loss(x, y)
end

Flux.Optimise.update!(opt, ps, gs)

# Flux.Optimise.MomentumType

Momentum(η = 0.01, ρ = 0.9)

Оптимизатор градиентного спуска со скоростью обучения η и импульсом ρ.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Импульс (ρ): управляет ускорением градиентного спуска в нужном направлении, фактически гася колебания.

Примеры

opt = Momentum()

opt = Momentum(0.01, 0.99)

# Flux.Optimise.NesterovType

Nesterov(η = 0.001, ρ = 0.9)

Оптимизатор градиентного спуска со скоростью обучения η и импульсом Нестерова ρ.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Импульс Нестерова (ρ): управляет ускорением градиентного спуска в нужном направлении, фактически гася колебания.

Примеры

opt = Nesterov()

opt = Nesterov(0.003, 0.95)

# Flux.Optimise.RMSPropType

RMSProp(η = 0.001, ρ = 0.9, ϵ = 1.0e-8)

Оптимизатор, использующий алгоритм RMSProp . Часто является хорошим вариантом для рекуррентных сетей. Параметры, отличные от скорости обучения, обычно не требуется настраивать.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Импульс (ρ): управляет ускорением градиентного спуска в нужном направлении, фактически гася колебания.

Примеры

opt = RMSProp()

opt = RMSProp(0.002, 0.95)

# Flux.Optimise.AdamType

Adam(η = 0.001, β::Tuple = (0.9, 0.999), ϵ = 1.0e-8)

Оптимизатор Adam.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = Adam()

opt = Adam(0.001, (0.9, 0.8))

# Flux.Optimise.RAdamType

RAdam(η = 0.001, β::Tuple = (0.9, 0.999), ϵ = 1.0e-8)

Оптимизатор Rectified Adam.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = RAdam()

opt = RAdam(0.001, (0.9, 0.8))

# Flux.Optimise.AdaMaxType

AdaMax(η = 0.001, β::Tuple = (0.9, 0.999), ϵ = 1.0e-8)

AdaMax — это вариант Adam на основе ∞-нормы.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = AdaMax()

opt = AdaMax(0.001, (0.9, 0.995))

# Flux.Optimise.AdaGradType

AdaGrad(η = 0.1, ϵ = 1.0e-8)

Оптимизатор AdaGrad. Скорости обучения с учетом параметров зависят от частоты обновления оптимизатора. Параметры настраивать не требуется.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

Примеры

opt = AdaGrad()

opt = AdaGrad(0.001)

# Flux.Optimise.AdaDeltaType

AdaDelta(ρ = 0.9, ϵ = 1.0e-8)

AdaDelta — это версия AdaGrad, адаптирующая скорость обучения на основе периода прошлых обновлений градиента. Параметры настраивать не требуется.

Параметры

  • Rho (ρ): коэффициент спада градиента на каждом временном шаге.

Примеры

opt = AdaDelta()

opt = AdaDelta(0.89)

# Flux.Optimise.AMSGradType

AMSGrad(η = 0.001, β::Tuple = (0.9, 0.999), ϵ = 1.0e-8)

Версия AMSGrad оптимизатора Adam. Параметры настраивать не требуется.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = AMSGrad()

opt = AMSGrad(0.001, (0.89, 0.995))

# Flux.Optimise.NAdamType

NAdam(η = 0.001, β::Tuple = (0.9, 0.999), ϵ = 1.0e-8)

NAdam — это вариант Нестерова для оптимизатора Adam. Параметры настраивать не требуется.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = NAdam()

opt = NAdam(0.002, (0.89, 0.995))

# Flux.Optimise.AdamWFunction

AdamW(η = 0.001, β::Tuple = (0.9, 0.999), decay = 0)

AdamW — это вариант Adam, исправляющий (как бы восстанавливающий) регуляризацию снижения веса.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

  • decay: спад, применяемый к весам во время оптимизации.

Примеры

opt = AdamW()

opt = AdamW(0.001, (0.89, 0.995), 0.1)

# Flux.Optimise.OAdamType

OAdam(η = 0.0001, β::Tuple = (0.5, 0.9), ϵ = 1.0e-8)

OAdam (Optimistic Adam) — это вариант Adam, добавляющий «оптимистичный» элемент, подходящий для состязательного обучения.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = OAdam()

opt = OAdam(0.001, (0.9, 0.995))

# Flux.Optimise.AdaBeliefType

AdaBelief(η = 0.001, β::Tuple = (0.9, 0.999), ϵ = 1.0e-8)

Оптимизатор AdaBelief является вариантом хорошо известного оптимизатора Adam.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • Спад импульсов (β::Tuple): экспоненциальный спад для оценки первого (β1) и второго импульса (β2).

Примеры

opt = AdaBelief()

opt = AdaBelief(0.001, (0.9, 0.8))

Составные оптимизаторы

Flux определяет особый тип оптимизатора, называемый просто Optimiser, который принимает произвольные оптимизаторы в качестве входных данных. Его поведение аналогично действию обычных оптимизаторов, но отличается тем, что он работает, последовательно вызывая содержащиеся в нем оптимизаторы. Каждый оптимизатор выдает измененный градиент, который поступает в следующий, и результирующее обновление применяется к параметру обычным образом. Классическим вариантом использования является ситуация с добавлением спадов. Flux определяет некоторые основные спады, включая ExpDecay, InvDecay и т. д.

opt = Optimiser(ExpDecay(1, 0.1, 1000, 1e-4), Descent())

Здесь мы применим экспоненциальный спад к оптимизатору Descent. Значения по умолчанию для ExpDecay означают, что скорость обучения будет уменьшаться каждые 1000 шагов. Затем он применяется как любой другой оптимизатор.

w = randn(10, 10)
w1 = randn(10,10)
ps = Params([w, w1])

loss(x) = Flux.Losses.mse(w * x, w1 * x)

loss(rand(10)) # около 9

for t = 1:10^5
  θ = Params([w, w1])
  θ̄ = gradient(() -> loss(rand(10)), θ)
  Flux.Optimise.update!(opt, θ, θ̄)
end

loss(rand(10)) # около 0.9

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

# Flux.Optimise.OptimiserType

Optimiser(a, b, c...)

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

Будет заменен Optimisers.OptimiserChain во Flux 0.15.

Планирование для оптимизаторов

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

Сначала мы импортируем ParameterSchedulers.jl и инициализируем график косинусного отжига для изменения скорости обучения между 1e-4 и 1e-2 каждые 10 шагов. Мы также создаем новый оптимизатор Momentum.

using ParameterSchedulers

opt = Momentum()
schedule = Cos(λ0 = 1e-4, λ1 = 1e-2, period = 10)
for (eta, epoch) in zip(schedule, 1:100)
  opt.eta = eta
  # место для вашего обучающего кода
end

schedule также можно индексировать (например, schedule(100)) или итерировать, как любой итератор в Julia.

Расписания ParameterSchedulers.jl не отслеживают состояния (они не хранят состояние итераций). Если вам требуется расписание с отслеживанием состояния, можно воспользоваться ParameterSchedulers.Stateful:

using ParameterSchedulers: Stateful, next!

schedule = Stateful(Cos(λ0 = 1e-4, λ1 = 1e-2, period = 10))
for epoch in 1:100
  opt.eta = next!(schedule)
  # место для вашего обучающего кода
end

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

Спады

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

# Flux.Optimise.ExpDecayType

ExpDecay(η = 0.001, decay = 0.1, decay_step = 1000, clip = 1e-4, start = 1)

Уменьшайте скорость обучения η на коэффициент decay каждые decay_step шагов до достижения минимального значения clip.

Параметры

  • Скорость обучения (η): величина, на которую уменьшаются градиенты перед обновлением весов.

  • decay: коэффициент, на который уменьшается скорость обучения.

  • decay_step: используется для планирования операций спада путем задания количества шагов между двумя операциями спада.

  • clip: минимальное значение скорости обучения.

  • 'start': шаг, с которого начинается спад.

См. раздел Планирование для оптимизаторов документации с описанием общих методов планирования.

Примеры

ExpDecay обычно используется вместе с другими оптимизаторами в качестве последнего преобразования градиента:

opt = Optimiser(Adam(), ExpDecay(1.0))

Примечание. Возможно, вы захотите начать с η=1 в ExpDecay в сочетании с другими оптимизаторами (в данном случае Adam), имеющими собственную скорость обучения.

# Flux.Optimise.InvDecayType

InvDecay(γ = 0.001)

Применяет к оптимизатору обратный временной спад, чтобы эффективный размер шага при итерации n был равен eta / (1 + γ * n), где eta — начальный размер шага. Размер шага заключенного в оболочку оптимизатора не изменяется.

См. раздел Планирование для оптимизаторов документации с описанием общих методов планирования.

Примеры

InvDecay обычно используется вместе с другими оптимизаторами в качестве последнего преобразования градиента:

# Обратный спад скорости обучения
# с начальным значением 0,001 и коэффициентом спада 0,01.
opt = Optimiser(Adam(1f-3), InvDecay(1f-2))

# Flux.Optimise.WeightDecayType

WeightDecay(λ = 0)

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

Примеры

opt = Optimiser(WeightDecay(1f-4), Adam())

Отсечение градиентов

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

opt = Optimiser(ClipValue(1e-3), Adam(1e-3))

# Flux.Optimise.ClipValueType

ClipValue(thresh)

Отсекает градиенты, когда их абсолютное значение превышает пороговое значение (thresh).

Будет заменено Optimisers.ClipGrad во Flux 0.15.

# Flux.Optimise.ClipNormType

ClipNorm(thresh)

Отсекает градиенты, когда их L2-норма превышает пороговое значение (thresh).