Skip to content

Commit c660ee2

Browse files
authored
Merge pull request #491 from komaksym/add_new_problem_stepLR
Add new problem: stepLR learning rate scheduler
2 parents 3d1abd4 + 804b4dd commit c660ee2

File tree

7 files changed

+140
-0
lines changed

7 files changed

+140
-0
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Problem
2+
3+
Write a Python class StepLRScheduler to implement a learning rate scheduler based on the StepLR strategy. Your class should have an __init__ method implemented to initialize with an initial_lr (float), step_size (int), and gamma (float) parameter. It should also have a **get_lr(self, epoch)** method implemented that returns the current learning rate for a given epoch (int). The learning rate should be decreased by gamma every step_size epochs. The answer should be rounded to 4 decimal places. Only use standard Python.

questions/153_stepLR/example.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"input": "scheduler = StepLRScheduler(initial_lr=0.1, step_size=5, gamma=0.5)\nprint(scheduler.get_lr(epoch=0))\nprint(scheduler.get_lr(epoch=4))\nprint(scheduler.get_lr(epoch=5))\nprint(scheduler.get_lr(epoch=9))\nprint(scheduler.get_lr(epoch=10))",
3+
"output": "0.1\n0.1\n0.05\n0.05\n0.025",
4+
"reasoning": "The initial learning rate is 0.1. It stays 0.1 for epochs 0-4. At epoch 5, it decays by 0.5 to 0.05. It stays 0.05 for epochs 5-9. At epoch 10, it decays again to 0.025."
5+
}

questions/153_stepLR/learn.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# **Learning Rate Schedulers: StepLR**
2+
3+
## **1. Definition**
4+
A **learning rate scheduler** is a component used in machine learning, especially in neural network training, to adjust the learning rate during the training process. The **learning rate** is a hyperparameter that determines the step size at each iteration while moving towards a minimum of a loss function.
5+
6+
**StepLR (Step Learning Rate)** is a common type of learning rate scheduler that multiplicatively decays the learning rate by a fixed factor at predefined intervals (epochs). It is simple yet effective in stabilizing training and improving model performance.
7+
8+
## **2. Why Use Learning Rate Schedulers?**
9+
* **Faster Convergence:** A higher initial learning rate can help quickly move through the loss landscape.
10+
* **Improved Performance:** A smaller learning rate towards the end of training allows for finer adjustments and helps in converging to a better local minimum, avoiding oscillations around the minimum.
11+
* **Stability:** Reducing the learning rate prevents large updates that could lead to divergence or instability.
12+
13+
## **3. StepLR Mechanism**
14+
The learning rate is reduced by a factor γ (gamma) every step size epochs.
15+
16+
The formula for the learning rate at a given epoch is:
17+
18+
$$LR_e = LR_{\text{initial}} \times \gamma^{\lfloor e / \text{step size} \rfloor}$$
19+
20+
Where:
21+
* $LR_e$: The learning rate at epoch e.
22+
* $LR_{\text{initial}}$: The initial learning rate.
23+
* γ (gamma): The multiplicative factor by which the learning rate is reduced (usually between 0 and 1, e.g., 0.1, 0.5).
24+
* step size: The interval (in epochs) after which the learning rate is decayed.
25+
* ⌊ · ⌋: The floor function, which rounds down to the nearest integer. This determines how many times the learning rate has been decayed.
26+
27+
**Example:**
28+
If initial learning rate = 0.1, step size = 5, and γ = 0.5:
29+
* Epoch 0-4: $LR_e = 0.1 \times 0.5^{\lfloor 0/5 \rfloor} = 0.1 \times 0.5^0 = 0.1$
30+
* Epoch 5-9: $LR_e = 0.1 \times 0.5^{\lfloor 5/5 \rfloor} = 0.1 \times 0.5^1 = 0.05$
31+
* Epoch 10-14: $LR_e = 0.1 \times 0.5^{\lfloor 10/5 \rfloor} = 0.1 \times 0.5^2 = 0.025$
32+
33+
## **4. Applications of Learning Rate Schedulers**
34+
Learning rate schedulers, including StepLR, are widely used in training various machine learning models, especially deep neural networks, across diverse applications such as:
35+
* **Image Classification:** Training Convolutional Neural Networks (CNNs) for tasks like object recognition.
36+
* **Natural Language Processing (NLP):** Training Recurrent Neural Networks (RNNs) and Transformers for tasks like machine translation, text generation, and sentiment analysis.
37+
* **Speech Recognition:** Training models for converting spoken language to text.
38+
* **Reinforcement Learning:** Optimizing policies in reinforcement learning agents.
39+
* **Any optimization problem:** where gradient descent or its variants are used.

questions/153_stepLR/meta.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"id": "153",
3+
"title": "StepLR Learning Rate Scheduler",
4+
"difficulty": "easy",
5+
"category": "Machine Learning",
6+
"video": "",
7+
"likes": "0",
8+
"dislikes": "0",
9+
"contributor": [
10+
{
11+
"profile_link": "https://github.com/komaksym",
12+
"name": "komaksym"
13+
}
14+
]
15+
}

questions/153_stepLR/solution.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
class StepLRScheduler:
2+
def __init__(self, initial_lr, step_size, gamma):
3+
"""
4+
Initializes the StepLR scheduler.
5+
6+
Args:
7+
initial_lr (float): The initial learning rate.
8+
step_size (int): The period of learning rate decay.
9+
Learning rate is decayed every `step_size` epochs.
10+
gamma (float): The multiplicative factor of learning rate decay.
11+
(e.g., 0.1 for reducing LR by 10x).
12+
"""
13+
self.initial_lr = initial_lr
14+
self.step_size = step_size
15+
self.gamma = gamma
16+
17+
def get_lr(self, epoch):
18+
"""
19+
Calculates and returns the current learning rate for a given epoch.
20+
21+
Args:
22+
epoch (int): The current epoch number (0-indexed).
23+
24+
Returns:
25+
float: The calculated learning rate for the current epoch.
26+
"""
27+
# Calculate the number of decays that have occurred.
28+
# Integer division (//) in Python automatically performs the floor operation.
29+
num_decays = epoch // self.step_size
30+
31+
# Apply the decay factor 'gamma' raised to the power of 'num_decays'
32+
# to the initial learning rate.
33+
current_lr = self.initial_lr * (self.gamma ** num_decays)
34+
35+
return round(current_lr, 4)
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class StepLRScheduler:
2+
def __init__(self, initial_lr, step_size, gamma):
3+
# Initialize initial_lr, step_size, and gamma
4+
pass
5+
6+
def get_lr(self, epoch):
7+
# Calculate and return the learning rate for the given epoch
8+
pass
9+

questions/153_stepLR/tests.json

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[
2+
{
3+
"test": "scheduler = StepLRScheduler(initial_lr=0.1, step_size=5, gamma=0.5)\nprint(scheduler.get_lr(epoch=0))",
4+
"expected_output": "0.1"
5+
},
6+
{
7+
"test": "scheduler = StepLRScheduler(initial_lr=0.1, step_size=5, gamma=0.5)\nprint(scheduler.get_lr(epoch=4))",
8+
"expected_output": "0.1"
9+
},
10+
{
11+
"test": "scheduler = StepLRScheduler(initial_lr=0.1, step_size=5, gamma=0.5)\nprint(scheduler.get_lr(epoch=5))",
12+
"expected_output": "0.05"
13+
},
14+
{
15+
"test": "scheduler = StepLRScheduler(initial_lr=0.1, step_size=5, gamma=0.5)\nprint(scheduler.get_lr(epoch=9))",
16+
"expected_output": "0.05"
17+
},
18+
{
19+
"test": "scheduler = StepLRScheduler(initial_lr=0.1, step_size=5, gamma=0.5)\nprint(scheduler.get_lr(epoch=10))",
20+
"expected_output": "0.025"
21+
},
22+
{
23+
"test": "scheduler = StepLRScheduler(initial_lr=0.01, step_size=10, gamma=0.1)\nprint(scheduler.get_lr(epoch=0))\nprint(scheduler.get_lr(epoch=9))\nprint(scheduler.get_lr(epoch=10))\nprint(scheduler.get_lr(epoch=19))\nprint(scheduler.get_lr(epoch=20))",
24+
"expected_output": "0.01\n0.01\n0.001\n0.001\n0.0001"
25+
},
26+
{
27+
"test": "scheduler = StepLRScheduler(initial_lr=1.0, step_size=1, gamma=0.9)\nprint(round(scheduler.get_lr(epoch=0), 6))\nprint(round(scheduler.get_lr(epoch=1), 6))\nprint(round(scheduler.get_lr(epoch=2), 6))\nprint(round(scheduler.get_lr(epoch=3), 6))",
28+
"expected_output": "1.0\n0.9\n0.81\n0.729"
29+
},
30+
{
31+
"test": "scheduler = StepLRScheduler(initial_lr=0.001, step_size=50, gamma=0.5)\nprint(scheduler.get_lr(epoch=49))\nprint(scheduler.get_lr(epoch=50))\nprint(scheduler.get_lr(epoch=100))",
32+
"expected_output": "0.001\n0.0005\n0.0003"
33+
}
34+
]

0 commit comments

Comments
 (0)