o
    si                     @   s|   d dl Z d dlmZ d dlZddlmZ G dd deZG dd deZ	G d	d
 d
eZ
dd ZG dd dejjZeZdS )    N)	Optimizer   )SinkPITLossWrapperc                   @   s^   e Zd ZdZdd Zdd Zdd Zdd	 ZdddZdd Z	dd Z
dddZdddZd
S )BaseSchedulerzBase class for the step-wise scheduler logic.

    Args:
        optimizer (Optimize): Optimizer instance to apply lr schedule on.

    Subclass this and overwrite ``_get_lr`` to write your own step-wise scheduler.
    c                 C   s   || _ d| _d S Nr   )	optimizerstep_num)selfr    r
   N/home/ubuntu/.local/lib/python3.10/site-packages/asteroid/engine/schedulers.py__init__   s   
zBaseScheduler.__init__c                 C   s   | j   d S N)r   	zero_gradr	   r
   r
   r   r      s   zBaseScheduler.zero_gradc                 C   s   t r   )NotImplementedErrorr   r
   r
   r   _get_lr   s   zBaseScheduler._get_lrc                 C   s   | j jD ]}||d< qd S )Nlr)r   param_groups)r	   r   param_groupr
   r
   r   _set_lr   s   
zBaseScheduler._set_lrNc                 C   s$   |  j d7  _ |  }| | dS )z5Update step-wise learning rate before optimizer.step.   N)r   r   r   )r	   metricsepochr   r
   r
   r   step   s   zBaseScheduler.stepc                 C   s   | j | d S r   )__dict__update)r	   
state_dictr
   r
   r   load_state_dict%      zBaseScheduler.load_state_dictc                 C   s   dd | j  D S )Nc                 S   s   i | ]\}}|d kr||qS )r   r
   ).0keyvaluer
   r
   r   
<dictcomp>)   s    z,BaseScheduler.state_dict.<locals>.<dictcomp>)r   itemsr   r
   r
   r   r   (   s   zBaseScheduler.state_dictr   順 c                 C   s@   g }t ||D ]}|  jd7  _||   qd| _t|S )z0Returns the scheduler values from start to stop.r   r   )ranger   appendr   torchtensor)r	   startstoplr_list_r
   r
   r   	as_tensor+   s   
zBaseScheduler.as_tensorc                 C   s4   ddl m} | j||d}||  |  dS )z-Plot the scheduler values from start to stop.r   N)r)   r*   )matplotlib.pyplotpyplotr-   plotnumpyshow)r	   r)   r*   pltall_lrr
   r
   r   r0   4   s   zBaseScheduler.plot)NN)r   r$   )__name__
__module____qualname____doc__r   r   r   r   r   r   r   r-   r0   r
   r
   r
   r   r      s    

	r   c                       s*   e Zd ZdZd fdd	Zdd Z  ZS )NoamSchedulera  The Noam learning rate scheduler, originally used in conjunction with
    the Adam optimizer in [1].

    Args:
        optimizer (Optimizer): Optimizer instance to apply lr schedule on.
        d_model(int): The number of units in the layer output.
        warmup_steps (int): The number of steps in the warmup stage of training.
        scale (float): A fixed coefficient for rescaling the final learning rate.

    Schedule:
        The Noam scheduler increases the learning rate linearly for the first
        ``warmup_steps`` steps, and decreases it thereafter proportionally to the
        inverse square root of the step number:
            :math:`lr = scale\_factor * ( model\_dim^{-0.5} * adj\_step )`
            :math:`adj\_step = min(step\_num^{0.5}, step\_num * warmup\_steps^{-1.5})`

    References
        [1] Vaswani et al. (2017) "Attention is all you need". 31st
        Conference on Neural Information Processing Systems
          ?c                    s"   t  | || _|| _|| _d S r   )superr   d_modelscalewarmup_steps)r	   r   r<   r>   r=   	__class__r
   r   r   S   s   
zNoamScheduler.__init__c                 C   s0   | j | jd  t| jd | j| jd   }|S )N            )r=   r<   minr   r>   r	   r   r
   r
   r   r   Y   s   zNoamScheduler._get_lr)r:   r5   r6   r7   r8   r   r   __classcell__r
   r
   r?   r   r9   =   s    r9   c                       s2   e Zd ZdZ				d
 fdd	Zdd	 Z  ZS )DPTNetSchedulerah  Dual Path Transformer Scheduler used in [1]

    Args:
        optimizer (Optimizer): Optimizer instance to apply lr schedule on.
        steps_per_epoch (int): Number of steps per epoch.
        d_model(int): The number of units in the layer output.
        warmup_steps (int): The number of steps in the warmup stage of training.
        noam_scale (float): Linear increase rate in first phase.
        exp_max (float): Max learning rate in second phase.
        exp_base (float): Exp learning rate base in second phase.

    Schedule:
        This scheduler increases the learning rate linearly for the first
        ``warmup_steps``, and then decay it by 0.98 for every two epochs.

    References
        [1]: Jingjing Chen et al. "Dual-Path Transformer Network: Direct Context-
        Aware Modeling for End-to-End Monaural Speech Separation" Interspeech 2020.
      r:   -C6:?\(\?c                    s:   t  | || _|| _|| _|| _|| _|| _d| _d S r   )	r;   r   
noam_scaler<   r>   exp_maxexp_basesteps_per_epochr   )r	   r   rN   r<   r>   rK   rL   rM   r?   r
   r   r   w   s   

zDPTNetScheduler.__init__c                 C   sx   | j | j dkr|  jd7  _| j | jkr$| j| j| jd d   }|S | j| jd  t| j d | j | jd   }|S )Nr   r   r   rA   rB   )	r   rN   r   r>   rL   rM   rK   r<   rC   rD   r
   r
   r   r      s   zDPTNetScheduler._get_lr)rH   r:   rI   rJ   rE   r
   r
   r?   r   rG   b   s    rG   c                 C   s   t d|  dgS )NgRQ?
   )rC   )r   r
   r
   r   sinkpit_default_beta_schedule   r   rP   c                   @   s$   e Zd ZdZefddZdd ZdS )SinkPITBetaSchedulerad  Scheduler of the beta value of SinkPITLossWrapper
    This module is used as a Callback function of `pytorch_lightning.Trainer`.

    Args:
        cooling_schedule (callable) : A callable that takes a parameter `epoch` (int)
            and returns the value of `beta` (float).

    The default function is ``sinkpit_default_beta_schedule``: :math:`\beta = min(1.02^{epoch}, 10)`

    Example
        >>> from pytorch_lightning import Trainer
        >>> from asteroid.losses import SinkPITBetaScheduler
        >>> # Default scheduling function
        >>> sinkpit_beta_schedule = SinkPITBetaSchedule()
        >>> trainer = Trainer(callbacks=[sinkpit_beta_schedule])
        >>> # User-defined schedule
        >>> sinkpit_beta_schedule = SinkPITBetaScheduler(lambda ep: 1. if ep < 10 else 100.)
        >>> trainer = Trainer(callbacks=[sinkpit_beta_schedule])
    c                 C   s
   || _ d S r   )cooling_schedule)r	   rR   r
   r
   r   r      s   
zSinkPITBetaScheduler.__init__c                 C   s<   t |jtsJ |j|jksJ |j}| |}||j_d S r   )
isinstance	loss_funcr   current_epochrR   beta)r	   trainer	pl_moduler   rV   r
   r
   r   on_train_epoch_start   s
   
z)SinkPITBetaScheduler.on_train_epoch_startN)r5   r6   r7   r8   rP   r   rY   r
   r
   r
   r   rQ      s    rQ   )r'   torch.optim.optimizerr   pytorch_lightningpllossesr   objectr   r9   rG   rP   	callbacksCallbackrQ   _BaseSchedulerr
   r
   r
   r   <module>   s    5%9"