a
    þdt  ã                   @   sL   d dl Z d dlmZ d dlmZ G dd„ deƒZdd„ ZG dd	„ d	eƒZdS )
é    N)ÚCounter)Ú_LRSchedulerc                       s*   e Zd ZdZd
‡ fdd„	Zdd	„ Z‡  ZS )ÚMultiStepRestartLRaÑ   MultiStep with restarts learning rate scheme.

    Args:
        optimizer (torch.nn.optimizer): Torch optimizer.
        milestones (list): Iterations that will decrease learning rate.
        gamma (float): Decrease ratio. Default: 0.1.
        restarts (list): Restart iterations. Default: [0].
        restart_weights (list): Restart weights at each restart iteration.
            Default: [1].
        last_epoch (int): Used in _LRScheduler. Default: -1.
    çš™™™™™¹?©r   ©é   éÿÿÿÿc                    sN   t |ƒ| _|| _|| _|| _t| jƒt| jƒks8J dƒ‚tt| ƒ ||¡ d S )Nz(restarts and their weights do not match.)	r   Ú
milestonesÚgammaÚrestartsÚrestart_weightsÚlenÚsuperr   Ú__init__)ÚselfÚ	optimizerr
   r   r   r   Ú
last_epoch©Ú	__class__© úd/var/www/html/stable-diffusion-webui/venv/lib/python3.9/site-packages/basicsr/models/lr_scheduler.pyr      s    
zMultiStepRestartLR.__init__c                    sj   ˆ j ˆ jv r6ˆ jˆ j ˆ j ¡ ‰‡fdd„ˆ jjD ƒS ˆ j ˆ jvrTdd„ ˆ jjD ƒS ‡ fdd„ˆ jjD ƒS )Nc                    s   g | ]}|d  ˆ  ‘qS )Z
initial_lrr   ©Ú.0Úgroup)Úweightr   r   Ú
<listcomp>   ó    z-MultiStepRestartLR.get_lr.<locals>.<listcomp>c                 S   s   g | ]}|d  ‘qS ©Úlrr   r   r   r   r   r       r   c                    s&   g | ]}|d  ˆ j ˆ jˆ j   ‘qS r   )r   r
   r   r   ©r   r   r   r   !   r   )r   r   r   Úindexr   Zparam_groupsr
   r    r   )r   r   r   Úget_lr   s    zMultiStepRestartLR.get_lr)r   r   r   r	   ©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r"   Ú__classcell__r   r   r   r   r      s   r   c                 C   s&   t |ƒD ]\}}| |kr|  S qdS )aì  Get the position from a period list.

    It will return the index of the right-closest number in the period list.
    For example, the cumulative_period = [100, 200, 300, 400],
    if iteration == 50, return 0;
    if iteration == 210, return 2;
    if iteration == 300, return 2.

    Args:
        iteration (int): Current iteration.
        cumulative_period (list[int]): Cumulative period list.

    Returns:
        int: The position of the right-closest number in the period list.
    N)Ú	enumerate)Ú	iterationÚcumulative_periodÚiZperiodr   r   r   Úget_position_from_periods$   s    r-   c                       s*   e Zd ZdZd	‡ fdd„	Zdd„ Z‡  ZS )
ÚCosineAnnealingRestartLRa’   Cosine annealing with restarts learning rate scheme.

    An example of config:
    periods = [10, 10, 10, 10]
    restart_weights = [1, 0.5, 0.5, 0.5]
    eta_min=1e-7

    It has four cycles, each has 10 iterations. At 10th, 20th, 30th, the
    scheduler will restart with the weights in restart_weights.

    Args:
        optimizer (torch.nn.optimizer): Torch optimizer.
        periods (list): Period for each cosine anneling cycle.
        restart_weights (list): Restart weights at each restart iteration.
            Default: [1].
        eta_min (float): The minimum lr. Default: 0.
        last_epoch (int): Used in _LRScheduler. Default: -1.
    r   r   r	   c                    sd   |ˆ _ |ˆ _|ˆ _tˆ j ƒtˆ jƒks.J dƒ‚‡ fdd„tdtˆ j ƒƒD ƒˆ _ttˆ ƒ ||¡ d S )Nz8periods and restart_weights should have the same length.c                    s"   g | ]}t ˆ jd |d … ƒ‘qS )r   r   )ÚsumÚperiods)r   r,   r    r   r   r   S   r   z5CosineAnnealingRestartLR.__init__.<locals>.<listcomp>r   )	r0   r   Úeta_minr   Úranger+   r   r.   r   )r   r   r0   r   r1   r   r   r    r   r   M   s    
ÿÿ z!CosineAnnealingRestartLR.__init__c                    sV   t ˆjˆjƒ}ˆj| ‰|dkr$dnˆj|d  ‰ˆj| ‰ ‡ ‡‡‡fdd„ˆjD ƒS )Nr   r   c              
      sB   g | ]:}ˆj ˆd  |ˆj   dt tjˆjˆ ˆ   ¡   ‘qS )g      à?r   )r1   ÚmathÚcosÚpir   )r   Zbase_lr©Zcurrent_periodZcurrent_weightZnearest_restartr   r   r   r   \   s   þÿz3CosineAnnealingRestartLR.get_lr.<locals>.<listcomp>)r-   r   r+   r   r0   Zbase_lrs)r   Úidxr   r6   r   r"   V   s    

ýzCosineAnnealingRestartLR.get_lr)r   r   r	   r#   r   r   r   r   r.   9   s   	r.   )r3   Úcollectionsr   Ztorch.optim.lr_schedulerr   r   r-   r.   r   r   r   r   Ú<module>   s
   