o
    i|!                     @   s~   d Z ddlZddlZddlZddlmZ ddlZddlZde	de
d fddZdd	d
ZdddZG dd deZdS )zCommon functions for ASR.    N)groupby      ic           	         s   t | dkrdS d}t| dd ddd }tj|D ].}||   fdd| D }t |dkrIt|d	d ddd }|d
 |d
  |k rI|d7 }q||krPdS dS )zEnd detection.

    described in Eq. (50) of S. Watanabe et al
    "Hybrid CTC/Attention Architecture for End-to-End Speech Recognition"

    :param ended_hyps:
    :param i:
    :param M:
    :param D_end:
    :return:
    r   Fc                 S      | d S Nscore xr   r   N/home/ubuntu/.local/lib/python3.10/site-packages/espnet/nets/e2e_asr_common.py<lambda>!       zend_detect.<locals>.<lambda>T)keyreversec                    s    g | ]}t |d   kr|qS )yseq)len.0r
   
hyp_lengthr   r   
<listcomp>%   s     zend_detect.<locals>.<listcomp>c                 S   r   r   r   r	   r   r   r   r   (   r   r   r   )r   sortedsixmovesrange)	
ended_hypsiMD_endcountbest_hypmhyps_same_lengthbest_hyp_same_lengthr   r   r   
end_detect   s&   
r$   c                 C   s  |dur t |d}t|d }W d   n1 sw   Y  |dkr{|dus.J d| t| }| D ]$\}}tdd |d d	 d
  D }	t|	d	kr[||	  d7  < q7t||| d < d||d	k< d	||< |	tj
t| }
|
S td|  t  |
S )zObtain label distribution for loss smoothing.

    :param odim:
    :param lsm_type:
    :param blank:
    :param transcript:
    :return:
    Nrbuttsunigramz-transcript is required for %s label smoothingc                 S   s   g | ]}t |qS r   )int)r   nr   r   r   r   G       z(label_smoothing_dist.<locals>.<listcomp>outputr   tokenidr   z*Error: unexpected label smoothing type: %s)openjsonloadnpzerositemsarraysplitr   astypefloat32sumloggingerrorsysexit)odimlsm_type
transcriptblankf
trans_json
labelcountkvids	labeldistr   r   r   label_smoothing_dist4   s,   	

$rG      c                 C   sH   | | } t t j| t jdd } t t j| t jdd } t| | S )zReturn the output size of the VGG frontend.

    :param in_channel: input channel size
    :param out_channel: output channel size
    :return: output size
    :rtype int
    )dtype   )r0   ceilr3   r6   r(   )idim
in_channelout_channelr   r   r   get_vgg2l_odimV   s   rO   c                       sN   e Zd ZdZ	d fdd	ZdddZdd Zd	d
 Zdd Zdd Z	  Z
S )ErrorCalculatora   Calculate CER and WER for E2E_ASR and CTC models during training.

    :param y_hats: numpy array with predicted text
    :param y_pads: numpy array with true (target) text
    :param char_list:
    :param sym_space:
    :param sym_blank:
    :return:
    Fc                    sf   t t|   || _|| _|| _|| _|| _| j| j| _	| j| jv r.| j| j| _
dS d| _
dS )z$Construct an ErrorCalculator object.N)superrP   __init__
report_cer
report_wer	char_listspacer?   index	idx_blank	idx_space)selfrU   	sym_space	sym_blankrS   rT   	__class__r   r   rR   o   s   
zErrorCalculator.__init__c                 C   sh   d\}}|r|  ||S | js| js||fS | ||\}}| jr'| ||}| jr0| ||}||fS )ad  Calculate sentence-level WER/CER score.

        :param torch.Tensor ys_hat: prediction (batch, seqlen)
        :param torch.Tensor ys_pad: reference (batch, seqlen)
        :param bool is_ctc: calculate CER score for CTC
        :return: sentence-level WER score
        :rtype float
        :return: sentence-level CER score
        :rtype float
        )NN)calculate_cer_ctcrS   rT   convert_to_charcalculate_cercalculate_wer)rZ   ys_hatys_padis_ctccerwerseqs_hat	seqs_truer   r   r   __call__   s   zErrorCalculator.__call__c                 C   s0  ddl }g g }}t|D ]x\}}dd t|D }|| }	g g }
}|D ]}t|}|dkrC|| jkrC|| jkrC|
| jt|  q%|	D ]}t|}|dkrd|| jkrd|| jkrd|| jt|  qFd|
}d|}t	|dkr||
|| |t	| q|rtt|t| }|S d}|S )zCalculate sentence-level CER score for CTC.

        :param torch.Tensor ys_hat: prediction (batch, seqlen)
        :param torch.Tensor ys_pad: reference (batch, seqlen)
        :return: average sentence-level CER score
        :rtype float
        r   Nc                 S   s   g | ]}|d  qS )r   r   r   r   r   r   r      r*   z5ErrorCalculator.calculate_cer_ctc.<locals>.<listcomp> )editdistance	enumerater   r(   rX   rY   appendrU   joinr   evalfloatr7   )rZ   rc   rd   rm   cerschar_ref_lensr   yy_haty_trueseq_hatseq_trueidx	hyp_chars	ref_charscer_ctcr   r   r   r_      s4   



z!ErrorCalculator.calculate_cer_ctcc                    s   g g }}t |D ]Z\}}|| }t|dkd }t|dkr$|d nt|}	 fdd|d|	 D }
 fdd|D }d|
 jd}| jd}d| jd}|| || q	||fS )	a"  Convert index to character.

        :param torch.Tensor seqs_hat: prediction (batch, seqlen)
        :param torch.Tensor seqs_true: reference (batch, seqlen)
        :return: token list of prediction
        :rtype list
        :return: token list of reference
        :rtype list
        rk   r   c                    s   g | ]	} j t| qS r   )rU   r(   r   rz   rZ   r   r   r      s    z3ErrorCalculator.convert_to_char.<locals>.<listcomp>Nc                    s&   g | ]}t |d kr jt | qS )rk   )r(   rU   r~   r   r   r   r      s   & rl    )	rn   r0   wherer   rp   replacerV   r?   ro   )rZ   rc   rd   rh   ri   r   rv   rw   eos_trueymaxrx   ry   seq_hat_textseq_true_textr   r   r   r`      s   


zErrorCalculator.convert_to_charc                 C   sx   ddl }g g }}t|D ]$\}}|| }|dd}	|dd}
|||	|
 |t|
 qtt|t| S )zCalculate sentence-level CER score.

        :param list seqs_hat: prediction
        :param list seqs_true: reference
        :return: average sentence-level CER score
        :rtype float
        r   Nr   rl   )rm   rn   r   ro   rq   r   rr   r7   )rZ   rh   ri   rm   char_edsrt   r   r   r   r{   r|   r   r   r   ra      s   
zErrorCalculator.calculate_cerc                 C   sp   ddl }g g }}t|D ] \}}|| }| }	| }
|||	|
 |t|
 qtt|t| S )zCalculate sentence-level WER score.

        :param list seqs_hat: prediction
        :param list seqs_true: reference
        :return: average sentence-level WER score
        :rtype float
        r   N)rm   rn   r4   ro   rq   r   rr   r7   )rZ   rh   ri   rm   word_edsword_ref_lensr   r   r   	hyp_words	ref_wordsr   r   r   rb      s   
zErrorCalculator.calculate_wer)FF)F)__name__
__module____qualname____doc__rR   rj   r_   r`   ra   rb   __classcell__r   r   r]   r   rP   d   s    
"rP   )Nr   )r   rH   )r   r.   r8   r:   	itertoolsr   numpyr0   r   logexpr$   rG   rO   objectrP   r   r   r   r   <module>   s   
"
"