Правила оптимизации
Flux содержит множество правил оптимизации для использования с функцией train!
и другими обучающими функциями.
Механизм, с помощью которого они работают, постепенно заменяется в рамках перехода от «неявных» структур, основанных на словарях, к «явным» древовидным структурам. В настоящее время одна и та же структура (например, Adam
) может использоваться в любой форме и будет переведена на новый вариант автоматически.
Подробную информацию о работе нового интерфейса можно найти в документации по Optimisers.jl.
Подробную информацию о том, как работал старый «неявный» интерфейс, можно найти в руководстве по Flux 0.13.6.
Справка по оптимизатору
Все оптимизаторы возвращают объект, который, будучи переданным функции train!
, обновляет переданные ей параметры.
#
Flux.Optimise.Descent
— Type
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.Momentum
— Type
Momentum(η = 0.01, ρ = 0.9)
Оптимизатор градиентного спуска со скоростью обучения η
и импульсом ρ
.
Параметры
-
Скорость обучения (
η
): величина, на которую уменьшаются градиенты перед обновлением весов. -
Импульс (
ρ
): управляет ускорением градиентного спуска в нужном направлении, фактически гася колебания.
Примеры
opt = Momentum()
opt = Momentum(0.01, 0.99)
#
Flux.Optimise.Nesterov
— Type
Nesterov(η = 0.001, ρ = 0.9)
Оптимизатор градиентного спуска со скоростью обучения η
и импульсом Нестерова ρ
.
Параметры
-
Скорость обучения (
η
): величина, на которую уменьшаются градиенты перед обновлением весов. -
Импульс Нестерова (
ρ
): управляет ускорением градиентного спуска в нужном направлении, фактически гася колебания.
Примеры
opt = Nesterov()
opt = Nesterov(0.003, 0.95)
#
Flux.Optimise.RMSProp
— Type
RMSProp(η = 0.001, ρ = 0.9, ϵ = 1.0e-8)
Оптимизатор, использующий алгоритм RMSProp . Часто является хорошим вариантом для рекуррентных сетей. Параметры, отличные от скорости обучения, обычно не требуется настраивать.
Параметры
-
Скорость обучения (
η
): величина, на которую уменьшаются градиенты перед обновлением весов. -
Импульс (
ρ
): управляет ускорением градиентного спуска в нужном направлении, фактически гася колебания.
Примеры
opt = RMSProp()
opt = RMSProp(0.002, 0.95)
#
Flux.Optimise.Adam
— Type
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.RAdam
— Type
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.AdaMax
— Type
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.AdaGrad
— Type
AdaGrad(η = 0.1, ϵ = 1.0e-8)
Оптимизатор AdaGrad. Скорости обучения с учетом параметров зависят от частоты обновления оптимизатора. Параметры настраивать не требуется.
Параметры
-
Скорость обучения (
η
): величина, на которую уменьшаются градиенты перед обновлением весов.
Примеры
opt = AdaGrad()
opt = AdaGrad(0.001)
#
Flux.Optimise.AdaDelta
— Type
AdaDelta(ρ = 0.9, ϵ = 1.0e-8)
AdaDelta — это версия AdaGrad, адаптирующая скорость обучения на основе периода прошлых обновлений градиента. Параметры настраивать не требуется.
Параметры
-
Rho (
ρ
): коэффициент спада градиента на каждом временном шаге.
Примеры
opt = AdaDelta()
opt = AdaDelta(0.89)
#
Flux.Optimise.AMSGrad
— Type
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.NAdam
— Type
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.AdamW
— Function
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.OAdam
— Type
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.AdaBelief
— Type
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.Optimiser
— Type
Optimiser(a, b, c...)
Объединяет несколько оптимизаторов в один. Каждый оптимизатор выдает измененный градиент, который поступает в следующий, а тот, в свою очередь, применяется к параметру обычным образом.
Будет заменен |
Планирование для оптимизаторов
На практике довольно часто приходится планировать скорость обучения оптимизатора, чтобы добиться более быстрой сходимости. Существует множество популярных политик планирования. Их реализации можно найти в документации по 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.ExpDecay
— Type
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.InvDecay
— Type
InvDecay(γ = 0.001)
Применяет к оптимизатору обратный временной спад, чтобы эффективный размер шага при итерации n
был равен eta / (1 + γ * n)
, где eta
— начальный размер шага. Размер шага заключенного в оболочку оптимизатора не изменяется.
См. раздел Планирование для оптимизаторов документации с описанием общих методов планирования.
Примеры
InvDecay
обычно используется вместе с другими оптимизаторами в качестве последнего преобразования градиента:
# Обратный спад скорости обучения
# с начальным значением 0,001 и коэффициентом спада 0,01.
opt = Optimiser(Adam(1f-3), InvDecay(1f-2))
#
Flux.Optimise.WeightDecay
— Type
WeightDecay(λ = 0)
Спад весов по . Обычно используется вместе с другими оптимизаторами в качестве первого преобразования градиента, что эквивалентно добавлению регуляризации с коэффициентом к потерям.
Примеры
opt = Optimiser(WeightDecay(1f-4), Adam())
Отсечение градиентов
Отсечение градиентов полезно для обучения рекуррентных нейронных сетей, которые, как правило, страдают от проблем взрывающегося градиента. Вот пример использования.
opt = Optimiser(ClipValue(1e-3), Adam(1e-3))
#
Flux.Optimise.ClipValue
— Type
ClipValue(thresh)
Отсекает градиенты, когда их абсолютное значение превышает пороговое значение (thresh
).
Будет заменено |
#
Flux.Optimise.ClipNorm
— Type
ClipNorm(thresh)
Отсекает градиенты, когда их L2-норма превышает пороговое значение (thresh
).