Вспомогательные функции обратных вызовов
#
Flux.throttle
— Function
throttle(f, timeout; leading=true, trailing=false)
Возвращает функцию, которая при вызове будет срабатывать не более одного раза в течение секунд времени ожидания (timeout
).
Обычно регулируемая функция будет выполняться столько, сколько сможет, не более одного раза за время ожидания (wait
). Но если вы хотите отключить выполнение на переднем фронте, передайте leading=false
. Чтобы включить выполнение на заднем фронте, передайте trailing=true
.
Примеры
julia> a = Flux.throttle(() -> println("Flux"), 2);
julia> for i = 1:4 # a, вызываемое в альтернативных итерациях
a()
sleep(1)
end
Flux
Flux
Вспомогательные функции, используемые для определенного числа эпох без улучшений, после которого обучение останавливается (patience)
Flux предоставляет функции для управления процедурой обучения в соответствии с некоторым отслеживаемым условием и максимальным patience
. Например, можно использовать early_stopping
, чтобы остановить обучение, когда модель сходится или ухудшается ее работа, или использовать plateau
, чтобы проверить, не находится ли модель в заторможенном состоянии.
Например, ниже мы создадим функцию псевдопотерь, которая уменьшается, достигает минимума, а затем увеличивается. Триггер ранней остановки прервет цикл до того, как потери вырастут слишком сильно.
# создадим псевдопотерю, которая уменьшается в течение 4 вызовов, а затем начинает увеличиваться
# назовем это loss()
loss = let t = 0
() -> begin
t += 1
(t - 4) ^ 2
end
end
# создадим триггер ранней остановки
# возвращает true, если потери увеличиваются в течение двух последовательных шагов
es = early_stopping(loss, 2; init_score = 9)
# остановится на 6-й (4 уменьшающихся + 2 увеличивающихся вызова) эпохе
for epoch in 1:10
es() && break
end
Именованный аргумент distance
функции early_stopping
является функцией вида distance(best_score, score)
. По умолчанию distance
имеет значение -
, что означает, что отслеживаемая метрика f
должна быть уменьшающейся и минимизированной. Если вы используете какую-то увеличивающуюся метрику (например, точность), можно настроить функцию distance
: (best_score, score) -> score - best_score
.
# создадим псевдоточность, которая увеличивается на 0,01 каждый раз от 0 до 1
# назовем это acc()
acc = let v = 0
() -> v = max(1, v + 0.01)
end
# создадим триггер досрочной остановки для точности
es = early_stopping(acc, 3; delta = (best_score, score) -> score - best_score)
# итерация будет выполняться до 10-й эпохи
for epoch in 1:10
es() && break
end
early_stopping
и plateau
созданы на основе patience
. Вы можете использовать patience
для создания собственных триггеров, использующих счетчик эпох без улучшения результата. Например, если вы хотите запускать триггер, когда потеря опускается ниже порогового значения в течение нескольких последовательных итераций:
threshold(f, thresh, delay) = patience(delay) do
f() < thresh
end
predicate
в patience
и f
в early_stopping
/plateau
могут принимать дополнительные аргументы. Такие дополнительные аргументы можно передать в predicate
или f
через возвращаемую функцию:
trigger = patience((a; b) -> a > b, 3)
# итерация будет выполняться до 10-й эпохи
for epoch in 1:10
trigger(1; b = 2) && break
end
# остановится на 3-й эпохе
for epoch in 1:10
trigger(3; b = 2) && break
end
#
Flux.patience
— Function
patience(predicate, wait)
Возвращает функцию, которая ведет внутренний счет по одному, если predicate(...) == true
, в противном случае подсчет обнуляется. Если подсчет больше или равен wait
, функция возвращает true
, в противном случае возвращает false
.
Примеры
julia> loss() = rand();
julia> trigger = Flux.patience(() -> loss() < 1, 3);
julia> for i in 1:10
@info "Epoch $i"
trigger() && break
end
[ Info: Epoch 1
[ Info: Epoch 2
[ Info: Epoch 3
#
Flux.early_stopping
— Function
early_stopping(f, delay; distance = -, init_score = 0, min_dist = 0)
Возвращает функцию, которая ведет внутренний счет по одному, если distance(best_score, f(...)) <= min_dist
, где best_score
— последнее наилучшее значение f(...)
. Если подсчет больше или равен delay
, функция возвращает true
, в противном случае возвращает false
. Подсчет сбрасывается, когда distance(best_score, f(...)) > min_dist
.
Примеры
julia> loss = let l = 0
() -> l += 1
end; # функция псевдопотерь, возвращающая возрастающие значения
julia> es = Flux.early_stopping(loss, 3);
julia> for i in 1:10
@info "Epoch $i"
es() && break
end
[ Info: Epoch 1
[ Info: Epoch 2
[ Info: Epoch 3
#
Flux.plateau
— Function
plateau(f, width; distance = -, init_score = 0, min_dist = 1f-6)
Возвращает функцию, которая ведет внутренний счет по одному, если abs(distance(last_score, f(...))) <= min_dist
, где last_score
содержит последнее значение f(...)
. Если подсчет больше или равен width
, функция возвращает true
, в противном случае возвращает false
. Подсчет сбрасывается, когда abs(distance(last_score, f(...))) > min_dist
.
Примеры
julia> f = let v = 10
() -> v = v / abs(v) - v
end; # -9, 8, -7, 6, ...
julia> trigger = Flux.plateau(f, 3; init_score=10, min_dist=18);
julia> for i in 1:10
@info "Epoch $i"
trigger() && break
end
[ Info: Epoch 1
[ Info: Epoch 2
[ Info: Epoch 3
[ Info: Epoch 4