o
    pi=                     @   s`   d dl Z d dlZd dlZddlmZ G dd dZG dd dZ						dd
dZdd Z	dS )    N   )common_functionsc                   @   s   e Zd Z					d6ddZdd	 Z	
			d7ddZdd Zd8ddZd9ddZ		d:ddZ	dd Z
d;ddZ	d<ddZdd Zdd  Zd!d" Zd=d#d$Z	%d>d&d'Zd?d(d)Zd*d+ Z			d@d,d-Zd.d/ Zd0d1 Zd2d3 Zd4d5 ZdS )AHookContainerNmean_average_precision_at_rvalT2   c                 C   s2   || _ || _g d| _|| _|| _|| _|| _d S )N)models
optimizerslr_schedulers
loss_funcsmining_funcs)record_keeperrecord_group_name_prefixsaveable_trainer_objectsprimary_metricvalidation_split_namedo_save_modelslog_freq)selfr   r   r   r   save_modelsr    r   a/home/ubuntu/.local/lib/python3.10/site-packages/pytorch_metric_learning/utils/logging_presets.py__init__   s   	

zHookContainer.__init__c                 C   s   |j | j dkr
d S |jjddig|jjddig|jdtjjt	gig|j
i g|ji g|jd| jigg}|D ]\}}| jj|| fi | q5d S )Nr   parent_nameloss_historiesloss_weightsrecursive_typescustom_attr_func)	iterationr   loss_trackerlossesr   r   torchnnModuledictr   r   r	   optimizer_custom_attr_funcr   update_recordsget_global_iteration)r   trainerrecord_theserecordkwargsr   r   r   end_of_iteration_hook-   s(   z#HookContainer.end_of_iteration_hookr   c           	         sX   j j vrtdj tjst  fdd}|S )Nz1HookContainer `primary_metric` must be one of: {}c              	      s<   d}| j  dkr|  }| j |}|S )NTr   )epochsave_models_and_evalpatience_remaining)r(   continue_training
best_epochdataset_dictmodel_folderpatiencer   splits_to_evaltest_collate_fntest_intervaltesterr   r   actual_hookW   s   	z4HookContainer.end_of_epoch_hook.<locals>.actual_hook)	r   accuracy_calculatorget_curr_metrics
ValueErrorformatospathexistsmakedirs)	r   r9   r3   r4   r8   r5   r6   r7   r:   r   r2   r   end_of_epoch_hookD   s   

zHookContainer.end_of_epoch_hookc           	      C   st   |j  D ]2\}}|d }| jj||| ||d | |||\}}}}||d}| jj||| ||d qd S )Nr-   )r   )r1   best_accuracy)all_accuraciesitemsr   r&   record_group_nameis_new_best_accuracy)	r   r9   
split_name
accuraciesr-   _r1   rD   bestr   r   r   end_of_testing_hookj   s"   


z!HookContainer.end_of_testing_hookFc                    sr   |d u rt t j rdnd}tj|d|d\}}|dkr5 fdd| jD D ]}tj||||dd	 q(|d
 S )Ncudacpuztrunk_*.pth)rL   r   c                       g | ]}t  |i qS r   getattr.0xr(   r   r   
<listcomp>       z:HookContainer.load_latest_saved_models.<locals>.<listcomp>T)log_if_successfulr   )r!   devicerN   is_availablec_flatest_versionr   load_dict_of_models)r   r(   r4   rZ   rL   resume_epochmodel_suffixobj_dictr   rV   r   load_latest_saved_models   s   



z&HookContainer.load_latest_saved_modelsc                    sL   | j r" fdd| jD D ]}t||| |d ur!t||| qd S d S )Nc                    rP   r   rQ   rS   rV   r   r   rW      rX   z-HookContainer.save_models.<locals>.<listcomp>)r   r   r\   save_dict_of_modelsdelete_dict_of_models)r   r(   r4   curr_suffixprev_suffixra   r   rV   r   r      s   

zHookContainer.save_modelsc                 C   s   |j }||||jd |jd || | || j\}	}
| || j|\}}}}| j  || | 	|||||  |r]t
jd| d| }|	d urSd|	 nd }| 	|||| |S )NtrunkembedderzNew best accuracy! {}zbest%d)r-   testr   get_best_epoch_and_accuracyr   rH   r   save_recordsstep_lr_plateau_schedulersr   r\   LOGGERinfor>   )r   r(   r3   r4   r8   r9   r6   
collate_fnr-   prev_best_epochrK   is_new_bestcurr_accuracyr1   rD   re   rf   r   r   r   r.      s@   


z"HookContainer.save_models_and_evalc                 C   sJ   |  ||}| ||\}}d}||ks|d u r||}}d}||||fS )NFT)get_curr_primary_metricrj   )r   r9   rI   r-   rr   r1   rD   rq   r   r   r   rH      s   
z"HookContainer.is_new_best_accuracyr   c                 C   sV   t |dkrdnd|}d}| j|si S | jjd||dd}|dd  |S )	Nr   *, r   SELECT {} FROM {}Treturn_dictid)lenjoinr   table_existsqueryr>   pop)r   
loss_namescolumns
table_nameoutputr   r   r   get_loss_history   s   zHookContainer.get_loss_historyc                    sb    ||jsi S  fdd}t|dkr|njg}|||}|dd  |S )Nc                    s,    rdnd|  } d | }jj|ddS )Nrt   	epoch, %srv   Trw   )r>   r   r}   )keysr}   return_all_metricsr   r   r   r   get_accuracies      z:HookContainer.get_accuracy_history.<locals>.get_accuraciesr   ry   )rG   r   r|   rz   r   try_keysr~   )r   r9   rI   r   metricsr   r   r   r   r   r   get_accuracy_history   s   z"HookContainer.get_accuracy_historyc                    s    fdd}|  |S )Nc                    s   j   |  S N)rE   )keyrI   r9   r   r   get_curr   s   z7HookContainer.get_curr_primary_metric.<locals>.get_curr)try_primary_metric)r   r9   rI   r   r   r   r   rs      s   z%HookContainer.get_curr_primary_metricc              
      sN   dD ]" d  fdd|D }z||W   S  ttjfy$   Y qw t)N)TFru   c                    s   g | ]}j | jd qS ))averagelabel_hierarchy_level)accuracies_keynamer   )rT   kr   r9   r   r   rW      s    z*HookContainer.try_keys.<locals>.<listcomp>)r{   KeyErrorsqlite3OperationalError)r   
input_keysr9   
input_funcr   r   r   r   r      s   
zHookContainer.try_keysc                 C   s   |  | jg||S r   )r   r   )r   r9   r   r   r   r   r   
     z HookContainer.try_primary_metricc                    s:    ||jsg S  fdd}||S )Nc                    s,   rdnd|  }d|f }j | fS )Nrt   r   zSELECT %s FROM %s WHERE epoch=?)r   r}   )r   r   r}   r-   
select_allr   r   r   r   r     r   z=HookContainer.get_accuracies_of_epoch.<locals>.get_accuraciesrG   r   r|   r   )r   r9   rI   r-   r   r   r   r   r   get_accuracies_of_epoch  s
   z%HookContainer.get_accuracies_of_epochc                    s>    ||jsg d fS  fdd}||S )Nc                    sN   rdnd|  }d dgt  }d|| |}j|   }|| fS )Nrt   r   ru   ?zSELECT {0} FROM {1} WHERE {2}=
                        (SELECT max({2}) FROM {1} WHERE epoch NOT IN ({3}))
                        AND epoch NOT IN ({3}))r{   rz   r>   r   r}   )r   r   paramsr}   r   ignore_epochr   r   r   r   r   r   "  s   zBHookContainer.get_accuracies_of_best_epoch.<locals>.get_accuraciesr   )r   r9   rI   r   r   r   r   r   r   get_accuracies_of_best_epoch  s
   z*HookContainer.get_accuracies_of_best_epochc                 C   s>   | j ||d|d\}}t|dkr|d d |d | fS dS )NF)r   r   r   r-   Nr   )r   rz   )r   r9   rI   r   rJ   r   r   r   r   rj   /  s   
z)HookContainer.get_best_epoch_and_accuracyc                 C   s0   |d ur|d ur|| |krt jd dS dS )Nz+Validation accuracy has plateaued. Exiting.FT)r\   rm   rn   )r   r-   r1   r5   r   r   r   r/   7  s
   z HookContainer.patience_remainingc	           	      C   sH   |r|  ||||}t|dkrtjd dS ||||||| dS )Nr   zAlready evaluatedFT)get_splits_to_evalrz   r\   rm   rn   ri   )	r   r9   r3   r-   rg   rh   r6   ro   skip_eval_if_already_doner   r   r   run_tester_separately>  s   z#HookContainer.run_tester_separatelyc                 C   sJ   |d u r
t | n|}g }|D ]}t| |||dkr"|| q|S r   )listr   rz   r   append)r   r9   r3   r-   input_splits_to_evalr6   splitr   r   r   r   S  s   
z HookContainer.get_splits_to_evalc                 C   s&   | j rd| j  nd}||d7 }|S )Nz%s_ rJ   )r   description_suffixes)r   r9   base_record_group_namer   r   r   r   _  s   z$HookContainer.base_record_group_namec           	      C   s|   |  |}| }ddd t|j| D }||krd}| d| d| }| jj D ]\}}||kr;|} |S q.|S )N_and_c                 S   s   g | ]}|  qS r   )upper)rT   namer   r   r   rW   l  s    z3HookContainer.record_group_name.<locals>.<listcomp>r   rK   _vs_)r   r   r{   sortedreference_split_namesr   hash_maprF   )	r   r9   rI   r   query_set_labelreference_sets_labelrG   r   r   r   r   r   rG   h  s    
zHookContainer.record_group_namec                 C   s   d|j d d iS )Nlrr   )param_groups)r   	optimizerr   r   r   r%   y  r   z(HookContainer.optimizer_custom_attr_func)Nr   r   Tr   )r   NNN)NFr   )NN)r   )Fr   )T)Tr   )r   )NNT)__name__
__module____qualname__r   r,   rC   rM   rb   r   r.   rH   r   r   rs   r   r   r   r   rj   r/   r   r   r   rG   r%   r   r   r   r   r      sN    

&


,





	r   c                   @   s   e Zd Zdd ZdZdZdS )EmptyContainerc                 G   s   d S r   r   )r   argsr   r   r   rC   ~  s   z EmptyContainer.end_of_epoch_hookN)r   r   r   rC   r,   rM   r   r   r   r   r   }  s    r   TFc              
   C   s   z/dd l }ddlm} |j| ||||d}|d ur||dnd }	|j|	|t d}
|
||	fW S  tyT } ztj	| tj	d tj	d W Y d }~dS d }~ww )	Nr   )SummaryWriter)folderglobal_db_pathexperiment_nameis_new_experiment
save_lists)log_dir)tensorboard_writerrecord_writerattributes_to_search_forz+There won't be any logging or model saving.z2To fix this, pip install record-keeper tensorboard)NNN)
r   torch.utils.tensorboardr   RecordWriterRecordKeeperr\   (list_of_recordable_attributes_list_namesModuleNotFoundErrorrm   warning)
csv_foldertensorboard_folderr   r   r   r   record_keeper_packager   r   r   r   er   r   r   get_record_keeper  s6   	
r   c                 K   s&   | r
t | fi |S tjd t S )Nz8No record_keeper, so no preset hooks are being returned.)r   r\   rm   r   r   )r   r+   r   r   r   get_hook_container  s   r   )NNNTF)
r?   r   r!   r   r   r\   r   r   r   r   r   r   r   r   <module>   s      q

%