o
    –hl  ã                   @   s–   d Z ddlZddlZddlZddlmZ ddlm  m	  m
Z e d¡Zdd„ Zddd„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
Different loss functions.
é    NÚstanzac                 C   s"   t  | ¡}d|tj< t |¡}|S ©Nr   )ÚtorchÚonesÚconstantÚPAD_IDÚnnÚNLLLoss)Ú
vocab_sizeÚweightÚcrit© r   úT/var/www/html/env_mimamsha/lib/python3.10/site-packages/stanza/models/common/loss.pyÚSequenceLoss   s   


r   Fc                 C   s„   t | tƒr
t | ¡}tj| dd\}}|tt |¡ƒ }t |¡| }|r,dt |¡ }t 	d 
|¡¡ tjt |¡ d¡d}|S )zË
    Either return a loss function which reweights all examples so the
    classes have the same effective weight, or dampened reweighting
    using log() so that the biggest class has some priority
    T)Úreturn_countsé   zReweighting cross entropy by {}ztorch.FloatTensor)r   )Ú
isinstanceÚlistÚnpÚarrayÚuniqueÚfloatÚsumÚlogÚloggerÚdebugÚformatr   ÚCrossEntropyLossr   Ú
from_numpyÚtype)ÚlabelsÚlog_dampenedÚ
all_labelsÚ_ÚweightsÚlossr   r   r   Úweighted_cross_entropy_loss   s   

ÿr&   c                       s*   e Zd ZdZd‡ fdd„	Zdd„ Z‡  ZS )	Ú	FocalLosszø
    Uses the model's assessment of how likely the correct answer is
    to weight the loss for a each error

    multi-category focal loss, in other words

    from "Focal Loss for Dense Object Detection"

    https://arxiv.org/abs/1708.02002
    Úmeanç       @c                    s<   t ƒ  ¡  |dvrtd| ƒ‚|| _tjdd| _|| _d S )N)r   Únoner(   zUnknown reduction: %sr*   )Ú	reduction)ÚsuperÚ__init__Ú
ValueErrorr+   r   r   Úce_lossÚgamma)Úselfr+   r0   ©Ú	__class__r   r   r-   2   s   

zFocalLoss.__init__c                 C   s*  t |jƒdkr#t |jƒdkr#|jd |jd kr"td |j|j¡ƒ‚nt |jƒdkr5t |jƒdkr5tdƒ‚td |j|j¡ƒ‚|  ||¡}t |jƒdkrV|jd |jd ksXJ ‚|dt | ¡ | j  }t |jƒdkrv|jd |jd ksxJ ‚| j	dkr| 
¡ S | j	dkrŠ| ¡ S | j	dkr‘|S td	ƒ‚)
z€
        Weight the loss using the models assessment of the correct answer

        inputs: [N, C]
        targets: [N]
        é   r   r   z4Expected inputs N,C and targets N, but got {} and {}zIThis would be a reasonable thing to implement, but we haven't done it yetr   r(   r*   z)unknown reduction!  how did this happen??)ÚlenÚshaper.   r   ÚNotImplementedErrorr/   r   Úexpr0   r+   r   r(   ÚAssertionError)r1   ÚinputsÚtargetsÚraw_lossÚ
final_lossr   r   r   Úforward;   s$   ÿ&&


zFocalLoss.forward)r(   r)   ©Ú__name__Ú
__module__Ú__qualname__Ú__doc__r-   r>   Ú__classcell__r   r   r2   r   r'   '   s    
	r'   c                       ó(   e Zd ZdZ‡ fdd„Zdd„ Z‡  ZS )ÚMixLosszb
    A mixture of SequenceLoss and CrossEntropyLoss.
    Loss = SequenceLoss + alpha * CELoss
    c                    s4   t ƒ  ¡  t|ƒ| _t ¡ | _|dksJ ‚|| _d S r   )r,   r-   r   Úseq_lossr   r   r/   Úalpha)r1   r
   rH   r2   r   r   r-   ]   ó
   



zMixLoss.__init__c                 C   s*   |   ||¡}|  ||¡}|| j|  }|S )N)rG   r/   rH   )r1   Ú
seq_inputsÚseq_targetsÚclass_inputsÚclass_targetsÚslÚcelr%   r   r   r   r>   d   s   zMixLoss.forwardr?   r   r   r2   r   rF   X   s    rF   c                       rE   )ÚMaxEntropySequenceLossz¡
    A max entropy loss that encourage the model to have large entropy,
    therefore giving more diverse outputs.

    Loss = NLLLoss + alpha * EntropyLoss
    c                    s4   t ƒ  ¡  t |¡}d|tj< t |¡| _|| _	d S r   )
r,   r-   r   r   r   r   r   r	   ÚnllrH   )r1   r
   rH   r   r2   r   r   r-   q   rI   zMaxEntropySequenceLoss.__init__c           	      C   s€   |  d¡|  d¡ksJ ‚|  ||¡}| tj¡ d¡ |¡}| ¡  |d¡}t	 
|¡}| |¡ ¡ |  d¡ }|| j|  }|S )z5
        inputs: [N, C]
        targets: [N]
        r   r   g        )ÚsizerQ   Úeqr   r   Ú	unsqueezeÚ	expand_asÚcloneÚmasked_fill_r   r8   Úmulr   rH   )	r1   r:   r;   Únll_lossÚmaskÚmasked_inputsÚpÚent_lossr%   r   r   r   r>   x   s   
zMaxEntropySequenceLoss.forwardr?   r   r   r2   r   rP   j   s    rP   )F)rC   ÚloggingÚnumpyr   r   Útorch.nnr   Ú%stanza.models.common.seq2seq_constantÚmodelsÚcommonÚseq2seq_constantr   Ú	getLoggerr   r   r&   ÚModuler'   rF   rP   r   r   r   r   Ú<module>   s    

1