o
    ´©iþ  ã                   @   s^   d Z ddlZddlmZ ddlmZ G dd„ dejƒZG dd„ dejƒZG d	d
„ d
ejƒZdS )zLabel smoothing module.é    N)Únn)Úmake_pad_maskc                       ó6   e Zd ZdZdejddf‡ fdd„	Zdd„ Z‡  ZS )	ÚLabelSmoothingLossaK  Label-smoothing loss.

    :param int size: the number of class
    :param int padding_idx: ignored class id
    :param float smoothing: smoothing rate (0.0 means the conventional CE)
    :param bool normalize_length: normalize loss by sequence length if True
    :param torch.nn.Module criterion: loss function to be smoothed
    FÚnone©Ú	reductionc                    s@   t t| ƒ ¡  || _|| _d| | _|| _|| _d| _|| _	dS )z'Construct an LabelSmoothingLoss object.g      ð?N)
Úsuperr   Ú__init__Ú	criterionÚpadding_idxÚ
confidenceÚ	smoothingÚsizeÚ	true_distÚnormalize_length)Úselfr   r   r   r   r   ©Ú	__class__© úV/home/ubuntu/.local/lib/python3.10/site-packages/funasr/losses/label_smoothing_loss.pyr
      s   	

zLabelSmoothingLoss.__init__c           	      C   s  |  d¡| j ks
J ‚|  d¡}| ¡  d| j ¡}| ¡  d¡}t ¡ 7 | ¡ }| | j| j d  ¡ || jk}t	|ƒ| 
¡  ¡  }| |d¡}| d| d¡| j¡ W d  ƒ n1 s]w   Y  |  tj|dd|¡}| jrr|n|}| | d¡d¡ 
¡ | S )á  Compute loss between x and target.

        :param torch.Tensor x: prediction (batch, seqlen, class)
        :param torch.Tensor target:
            target signal masked with self.padding_id (batch, seqlen)
        :return: scalar float value
        :rtype torch.Tensor
        é   r   éÿÿÿÿé   N)Údim)r   Ú
contiguousÚviewÚtorchÚno_gradÚcloneÚfill_r   r   ÚlenÚsumÚitemÚmasked_fillÚscatter_Ú	unsqueezer   r   Úlog_softmaxr   )	r   ÚxÚtargetÚ
batch_sizer   ÚignoreÚtotalÚklÚdenomr   r   r   Úforward*   s   	


úzLabelSmoothingLoss.forward)	Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Ú	KLDivLossr
   r0   Ú__classcell__r   r   r   r   r      s    
úr   c                       s2   e Zd Zdejddf‡ fdd„	Zdd„ Z‡  ZS )ÚSequenceBinaryCrossEntropyFr   r   c                    s   t ƒ  ¡  || _|| _d S )N)r	   r
   r   r   )r   r   r   r   r   r   r
   D   s   

z#SequenceBinaryCrossEntropy.__init__c                 C   sZ   t ||jd d |j¡}|  ||¡}| jr|  ¡ n|jd }| | d¡d¡ ¡ | S )Nr   )Úmaxlenr   r   )	r   ÚshapeÚtoÚdevicer   r   r#   r%   r'   )r   ÚpredÚlabelÚlengthsÚpad_maskÚlossr/   r   r   r   r0   I   s   z"SequenceBinaryCrossEntropy.forward)r1   r2   r3   r   ÚBCEWithLogitsLossr
   r0   r6   r   r   r   r   r7   C   s    r7   c                       r   )	ÚNllLosszåNll loss.

    :param int size: the number of class
    :param int padding_idx: ignored class id
    :param bool normalize_length: normalize loss by sequence length if True
    :param torch.nn.Module criterion: loss function
    Fr   r   c                    s0   t t| ƒ ¡  || _|| _|| _d| _|| _dS )zConstruct an NllLoss object.N)r	   rB   r
   r   r   r   r   r   )r   r   r   r   r   r   r   r   r
   Y   s   
zNllLoss.__init__c                 C   s¶   |  d¡| j ks
J ‚|  d¡}| d| j ¡}| d¡}t ¡  || jk}t|ƒ| ¡  ¡  }| |d¡}W d  ƒ n1 s?w   Y  |  	||¡}| j
rO|n|}| |d¡ ¡ | S )r   r   r   r   N)r   r   r   r   r   r"   r#   r$   r%   r   r   )r   r)   r*   r+   r,   r-   r.   r/   r   r   r   r0   h   s   	



ýzNllLoss.forward)	r1   r2   r3   r4   r   ÚNLLLossr
   r0   r6   r   r   r   r   rB   P   s    
ûrB   )	r4   r   r   Ú*funasr.models.transformer.utils.nets_utilsr   ÚModuler   r7   rB   r   r   r   r   Ú<module>   s   5