Skip to main content

entrenar/optim/scheduler/
linear_warmup.rs

1//! Linear warmup learning rate scheduler
2
3use super::LRScheduler;
4use crate::optim::Optimizer;
5
6/// Linear Warmup Learning Rate Scheduler
7///
8/// Linearly increases learning rate from 0 to target over warmup_steps.
9/// After warmup, maintains target learning rate.
10///
11/// Formula: lr_t = lr_target * min(1, t / warmup_steps)
12pub struct LinearWarmupLR {
13    lr_target: f32,
14    warmup_steps: usize,
15    current_step: usize,
16}
17
18impl LinearWarmupLR {
19    /// Create a new linear warmup scheduler
20    ///
21    /// # Arguments
22    /// * `lr_target` - Target learning rate after warmup
23    /// * `warmup_steps` - Number of steps for warmup
24    pub fn new(lr_target: f32, warmup_steps: usize) -> Self {
25        Self { lr_target, warmup_steps, current_step: 0 }
26    }
27
28    /// Apply the current learning rate to an optimizer
29    pub fn apply<O: Optimizer>(&self, optimizer: &mut O) {
30        optimizer.set_lr(self.get_lr());
31    }
32}
33
34impl LRScheduler for LinearWarmupLR {
35    fn get_lr(&self) -> f32 {
36        if self.warmup_steps == 0 {
37            return self.lr_target;
38        }
39
40        let progress = (self.current_step as f32 / self.warmup_steps as f32).min(1.0);
41        self.lr_target * progress
42    }
43
44    fn step(&mut self) {
45        self.current_step += 1;
46    }
47}