o
    -wiV$                     @   s   d Z ddl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
mZ ddlZddlmZ zddlZe s<ed ddlmZ W n eyQ   ed Y nw G d	d
 d
eZG dd dejZdS )a  Hooks that add fast.ai v1 Learners to Weights & Biases through a callback.

Requested logged data can be configured through the callback constructor.

Examples:
    WandbCallback can be used when initializing the Learner::

    ```
        from wandb.fastai import WandbCallback
        [...]
        learn = Learner(data, ..., callback_fns=WandbCallback)
        learn.fit(epochs)
    ```

    Custom parameters can be given using functools.partial::

    ```
        from wandb.fastai import WandbCallback
        from functools import partial
        [...]
        learn = Learner(data, ..., callback_fns=partial(WandbCallback, ...))
        learn.fit(epochs)
    ```

    Finally, it is possible to use WandbCallback only when starting
    training. In this case it must be instantiated::

    ```
        learn.fit(..., callbacks=WandbCallback(learn))
    ```

    or, with custom parameters::

    ```
        learn.fit(..., callbacks=WandbCallback(learn, ...))
    ```
    N)Path)AnyLiteralOptional)TrackerCallback)ipythonAggz7matplotlib required if logging sample image predictionsc                       s   e Zd ZdZdZ								d%d	d
deed  dedee ded deed  dee	 de
de
ddf fddZdeddf fddZde
dede	deddf
dd Zdeddfd!d"Zd&d#d$Z  ZS )'WandbCallbacka  Callback for saving model topology, losses & metrics.

    Optionally logs weights, gradients, sample predictions and best trained model.

    Args:
        learn (fastai.basic_train.Learner): the fast.ai learner to hook.
        log (str): "gradients", "parameters", "all", or None. Losses & metrics are always logged.
        save_model (bool): save model at the end of each epoch. It will also load best model at the end of training.
        monitor (str): metric to monitor for saving best model. None uses default TrackerCallback monitor value.
        mode (str): "auto", "min" or "max" to compare "monitor" values and define best model.
        input_type (str): "images" or None. Used to display sample predictions.
        validation_data (list): data used for sample predictions if input_type is set.
        predictions (int): number of predictions to make if input_type is set and validation_data is None.
        seed (int): initialize random generator for sample predictions if input_type is set and validation_data is None.
    F	gradientsTNauto$   90  learnzfastai.basic_train.Learnerlog)r
   
parametersall
save_modelmonitormode)r   minmax
input_typeimagesvalidation_datapredictionsseedreturnc
                    s   t jd u r	td|d u rt j |d n	t j ||d || _tt jjd | _|| _	|| _
d | _|| _|rb| jsdt|	}
t|t jj}|
tt jj|} fdd|D | _d S d S d S )Nz1You must call wandb.init() before WandbCallback())r   )r   r   zbestmodel.pthc                    s   g | ]} j j| qS  )datavalid_ds).0ir   r   ^/home/ubuntu/sommelier/.venv/lib/python3.10/site-packages/wandb/integration/fastai/__init__.py
<listcomp>s   s    z*WandbCallback.__init__.<locals>.<listcomp>)wandbrun
ValueErrorsuper__init__r   r   dir
model_pathr   r   bestr   randomRandomr   lenr   r   samplerange)selfr   r   r   r   r   r   r   r   r   wandb_randomindices	__class__r"   r#   r)   P   s"   


zWandbCallback.__init__kwargsc                    s2   t    tjsdt_tj| jj| jd dS dS )z=Call watch method to log model topology, gradients & weights.T)r   N)	r(   on_train_beginr	   _watch_calledr%   watchr   modelr   )r2   r7   r5   r   r#   r8   u   s
   
zWandbCallback.on_train_beginepochsmooth_losslast_metricsc           	   
   K   s8  | j rA|  }|durA| || jrAtd| d| j d| d || _| jd}| j	
| W d   n1 s<w   Y  | jrz|   W n7 tye } zt|j d| _W Y d}~n!d}~w ty } ztd|  d| _W Y d}~nd}~ww dd	 tt| j	jj||g| D }t| dS )
z\Log training loss, validation loss and custom metrics & log prediction samples & save model.NzBetter model found at epoch z with z value: .wbz"Unable to log prediction samples.
c                 S   s   i | ]\}}||qS r   r   )r    namestatr   r   r#   
<dictcomp>   s    z.WandbCallback.on_epoch_end.<locals>.<dictcomp>)r   get_monitor_valueoperatorr,   r%   termlogr   r+   openr   saver   _wandb_log_predictionsFastaiErrortermwarnmessage	Exceptionlistziprecordernamesr   )	r2   r<   r=   r>   r7   current
model_fileelogsr   r   r#   on_epoch_end   s8   zWandbCallback.on_epoch_endc                 K   sl   | j r2| j r4| jd}| jj|dd td| j  W d   dS 1 s+w   Y  dS dS dS )zLoad the best model.rbF)purgezLoaded best saved model from N)r   r+   is_filerG   r   loadr%   rF   )r2   r7   rS   r   r   r#   on_train_end   s   
"zWandbCallback.on_train_endc              
   C   s  g }| j du r	dS | j D ]\}}z| j|}W n ty#   tdw |d jr1|d  dkrE|tj	|j
d| d|d  d nt|dr|tj	|j
d	d
d |d df|dffD ]C\}}d}tjd|d}|j\}	}
||
| |	|  t|g d}|  || |j||d |tj	||d t| q`nCt|drt|jdkst|jd
kr|jd dv r|tj	|j
d	d
dtj	|d j
ddtj	|j
ddg n|tj	|j
d	d tjd|idd qdS )zLog prediction samples.NzFUnable to run "predict" method from Learner to log prediction samples.   zGround Truth: z
Prediction: r   )captionshowz
Input data   )r]   grouping
PredictionzGround Truthd   F)frameondpi)        re         ?rf   )axyshape   )r\   r_      zPrediction Samples)commit)r   r   predictrM   rJ   ri   dimappendr%   Imager   hasattrpltfiguresizeset_size_inchesAxesset_axis_offadd_axesr^   closer/   extendr   )r2   pred_logxrh   predimcaptmy_dpifighwrg   r   r   r#   rI      sV   




*
z$WandbCallback._wandb_log_predictions)r
   TNr   NNr   r   )r   N)__name__
__module____qualname____doc__r9   r   r   boolstrrN   intr)   r   r8   floatrV   r[   rI   __classcell__r   r   r5   r#   r	   <   s\    

	
%
&	r	   c                   @   s   e Zd ZdS )rJ   N)r   r   r   r   r   r   r#   rJ      s    rJ   )r   r-   syspathlibr   typingr   r   r   fastaifastai.callbacksr   r%   wandb.sdk.libr   
matplotlib
in_jupyterusematplotlib.pyplotpyplotrr   ImportErrorrK   r	   ErrorrJ   r   r   r   r#   <module>   s(    &
 7