o
    xi?$                     @  s   d Z ddlmZ ddlZddlmZ ddl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, ...))
    ```
    )annotationsN)Path)AnyLiteral)TrackerCallback)ipythonAggz7matplotlib required if logging sample image predictionsc                      sd   e Zd ZdZdZ								d-d. fddZd/ fd d!Zd0d'd(Zd/d)d*Zd1d+d,Z	  Z
S )2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  learnfastai.basic_train.Learnerlog0Literal['gradients', 'parameters', 'all'] | None
save_modelboolmonitor
str | NonemodeLiteral['auto', 'min', 'max']
input_typeLiteral['images'] | Nonevalidation_datalist | NonepredictionsintseedreturnNonec
                   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!   U/home/ubuntu/.local/lib/python3.10/site-packages/wandb/integration/fastai/__init__.py
<listcomp>t   s    z*WandbCallback.__init__.<locals>.<listcomp>)wandbrun
ValueErrorsuper__init__r   r   dir
model_pathr   r   bestr   randomRandomminlenr"   r#   samplerange)selfr   r   r   r   r   r   r   r   r   wandb_randomindices	__class__r&   r'   r-   Q   s"   


zWandbCallback.__init__kwargsr   c                   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   )r7   r<   r:   r!   r'   r=   v   s
   
zWandbCallback.on_train_beginepochsmooth_lossfloatlast_metricslistc           	   
   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operatorr0   r)   termlogr   r/   openr   saver   _wandb_log_predictionsFastaiErrortermwarnmessage	ExceptionrE   ziprecordernamesr   )	r7   rA   rB   rD   r<   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_filerN   r   loadr)   rM   )r7   r<   rY   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   )rc   grouping
PredictionzGround Truthd   F)frameondpi)        rk         ?rl   )axyshape   )rb   re      zPrediction Samples)commit)r   r   predictrT   rQ   ro   dimappendr)   Imager"   hasattrpltfiguresizeset_size_inchesAxesset_axis_offadd_axesrd   closer4   extendr   )r7   pred_logxrn   predimcaptmy_dpifighwrm   r!   r!   r'   rP      sV   




*
z$WandbCallback._wandb_log_predictions)r
   TNr   NNr   r   )r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r    )r<   r   r   r    )
rA   r   rB   rC   rD   rE   r<   r   r   r    )r   r    )__name__
__module____qualname____doc__r>   r-   r=   r\   ra   rP   __classcell__r!   r!   r:   r'   r	   =   s     %

&r	   c                   @  s   e Zd ZdS )rQ   N)r   r   r   r!   r!   r!   r'   rQ      s    rQ   )r   
__future__r   r1   pathlibr   typingr   r   fastaifastai.callbacksr   r)   wandb.sdk.libr   
matplotlib
in_jupyterusematplotlib.pyplotpyplotrx   ImportErrorrR   r	   ErrorrQ   r!   r!   r!   r'   <module>   s(    &
 6