o
    i?                     @   s  d dl mZ d dlmZmZmZmZmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZmZ ddlmZmZ e
dZe
dZe
d	Ze
d
Zeeef Zeeeee ee f ZG dd deeeeef ZG dd deZedddddde deee  deeeef  defddZ!eddddddde deee  deeeef  dee def
ddZ"eddddddd de deee  deeeef  dee d!e#defd"d#Z$G d$d% d%eZ%ed&ddd'de deee  de%fd(d)Z&ed*dddd+de deee  dee de%fd,d-Z'ed.dddddd de deee  deeeef  dee d!e#de%fd/d0Z(G d1d2 d2eZ)ed3dd4de de)fd5d6Z*G d7d8 d8eZ+ed9dd:d;de d<e de+fd=d>Z,defd?d@Z-defdAdBZ.g dCZ/dS )D    )abstractmethod)
AnyDictGenericListOptionalSequenceTupleTypeVarUnioncast   )registry)Floats2dInts1d)get_array_moduleto_categoricalLossTGradTGuessTTruthTc                   @   st   e Zd ZdZdeddfddZdededee	e
f fd	d
Zededede	fddZededede
fddZdS )Lossa  Base class for classes computing the loss / gradient. The class can
    be initialized with settings if needed. It provides get_loss and
    get_grad as separate methods to allow calculating them separately. It
    also provides a __call__ method that returns a tuple of both.
    kwargsreturnNc                 K      d S N )selfr   r   r   >/home/ubuntu/.local/lib/python3.10/site-packages/thinc/loss.py__init__"   s   zLoss.__init__guessestruthsc                 C      |  ||| ||fS r   get_gradget_lossr   r    r!   r   r   r   __call__%      zLoss.__call__c                 C   r   r   r   r&   r   r   r   r$   (      zLoss.get_gradc                 C   r   r   r   r&   r   r   r   r%   ,   r)   zLoss.get_loss)__name__
__module____qualname____doc__r   r   r   r   r	   r   r   r'   r   r$   r%   r   r   r   r   r      s    r   c                   @   s   e Zd ZU eee  ed< eeeef  ed< e	eef ed< ddddddde
deee  deeeef  d	ee d
ef
ddZdedeeef fddZdededeeef fddZdededefddZdededefddZdedefddZdS )CategoricalCrossentropynamesmissing_value
_name_to_iTN        	normalizer/   r0   
neg_prefixlabel_smoothingr4   r5   r6   c                C   sH   || _ || _|| _|| _|| _|d urdd t|D | _d S i | _d S )Nc                 S   s   i | ]\}}||qS r   r   ).0inamer   r   r   
<dictcomp>E       z4CategoricalCrossentropy.__init__.<locals>.<dictcomp>)r4   r/   r0   r5   r6   	enumerater1   r   r4   r/   r0   r5   r6   r   r   r   r   6   s   	
z CategoricalCrossentropy.__init__r    r   c                    s  t |}g }d } jr|jt|t jfdd} j}t|trt|}t|rt|d trCt|D ]\}}||krA|	| q4nU jd u rNd}	t
|	t|D ]<\}}||krg jd ||< |	| qR|r jr| jr|t jd  ||<  j||  }
d||< d|| |
< qR fdd|D }|j|dd}t||}nt|||}|j|jkrttt||jd  jd	}n jrt
d
|d ur||9 }d||dk< d||dk< ||9 }||fS )Nfdtyper   zCannot calculate loss from list of strings without names. You can pass the names as a keyword argument when you create the loss object, e.g. CategoricalCrossentropy(names=['dog', 'cat'])c                    s   g | ]} j | qS r   )r1   )r7   r9   r   r   r   
<listcomp>n   r;   z:CategoricalCrossentropy.convert_truths.<locals>.<listcomp>r8   )	n_classesr6   zLabel smoothing is only applied, when truths have type List[str], List[int] or Ints1d, but it seems like Floats2d was provided.r   )r   r/   oneslenr0   
isinstancelistintr<   append
ValueErrorr5   
startswithr1   asarray
_make_mask_make_mask_by_valuendimr   r   r   shaper6   )r   r!   r    xpmissingnegatives_maskr0   r8   valuemsg	neg_indexmaskr   rB   r   convert_truthsI   sl   



z&CategoricalCrossentropy.convert_truthsr!   c                 C   s   |  ||}|| |fS r   r$   _get_loss_from_gradr   r    r!   d_truthr   r   r   r'      s   z CategoricalCrossentropy.__call__c                 C   s   |  ||\}}t|}|j|jkr!d|j d|j d}t|||dks/||dk r5d}t|||dksC||dk rId}t||| }||9 }| jr[||jd  }|S )NzBCannot calculate CategoricalCrossentropy loss: mismatched shapes:  vs .r   r   zVCannot calculate CategoricalCrossentropy loss with guesses outside the [0,1] interval.z[Cannot calculate CategoricalCrossentropy loss with truth values outside the [0,1] interval.)rY   r   rQ   rK   anyr4   )r   r    r!   targetrX   rR   err
differencer   r   r   r$      s    z CategoricalCrossentropy.get_gradc                 C   s   |  ||}| |S r   rZ   r\   r   r   r   r%      s   
z CategoricalCrossentropy.get_lossr]   c                 C   s   |d   S )N   )sum)r   r]   r   r   r   r[      s   z+CategoricalCrossentropy._get_loss_from_grad)r*   r+   r,   r   r   str__annotations__r   rI   r   boolfloatr   r   r	   rY   IntsOrFloatsOrStrsr'   r$   r%   r[   r   r   r   r   r.   1   s>   
 

A

r.   zCategoricalCrossentropy.v1TNr4   r/   r0   r4   r/   r0   r   c                 C      t | ||dS )Nrk   r.   rk   r   r   r   $configure_CategoricalCrossentropy_v1      rn   zCategoricalCrossentropy.v2r4   r/   r0   r5   r5   c                 C   s   t | |||dS )Nrp   rm   rp   r   r   r   $configure_CategoricalCrossentropy_v2   s   rq   zCategoricalCrossentropy.v3r2   r3   r6   c                 C      t | ||||dS Nr3   rm   r3   r   r   r   $configure_CategoricalCrossentropy_v3      	rt   c                   @   s   e Zd Zdddddddedeee  deeeef  dee d	e	f
d
dZ
dee dee deee e	f fddZdee dee dee fddZdee dee de	fddZdee de	fddZdS )SequenceCategoricalCrossentropyTNr2   r3   r4   r/   r0   r5   r6   c                C   s   t d||||d| _|| _d S )NFr3   )r.   ccr4   r=   r   r   r   r      s   	
z(SequenceCategoricalCrossentropy.__init__r    r!   r   c                 C   s   |  ||}| |}||fS r   rZ   )r   r    r!   gradslossr   r   r   r'      s   
z(SequenceCategoricalCrossentropy.__call__c           	      C   sf   d}t |t |krt|t |}g }t||D ]\}}| j||}| jr+|| }|| q|S )Nz]Cannot calculate SequenceCategoricalCrossentropy loss: guesses and truths must be same length)rF   rK   ziprw   r$   r4   rJ   )	r   r    r!   rb   nd_scoresyhyd_yhr   r   r   r$      s   z(SequenceCategoricalCrossentropy.get_gradc                 C   s   |  | ||S r   )r[   r$   r&   r   r   r   r%     s   z(SequenceCategoricalCrossentropy.get_lossrx   c                 C   s"   d}|D ]
}|| j |7 }q|S )Nr2   )rw   r[   )r   rx   ry   gradr   r   r   r[     s   z3SequenceCategoricalCrossentropy._get_loss_from_grad)r*   r+   r,   rh   r   r   rf   r   rI   ri   r   r   rj   r	   r   r'   r$   r%   r[   r   r   r   r   rv      sN    




rv   z"SequenceCategoricalCrossentropy.v1r4   r/   c                 C      t | |dS )Nr   rv   r   r   r   r   ,configure_SequenceCategoricalCrossentropy_v1     r   z"SequenceCategoricalCrossentropy.v2r4   r/   r5   c                 C   rl   )Nr   r   r   r   r   r   ,configure_SequenceCategoricalCrossentropy_v2  ro   r   z"SequenceCategoricalCrossentropy.v3c                 C   rr   rs   r   r3   r   r   r   ,configure_SequenceCategoricalCrossentropy_v3!  ru   r   c                   @   sj   e Zd ZdddefddZdededeeef fd	d
ZdededefddZ	dededefddZ
dS )
L2DistanceTr4   r4   c                C   s
   || _ d S r   r   )r   r4   r   r   r   r   4  s   
zL2Distance.__init__r    r!   r   c                 C   r"   r   r#   r&   r   r   r   r'   7  r(   zL2Distance.__call__c                 C   sJ   |j |j krd|j  d|j  d}t||| }| jr#||j d  }|S )N1Cannot calculate L2 distance: mismatched shapes: r^   r_   r   )rQ   rK   r4   )r   r    r!   rb   rc   r   r   r   r$   :  s   zL2Distance.get_gradc                 C   sB   |j |j krd|j  d|j  d}t|| ||}|d  S )Nr   r^   r_   rd   )rQ   rK   r$   re   )r   r    r!   rb   r]   r   r   r   r%   C  s
   zL2Distance.get_lossN)r*   r+   r,   rh   r   r   r	   ri   r'   r$   r%   r   r   r   r   r   3  s
    	r   zL2Distance.v1r   c                 C   s
   t | dS )Nr   )r   r   r   r   r   configure_L2DistanceL  s   
r   c                   @   s   e Zd ZddddedefddZded	ed
eeef fddZded	ed
efddZ	ded	ed
efddZ
ded	ed
efddZdS )CosineDistanceTFr4   ignore_zerosr4   r   c                C   s   || _ || _d S r   r   )r   r4   r   r   r   r   r   R  s   
zCosineDistance.__init__r    r!   r   c                 C   r"   r   r#   r&   r   r   r   r'   V  r(   zCosineDistance.__call__c                 C   s   |j |j krd|j  d|j  d}t|t|}|d }|d }|jj|ddd}|jj|ddd}|| }	|| jddd|	 }
|
S )N7Cannot calculate cosine similarity: mismatched shapes: r^   r_   :0yE>r   Taxiskeepdims)rQ   rK   r   linalgnormre   )r   r    r!   rb   rR   r}   r~   norm_yhnorm_y	mul_normscosiner   r   r   get_similarityY  s   zCosineDistance.get_similarityc                 C   s   |j |j krd|j  d|j  d}t|t|}| jr'||jdddk}|d }|d }|jj|ddd	}|jj|ddd	}	||	 }
|| jddd	|
 }||
 |||d
    }| jrcd||< | jrm||j d  }| S )Nr   r^   r_   r   r   r   r   Tr   rd   )	rQ   rK   r   r   absre   r   r   r4   )r   r    r!   rb   rR   zero_indicesr}   r~   r   r   r   r   r   r   r   r   r$   h  s$   zCosineDistance.get_gradc           	      C   s   |j |j krd|j  d|j  d}t|t|}| ||}||d }| jr8||jdddk}d||< | jrB||j d  }| }|S )Nr   r^   r_   r   r   r   )rQ   rK   r   r   r   r   re   r4   )	r   r    r!   rb   rR   r   lossesr   ry   r   r   r   r%     s   zCosineDistance.get_lossN)r*   r+   r,   rh   r   r   r	   ri   r'   r   r$   r%   r   r   r   r   r   Q  s    r   zCosineDistance.v1Fr   r   c                 C   r   )Nr   )r   r   r   r   r   configure_CosineDistance  r   r   c                 C   s$   t | }|j| jdd}d||< |S )Nr>   r?   r   )r   rE   rQ   )r    rS   rR   rX   r   r   r   rN     s   rN   c                 C   sX   t |}|j|jdd}|d ur*| jdkrd|| |k< |S |j| dd}d|||k< |S )Nr>   r?   r   r2   rA   r   )r   rE   rQ   rP   argmax)r!   r    r0   rR   rX   labelsr   r   r   rO     s   
rO   )rv   r.   r   r   )0abcr   typingr   r   r   r   r   r   r	   r
   r   r   configr   typesr   r   utilr   r   r   r   r   r   IntsOrFloatsrI   rf   rj   r   r.   r   rh   rn   rq   ri   rt   rv   r   r   r   r   r   r   r   rN   rO   __all__r   r   r   r   <module>   s    0z


5


C