generated from Axect/pytorch_template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hyperbolic_lr.py
126 lines (111 loc) · 3.62 KB
/
hyperbolic_lr.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import math
class HyperbolicLR:
"""
HyperbolicLR
Args:
optimizer: Optimizer
upper_bound: Upper bound on various max_iters
max_iter: Maximum number of iterations
init_lr: Initial learning rate
infimum_lr: The infimum of the hyperbolic learning rate
"""
def __init__(self, optimizer, upper_bound=1000, max_iter=100, infimum_lr=1e-6):
init_lr = optimizer.param_groups[0]['lr']
if upper_bound < max_iter:
raise ValueError("upper_bound must be greater than max_iter")
elif infimum_lr >= init_lr:
raise ValueError("infimum_lr must be less than init_lr")
self._optimizer = optimizer
self.upper_bound = upper_bound
self.max_iter = max_iter
self.init_lr = init_lr
self.delta_lr = init_lr - infimum_lr
self.iter = 0
def step(self):
"""
Update the learning rate
"""
self._update_learning_rate()
def zero_grad(self):
"""
Zero out the gradients with the inner optimizer
"""
self._optimizer.zero_grad()
def get_last_lr(self):
"""
Get the last learning rates from the inner optimizer
"""
return [param_group['lr'] for param_group in self._optimizer.param_groups]
def _get_lr(self):
"""
Get the learning rate
"""
x = self.iter
N = self.max_iter
U = self.upper_bound
return self.init_lr + self.delta_lr * (
math.sqrt((N - x) / U * (2 - (N + x) / U)) - math.sqrt(N / U * (2 - N / U))
)
def _update_learning_rate(self):
"""
Update the learning rate
"""
self.iter += 1
lr = self._get_lr()
for param_group in self._optimizer.param_groups:
param_group['lr'] = lr
class ExpHyperbolicLR:
"""
ExpHyperbolicLR
Args:
optimizer: Optimizer
upper_bound: Upper bound on various max_iters
max_iter: Maximum number of iterations
init_lr: Initial learning rate
infimum_lr: The infimum of the hyperbolic learning rate
"""
def __init__(self, optimizer, upper_bound=1000, max_iter=100, infimum_lr=1e-6):
init_lr = optimizer.param_groups[0]['lr']
if upper_bound < max_iter:
raise ValueError("upper_bound must be greater than max_iter")
elif infimum_lr >= init_lr:
raise ValueError("infimum_lr must be less than init_lr")
self._optimizer = optimizer
self.upper_bound = upper_bound
self.max_iter = max_iter
self.init_lr = init_lr
self.lr_ratio = init_lr / infimum_lr
self.iter = 0
def step(self):
"""
Update the learning rate
"""
self._update_learning_rate()
def zero_grad(self):
"""
Zero out the gradients with the inner optimizer
"""
self._optimizer.zero_grad()
def get_last_lr(self):
"""
Get the last learning rates from the inner optimizer
"""
return [param_group['lr'] for param_group in self._optimizer.param_groups]
def _get_lr(self):
"""
Get the learning rate
"""
x = self.iter
N = self.max_iter
U = self.upper_bound
return self.init_lr * self.lr_ratio ** (
math.sqrt((N - x) / U * (2 - (N + x) / U)) - math.sqrt(N / U * (2 - N / U))
)
def _update_learning_rate(self):
"""
Update the learning rate
"""
self.iter += 1
lr = self._get_lr()
for param_group in self._optimizer.param_groups:
param_group['lr'] = lr