o
    –h{"  ã                   @   sÌ   d Z ddlZddlZddlmZ ddlZddlZddlmZ ddl	m  m
Z
 ddlm  m  mZ ddlmZ ddlmZ ddlmZmZ ddlmZ dd	lmZ e d
¡Zdd„ ZG dd„ deƒZdS )z;
A trainer class to handle training and testing of models.
é    N)ÚCounter)Únn)ÚTrainer)ÚSeq2SeqModel)ÚutilsÚloss)ÚCharacterClassifier)ÚVocabÚstanzac                    s4   ‡ fdd„| dd… D ƒ}| d }| d }|||fS )z& Unpack a batch from the data loader. c                    s"   g | ]}|d ur|  ˆ ¡nd ‘qS ©N)Úto)Ú.0Úb©Údevice© úT/var/www/html/env_mimamsha/lib/python3.10/site-packages/stanza/models/mwt/trainer.pyÚ
<listcomp>   s   " z unpack_batch.<locals>.<listcomp>Né   é   r   )Úbatchr   ÚinputsÚ	orig_textÚorig_idxr   r   r   Úunpack_batch   s   
r   c                   @   s^   e Zd ZdZddd„Zddd„Zdd	d
„Zdd„ Zdd„ Zdd„ Z	dd„ Z
dd„ Zdd„ ZdS )r   z  A trainer for training models. Nc                 C   sÌ   |d ur
|   |¡ n%|| _|d rd | _n| dd¡r!t|ƒ| _nt||d| _|| _tƒ | _| jd sd| j 	|¡| _| j dd¡rHt
 ¡ | _nt | jj¡ 	|¡| _t | jd | j| jd ¡| _d S d S )NÚ	dict_onlyÚforce_exact_piecesF)Ú
emb_matrixÚoptimÚlr)ÚloadÚargsÚmodelÚgetr   r   ÚvocabÚdictÚexpansion_dictr   r   ÚCrossEntropyLossÚcritr   ÚSequenceLossÚsizer   Úget_optimizerÚ	optimizer)Úselfr!   r$   r   Ú
model_filer   r   r   r   Ú__init__   s"   
"úzTrainer.__init__Fc                 C   s4  t | j ¡ ƒj}t||ƒ\}}}|\}}}	}
|r| j ¡  n
| j ¡  | j ¡  | j	 
dd¡r`|  ||¡}t|j tj¡ ¡  d¡ƒ}tjjj||dd}tjjj|	|dd}|  |j|j¡}n|  |||	¡\}}|  | d| jj¡|
 d¡¡}|j ¡ }|r|S | ¡  tjj | j ¡ | j	d ¡ | j ¡  |S )Nr   Fé   T)Úbatch_firstéÿÿÿÿÚmax_grad_norm)Únextr"   Ú
parametersr   r   ÚevalÚtrainr,   Ú	zero_gradr!   r#   ÚlistÚdataÚeqÚconstantÚPAD_IDÚlongÚsumr   r   ÚrnnÚpack_padded_sequencer(   Úviewr$   r*   ÚitemÚbackwardÚtorchÚclip_grad_norm_Ústep)r-   r   r6   r   r   Ú_r   ÚsrcÚsrc_maskÚtgt_inÚtgt_outÚ	log_probsÚsrc_lensÚpacked_outputÚ
packed_tgtr   Úloss_valr   r   r   Úupdate5   s,   



zTrainer.updateTc                    s˜  ˆ d u r| j ‰ t| j ¡ ƒj}t||ƒ\}}}|\}	}
}}| j ¡  |	 d¡}| j 	dd¡r”|  |	|
¡}|d d …d d …df |d d …d d …df k}t
|
j tj¡ ¡  d¡ƒ}g }t|	||ƒD ]2\}}}ˆ  |¡}g }td|d ƒD ]}|| r~| d¡ | || ¡ qsd |¡ ¡ }| |¡ q`n.| jj|	|
| jd |d\}}‡ fd	d
„|D ƒ}t |¡}dd
„ |D ƒ}dd
„ t||ƒD ƒ}|rÊt ||¡}|S )Nr   r   Fr0   ú Ú Ú	beam_size)Únever_decode_unkc                    s   g | ]}ˆ   |¡‘qS r   )Úunmap)r   Úids©r$   r   r   r   n   ó    z#Trainer.predict.<locals>.<listcomp>c                 S   s   g | ]}d   |¡‘qS )rT   )Újoin)r   Úseqr   r   r   r   q   rZ   c                 S   s$   g | ]\}}|rd |v r|n|‘qS )rS   r   )r   ÚxÚyr   r   r   r   x   s   $ )r$   r4   r"   r5   r   r   r6   r*   r!   r#   r9   r:   r;   r<   r=   r>   r?   ÚziprW   ÚrangeÚappendr[   ÚstripÚpredictr   Úprune_decoded_seqsÚunsort)r-   r   re   rV   r$   r   r   r   r   rI   rJ   ÚtgtÚtgt_maskÚ
batch_sizerM   ÚcutsrN   Úpred_tokensÚsrc_idsÚcutÚsrc_lenÚ	src_charsÚpred_seqÚchar_idxÚpredsrH   Ú	pred_seqsr   rY   r   rc   T   s<   

,

ø

zTrainer.predictc                 C   sb   t ƒ }| dd„ |D ƒ¡ tƒ }| ¡ D ]\}}|\}}||vr)||kr)|| j|< | |¡ qdS )z; Train a MWT expander given training word-expansion pairs. c                 S   s   g | ]
}|d  |d f‘qS )r   r0   r   )r   Úpr   r   r   r      s    z&Trainer.train_dict.<locals>.<listcomp>N)r   rR   ÚsetÚmost_commonr&   Úadd)r-   ÚpairsÚctrÚseenrs   rH   ÚwÚlr   r   r   Ú
train_dict}   s   
zTrainer.train_dictc                 C   s   | j  |¡}|dur|S | ¡ r | j  | ¡ ¡}|dur | ¡ S |d  ¡ rF|dd…  ¡ rF| j  | ¡ ¡}|durF|d  ¡ |dd…  S dS )z–
        Check the expansion dictionary for the word along with a couple common lowercasings of the word

        (Leadingcase and UPPERCASE)
        Nr   r0   )r&   r#   ÚisupperÚlowerÚupperÚislower)r-   ÚwordÚ	expansionr   r   r   Údict_expansion‹   s   zTrainer.dict_expansionc                 C   s:   g }|D ]}|   |¡}|dur| |¡ q| |¡ q|S )z+ Predict a list of expansions given words. N)rƒ   ra   )r-   ÚwordsÚ
expansionsrz   r‚   r   r   r   Úpredict_dict£   s   
zTrainer.predict_dictc                 C   sX   g }t |ƒt |ƒksJ ‚t||ƒD ]\}}|  |¡}|dur$| |¡ q| |¡ q|S )z7 Ensemble the dict with statistical model predictions. N)Úlenr_   rƒ   ra   )r-   ÚcandsÚother_predsr…   ÚcÚpredr‚   r   r   r   Úensemble®   s   
zTrainer.ensemblec                 C   sr   | j d ur
| j  ¡ nd | j| j ¡ | jdœ}ztj||dd t d 	|¡¡ W d S  t
y8   t d¡ Y d S w )N)r"   r%   r$   ÚconfigF)Ú_use_new_zipfile_serializationzModel saved to {}z#Saving failed... continuing anyway.)r"   Ú
state_dictr&   r$   r!   rE   ÚsaveÚloggerÚinfoÚformatÚBaseExceptionÚwarning)r-   ÚfilenameÚparamsr   r   r   r   º   s   üÿzTrainer.savec                 C   s°   zt j|dd„ dd}W n ty   t d |¡¡ ‚ w |d | _|d | _| jd sK| j d	d
¡r:t	| jƒ| _
nt| jƒ| _
| j
j|d d
d nd | _
t |d ¡| _d S )Nc                 S   s   | S r   r   )ÚstorageÚlocr   r   r   Ú<lambda>É   s    zTrainer.load.<locals>.<lambda>T)Úweights_onlyzCannot load model from {}r   r%   r   r   Fr"   )Ústrictr$   )rE   r    r”   r‘   Úerrorr“   r!   r&   r#   r   r"   r   Úload_state_dictr	   r$   )r-   r–   Ú
checkpointr   r   r   r    Ç   s   þ


zTrainer.load)NNNNN)F)TFN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r/   rR   rc   r|   rƒ   r†   rŒ   r   r    r   r   r   r   r      s    


)r   )r£   ÚsysÚnumpyÚnpÚcollectionsr   ÚloggingrE   r   Útorch.nn.initÚinitÚ%stanza.models.common.seq2seq_constantÚmodelsÚcommonÚseq2seq_constantr<   Ústanza.models.common.trainerr   ÚBaseTrainerÚ"stanza.models.common.seq2seq_modelr   Ústanza.models.commonr   r   Ú&stanza.models.mwt.character_classifierr   Ústanza.models.mwt.vocabr	   Ú	getLoggerr‘   r   r   r   r   r   Ú<module>   s"    
