|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| """PyTorch DataLoader for TFRecords"""
|
|
|
| import torch
|
|
|
| from torch.optim.lr_scheduler import _LRScheduler
|
| import math
|
|
|
| class AnnealingLR(_LRScheduler):
|
| """Anneals the learning rate from start to zero along a cosine curve."""
|
|
|
| DECAY_STYLES = ['linear', 'cosine', 'exponential', 'constant', 'None']
|
|
|
| def __init__(self, optimizer, start_lr, warmup_iter, num_iters, decay_style=None, last_iter=-1):
|
| self.optimizer = optimizer
|
| self.start_lr = start_lr
|
| self.warmup_iter = warmup_iter
|
| self.num_iters = last_iter + 1
|
| self.end_iter = num_iters
|
| self.decay_style = decay_style.lower() if isinstance(decay_style, str) else None
|
| self.step(self.num_iters)
|
| self.gamma = 0.995
|
| self.iters_to_steps = 80.0
|
|
|
|
|
| def get_lr(self):
|
|
|
| if self.warmup_iter > 0 and self.num_iters <= self.warmup_iter:
|
| return float(self.start_lr) * self.num_iters / self.warmup_iter
|
| else:
|
| if self.decay_style == self.DECAY_STYLES[0]:
|
| return self.start_lr*((self.end_iter-(self.num_iters-self.warmup_iter))/self.end_iter)
|
| elif self.decay_style == self.DECAY_STYLES[1]:
|
| return self.start_lr / 2.0 * (math.cos(math.pi * (self.num_iters - self.warmup_iter) / self.end_iter) + 1)
|
| elif self.decay_style == self.DECAY_STYLES[2]:
|
|
|
| return self.start_lr * pow(self.gamma, (self.num_iters - self.warmup_iter) / self.iters_to_steps)
|
| else:
|
| return self.start_lr
|
|
|
| def step(self, step_num=None):
|
| if step_num is None:
|
| step_num = self.num_iters + 1
|
| self.num_iters = step_num
|
| new_lr = self.get_lr()
|
| for group in self.optimizer.param_groups:
|
| group['lr'] = new_lr
|
|
|
| def state_dict(self):
|
| sd = {
|
| 'start_lr': self.start_lr,
|
| 'warmup_iter': self.warmup_iter,
|
| 'num_iters': self.num_iters,
|
| 'decay_style': self.decay_style,
|
| 'end_iter': self.end_iter
|
| }
|
| return sd
|
|
|
| def load_state_dict(self, sd):
|
| self.start_lr = sd['start_lr']
|
| self.warmup_iter = sd['warmup_iter']
|
| self.num_iters = sd['num_iters']
|
| self.end_iter = sd['end_iter']
|
| self.decay_style = sd['decay_style']
|
| self.step(self.num_iters)
|
|
|