o
    i                     @  s   d dl mZ d dlZd dlmZ d dlmZmZmZ d dl	Z
d dlZd dlmZ d dlmZ ddlmZmZmZmZ dddZ	d d!ddZd"ddZG dd dejZdS )#    )annotationsN)Path)DictOptionalTuple)nn)
functional   )ANCHORS_PATHEMOTION_LABELSEMOTION_TO_IDMicroAlbertConfiglevelintreturntorch.Tensorc                   s   t tjddd }g }tD ](}|| } fdd|D }t|dks.J d  d| ||d	 d
  qtj|tj	dS )Nutf-8encodinganchorsc                   s   g | ]
}|d   kr|qS r    ).0er   r   Q/dataset/kemix-engine/package/face/animasync-face-v3/models/microalbert/losses.py
<listcomp>   s    z&build_anchor_table.<locals>.<listcomp>r	   zexpected exactly one level-z entry for r   vaddtype)
jsonloadsr
   	read_textr   lenappendtorchtensorfloat32)r   datarowsnameentriesmatchr   r   r   build_anchor_table   s    r,      train_jsonlr   num_emotionsfallback_levelc                 C  s.  t j|dft jd}t j|t jd}t| jdd@}|D ]5}t|}|d D ])}t	|d }	|	du r6q(|d }
t
|
dkrAq(||	  |
7  < ||	  d	7  < q(qW d   n1 s]w   Y  ||dddf jd	d
 }|dk rt| }t|D ]}|| dkr|| ||< qtj|tjdS )uH  Compute per-emotion VAD centroids from training data.

    Replaces hand-curated anchors (which were 0.25-0.40 from data means)
    with empirical class centroids — snap loss now pulls toward what the
    data actually shows for each class. Falls back to JSON level-3 anchors
    for any class with zero training samples.
    r-   r   r   r   turnsemotionNr   r	   minr   )npzerosfloat64int64r   openr   r    r   getr"   clipanyr,   numpyranger$   r%   r&   )r.   r/   r0   sumscountsflinerowtemo_idr   	centroidsjson_anchorsir   r   r   build_data_centroid_anchors   s2   

rI   emotion_ids
np.ndarraynum_classes
clip_rangeTuple[float, float]c                 C  sR   ddl m} |dt|| d}t||d |d }||  }tj|tjdS )Nr   )compute_class_weightbalanced)class_weightclassesyr	   r   )	sklearn.utils.class_weightrO   r5   aranger;   meanr$   r%   r&   )rJ   rL   rM   rO   wr   r   r   compute_class_weights<   s   rX   c                      s6   e Zd Z	dd fdd	ZdddZdddZ  ZS )MultitaskLossNcfgr   class_weightsr   r   Optional[torch.Tensor]c                   sl   t    || _| d|  |d u rt|j}| d| | dtj|j	tj
d tt|j	| _d S )Nr[   r   vad_dim_weightsr   )super__init__rZ   register_bufferfloatr,   
snap_levelr$   r%   r]   r&   sum
_dim_w_sum)selfrZ   r[   r   	__class__r   r   r_   N   s   

zMultitaskLoss.__init__epochr   r   rN   c                 C  sF   | j }td|d td|j }|j| }||jkr|jnd}||fS )N      ?r	   g        )rZ   r4   maxvad_warmup_epochsvad_loss_weight_maxsnap_start_epochsnap_loss_weight)re   rh   rZ   rampw_vadw_snapr   r   r   current_weights`   s
   
zMultitaskLoss.current_weightsemotion_logitsvad_predemotion_target
vad_target7Tuple[torch.Tensor, Dict[str, float], Dict[str, float]]c                 C  s  | j }tj||| j|jd}tj||d|jd}|| j jdd	 | j
 }	tj| |j dd}
|
jdd\}}||jk }| j| }tj||d|jdj	dd}||  | jdd }t|	  }|dd	kr|jdd}t|j| d		 }n|d
}| |\}}|||	  ||  |j|  }t|  t|	  t|  t|  d}t|t||d}|||fS )N)weightlabel_smoothingnone)	reductionbeta)dimri   r3   r      r   )cer   snapr>   )rp   rq   	gate_rate)rZ   Fcross_entropyr[   ry   smooth_l1_losssmooth_l1_betar]   rc   rV   rd   softmaxdetachsnap_softmax_temprj   snap_conf_thresholdra   r   clampitemsizestdrelurange_target_stdpow	new_zerosrr   range_loss_weight)re   rs   rt   ru   rv   rh   rZ   l_cediffl_vad
soft_probstop_probtop_idxgateanchor_targetsnap_perl_snapr   	batch_stdl_rangerp   rq   total
componentsauxr   r   r   forwardg   sT   




zMultitaskLoss.forward)N)rZ   r   r[   r   r   r\   )rh   r   r   rN   )rs   r   rt   r   ru   r   rv   r   rh   r   r   rw   )__name__
__module____qualname__r_   rr   r   __classcell__r   r   rf   r   rY   M   s
    
rY   )r   r   r   r   )r-   )r.   r   r/   r   r0   r   r   r   )rJ   rK   rL   r   rM   rN   r   r   )
__future__r   r   pathlibr   typingr   r   r   r=   r5   r$   r   torch.nnr   r   configr
   r   r   r   r,   rI   rX   ModulerY   r   r   r   r   <module>   s    

"