o
    miA                     @   sb  d Z ddlZddl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dlm  mZ ddlZddlmZ ddlmZmZ ddlmZ dd Zd	efd
dZdejv rYe  nede eeZdd Zdd Z dd Z!dd Z"dd Z#dd Z$dd Z%dd Z&e' Z(e!  dd Z)e) Z*G dd  d e*Z+G d!d" d"ejj,j-Z.G d#d$ d$ejj,j-Z/dS )%zkeras init.    N)chain)ValidationDataLogger)
Deprecated	deprecate)add_import_hookc                  C   sB   ddl m}  ddlm} || |dk rtd|  d d S d S )Nr   )__version__parse_versionz2.4.0zKeras version z0 is not fully supported. Required keras >= 2.4.0)kerasr   
wandb.utilr	   wandbtermwarn)keras_versionr	    r   [/home/ubuntu/SoloSpeech/.venv/lib/python3.10/site-packages/wandb/integration/keras/keras.py_check_keras_version   s   
r   returnc                  C   s&   ddl m}  | tj| dkrdS dS )zFFLOPS computation is restricted to TF 2.x as it requires tf.compat.v1.r   r   z2.0.0TF)r   r	   tfr   r   r   r   r   _can_compute_flops   s   r   r
   c                 C   sF   t jd}|r!t|dr!|jf}t|dr||jf }t| |S dS )Nz&tensorflow.python.data.ops.dataset_ops	DatasetV2	DatasetV1F)r   util
get_modulehasattrr   r   
isinstance)datadataset_opsdataset_typesr   r   r   
is_dataset2   s   

r   c                 C   st   t jjjf}tjd}|r+||jf }t|dr ||j	f }nt|dr+||j
f }t| dp9t| dp9t| |S )Nz'tensorflow.python.data.ops.iterator_opsEagerIterator
IteratorV2next__next__)r   r
   utilsSequencer   r   r   Iteratorr   r   r    r   )r   typesiterator_opsr   r   r   is_generator_like=   s   

r(   c            
         s<  ddl m  ddlm}  | d| tj  kr| dk rLn n-d}zddlm} ddlm} dd	lm	} W nZ t
tfyK   td
 td Y d S w d}ddlm} zddlm} dd	lm	} W n- t
tfy   z
ddlm}m} W n t
tfy   td
 td Y Y d S w Y nw tjd}tj| d}|r|jjn|r|jj|j|j fddfdd}fdd}fdd}	|_||_|_||_tjd | ddg tjd | ddg |r|	|j_tjd ddg d S |r|	|j_tjd | ddg d S d S ) Nr   contextr   z2.6.0z2.13.0zkeras.engine)training)training_arrays_v1)training_generator_v1z Unable to patch Tensorflow/Kerasz(exception while trying to patch_tf_kerasztensorflow.python.keras.engine)training_arraystraining_generatorz*tensorflow.python.keras.engine.training_v2z.training_v1c                    s   t | trBt r | _d S t r$ rt | _d S td d S t  t	r=t  d t
jr= fdd}| | _d S  | _d S d S )Nz<Found a validation dataset in graph mode, can't patch Keras.r   c                   3   s    	 t   V  qN)Kget_sessionrunr   val_datar   r   gen   s   z4patch_tf_keras.<locals>.set_wandb_attrs.<locals>.gen)r   WandbCallbackr(   	generatorr   executing_eagerlyiterr   r   tupler   Tensorvalidation_data)cbkr5   r6   r)   r4   r   set_wandb_attrs   s   


z'patch_tf_keras.<locals>.set_wandb_attrsc                     sV   | dg }| d}| d}|r$|r$|D ]}||d |d f q | i |S )N	callbacks
val_inputsval_targetsr   get)argskwargscbksrA   rB   r>   )
old_arraysr?   r   r   
new_arrays   s   

z"patch_tf_keras.<locals>.new_arraysc                     <   | dg }| d}|r|D ]}|| q | i |S Nr@   r=   rC   rE   rF   rG   r5   r>   )old_generatorr?   r   r   new_generator      
z%patch_tf_keras.<locals>.new_generatorc                     rJ   rK   rC   rL   )old_v2r?   r   r   new_v2   rO   zpatch_tf_keras.<locals>.new_v2r
   z.training_arraysfit_loopz.training_generatorfit_generatorz/tensorflow.python.keras.engine.training_v2.Loopfitz.training.Model)tensorflow.python.eagerr*   r   r	   r   r   keras.enginer+   r,   r-   ImportErrorAttributeErrorr   	termerrorlogger	exceptiontensorflow.python.keras.enginer.   r/   r   r   LooprT   ModelrR   rS   orig_fit_looporig_fit_generatorpatchedappend)
r	   keras_enginer+   r.   r/   training_v2_1training_v2_2rI   rN   rQ   r   )r*   rH   rM   rP   r?   r   patch_tf_kerasL   sz   








rf   c                 C   s
   t | dS )Ndtype)r   arrayr   r   r   _array_has_dtype      
rj   c                 C   s:   t |s
t| d S t|st| d S t|| |< d S r0   )rj   _warn_not_loggingis_numeric_array_warn_not_logging_non_numericr   	Histogram)metricskeyvaluesr   r   r   _update_if_numeric   s   rs   c                 C   s   t | jt jS r0   )np
issubdtyperg   numberrh   r   r   r   rm         rm   c                 C      t jd|  ddd d S )Nz#Non-numeric values found in layer: z, not logging this layerFrepeatr   r   namer   r   r   rn         

rn   c                 C   rx   )NzLayer z1 has undetermined datatype not logging this layerFry   r{   r|   r   r   r   rl      r~   rl   c                  C   s<   ddl m}  | tj| dkrtjjjj}|S tjjj}|S )Nr   r   z2.9.0)r   r	   r   r   r
   
optimizerslegacy	Optimizer)r	   custom_optimizer_parent_classr   r   r   "_get_custom_optimizer_parent_class   s   
r   c                       s8   e Zd Z fddZdd Zdd Z fddZ  ZS )	_CustomOptimizerc                    s.   t  jdd t| j| _t| j| _d S )NCustomOptimizerr|   )super__init__r   function_resource_apply_dense_resource_apply_sparseself	__class__r   r   r      s   z_CustomOptimizer.__init__c                 C   s   | | d S r0   )assign)r   gradvarr   r   r   r     s   z&_CustomOptimizer._resource_apply_densec                 C      d S r0   r   )r   r   r   indicesr   r   r   r        z'_CustomOptimizer._resource_apply_sparsec                    s
   t   S r0   )r   
get_configr   r   r   r   r     rk   z_CustomOptimizer.get_config)__name__
__module____qualname__r   r   r   r   __classcell__r   r   r   r   r      s
    r   c                       s2   e Zd ZdZ fddZd	ddZdd Z  ZS )
_GradAccumulatorCallbackzbAccumulates gradients during a fit() call when used in conjunction with the CustomOptimizer above.c                    s,   t  | | | _dd |jD | _d S )Nc                 S   s   g | ]
}t t|jqS r   )rt   zerosr;   shape).0wr   r   r   
<listcomp>  s    z6_GradAccumulatorCallback.set_model.<locals>.<listcomp>)r   	set_modelget_weights
og_weightstrainable_weightsgradsr   modelr   r   r   r     s   
z"_GradAccumulatorCallback.set_modelNc                 C   s8   t | j| jjD ]
\}}|| 7 }q| j| j d S r0   )zipr   r   r   numpyset_weightsr   )r   batchlogsgr   r   r   r   on_batch_end  s   z%_GradAccumulatorCallback.on_batch_endc                 C   s   dd | j D S )Nc                 S   s   g | ]}|  qS r   )copy)r   r   r   r   r   r         z6_GradAccumulatorCallback.get_grads.<locals>.<listcomp>)r   r   r   r   r   	get_grads  rw   z"_GradAccumulatorCallback.get_gradsr0   )r   r   r   __doc__r   r   r   r   r   r   r   r   r     s
    
r   c                       sv  e Zd ZdZ																											dKd
dZdd Zdd Zdd Zdd Zdd Z	 fddZ
dLddZdMddZdMddZdMddZdMd d!ZdMd"d#ZdMd$d%ZdMd&d'ZdMd(d)ZdMd*d+ZdMd,d-ZdMd.d/ZdMd0d1ZdMd2d3ZdMd4d5ZdMd6d7Zd8d9 Zd:d; ZdNd<d=Zd>d? Zd@dA ZdBdC Z dDdE Z!dFdG Z"dHe#fdIdJZ$  Z%S )Or7   a  `WandbCallback` automatically integrates keras with wandb.

    Example:
        ```python
        model.fit(
            X_train,
            y_train,
            validation_data=(X_test, y_test),
            callbacks=[WandbCallback()],
        )
        ```

    `WandbCallback` will automatically log history data from any
    metrics collected by keras: loss and anything passed into `keras_model.compile()`.

    `WandbCallback` will set summary metrics for the run associated with the "best" training
    step, where "best" is defined by the `monitor` and `mode` attributes.  This defaults
    to the epoch with the minimum `val_loss`. `WandbCallback` will by default save the model
    associated with the best `epoch`.

    `WandbCallback` can optionally log gradient and parameter histograms.

    `WandbCallback` can optionally save training and validation data for wandb to visualize.

    Args:
        monitor: (str) name of metric to monitor.  Defaults to `val_loss`.
        mode: (str) one of {`auto`, `min`, `max`}.
            `min` - save model when monitor is minimized
            `max` - save model when monitor is maximized
            `auto` - try to guess when to save the model (default).
        save_model:
            True - save a model when monitor beats all previous epochs
            False - don't save models
        save_graph: (boolean) if True save model graph to wandb (default to True).
        save_weights_only: (boolean) if True, then only the model's weights will be
            saved (`model.save_weights(filepath)`), else the full model
            is saved (`model.save(filepath)`).
        log_weights: (boolean) if True save histograms of the model's layer's weights.
        log_gradients: (boolean) if True log histograms of the training gradients
        training_data: (tuple) Same format `(X,y)` as passed to `model.fit`.  This is needed
            for calculating gradients - this is mandatory if `log_gradients` is `True`.
        validation_data: (tuple) Same format `(X,y)` as passed to `model.fit`.  A set of data
            for wandb to visualize.  If this is set, every epoch, wandb will
            make a small number of predictions and save the results for later visualization. In case
            you are working with image data, please also set `input_type` and `output_type` in order
            to log correctly.
        generator: (generator) a generator that returns validation data for wandb to visualize.  This
            generator should return tuples `(X,y)`.  Either `validate_data` or generator should
            be set for wandb to visualize specific data examples. In case you are working with image data,
            please also set `input_type` and `output_type` in order to log correctly.
        validation_steps: (int) if `validation_data` is a generator, how many
            steps to run the generator for the full validation set.
        labels: (list) If you are visualizing your data with wandb this list of labels
            will convert numeric output to understandable string if you are building a
            multiclass classifier.  If you are making a binary classifier you can pass in
            a list of two labels ["label for false", "label for true"].  If `validate_data`
            and generator are both false, this won't do anything.
        predictions: (int) the number of predictions to make for visualization each epoch, max
            is 100.
        input_type: (string) type of the model input to help visualization. can be one of:
            (`image`, `images`, `segmentation_mask`, `auto`).
        output_type: (string) type of the model output to help visualization. can be one of:
            (`image`, `images`, `segmentation_mask`, `label`).
        log_evaluation: (boolean) if True, save a Table containing validation data and the
            model's predictions at each epoch. See `validation_indexes`,
            `validation_row_processor`, and `output_row_processor` for additional details.
        class_colors: ([float, float, float]) if the input or output is a segmentation mask,
            an array containing an rgb tuple (range 0-1) for each class.
        log_batch_frequency: (integer) if None, callback will log every epoch.
            If set to integer, callback will log training metrics every `log_batch_frequency`
            batches.
        log_best_prefix: (string) if None, no extra summary metrics will be saved.
            If set to a string, the monitored metric and epoch will be prepended with this value
            and stored as summary metrics.
        validation_indexes: ([wandb.data_types._TableLinkMixin]) an ordered list of index keys to associate
            with each validation example.  If log_evaluation is True and `validation_indexes` is provided,
            then a Table of validation data will not be created and instead each prediction will
            be associated with the row represented by the `TableLinkMixin`. The most common way to obtain
            such keys are is use `Table.get_index()` which will return a list of row keys.
        validation_row_processor: (Callable) a function to apply to the validation data, commonly used to visualize the data.
            The function will receive an `ndx` (int) and a `row` (dict). If your model has a single input,
            then `row["input"]` will be the input data for the row. Else, it will be keyed based on the name of the
            input slot. If your fit function takes a single target, then `row["target"]` will be the target data for the row. Else,
            it will be keyed based on the name of the output slots. For example, if your input data is a single ndarray,
            but you wish to visualize the data as an Image, then you can provide `lambda ndx, row: {"img": wandb.Image(row["input"])}`
            as the processor. Ignored if log_evaluation is False or `validation_indexes` are present.
        output_row_processor: (Callable) same as `validation_row_processor`, but applied to the model's output. `row["output"]` will contain
            the results of the model output.
        infer_missing_processors: (bool) Determines if `validation_row_processor` and `output_row_processor`
            should be inferred if missing. Defaults to True. If `labels` are provided, we will attempt to infer classification-type
            processors where appropriate.
        log_evaluation_frequency: (int) Determines the frequency which evaluation results will be logged. Default 0 (only at the end of training).
            Set to 1 to log every epoch, 2 to log every other epoch, and so on. Has no effect when log_evaluation is False.
        compute_flops: (bool) Compute the FLOPs of your Keras Sequential or Functional model in GigaFLOPs unit.
    val_lossr   autoFTN$   best_c                 K   s  t jd u r
t dttjdd t jjjt jd}d|j	_
W d    n1 s)w   Y  d | _|	d ur?t|	r<|	}n|	| _|
d u rEg }
|
| _t|d| _|| _|| _|| _|| _t d tjt jjd| _|| _|ruttjdd d| _|| _|| _|| _|| _ d	| _!|"d
d }|d urttj#dd |}|| _$|| _%|| _&|| _'|d urt()|nd | _*|| _+|| _,|| _-d | _.| jrt/t0j12dd dk rt3d| jd u rt4dt5| jt6t7frt8| jdkrt4d| j\| _9| _:n| j| _9d | _:|dvrt;d| d d}|dkrt<j=| _>t?d| _@n/|dkr)t<jA| _>t?d| _@n d| jv s6| jBdr@t<jA| _>t?d| _@n	t<j=| _>t?d| _@t jjC"| j, | j }|d ur^|| _@d | _D|| _E|| _F|| _G|| _H|| _Id	| _Jd S )Nz1You must call wandb.init() before WandbCallback()zWandbCallback is deprecated and will be removed in a future release. Please use the WandbMetricsLogger, WandbModelCheckpoint, and WandbEvalCallback callbacks instead. See https://docs.wandb.ai/guides/integrations/keras for more information.)
field_namewarning_message)r3   Td   zmodel-best.h5a<  The save_model argument by default saves the model in the HDF5 format that cannot save custom objects like subclassed models and custom layers. This behavior will be deprecated in a future release in favor of the SavedModel format. Meanwhile, the HDF5 model is saved as W&B files and the SavedModel as W&B Artifacts.F	data_typezThe data_type argument of wandb.keras.WandbCallback is deprecated and will be removed in a future release. Please use input_type instead.
Setting input_type = data_type..r      z3Gradient logging requires tensorflow 2.0 or higher.z8training_data argument is required for gradient logging.z+training data must be a tuple of length two)r   minmaxzWandbCallback mode z# is unknown, fallback to auto mode.r   r   infr   z-infaccfmeasure)Kr   r3   Errorr   r   keras_callback	wandb_lib	telemetryr*   featurer
   r=   r(   labelsr   predictionsmonitorverbosesave_weights_only
save_graphsaveospathjoindirfilepath
save_modelkeras_callback__save_modelsave_model_as_artifactlog_weightslog_gradientstraining_datar8   _graph_renderedrD   keras_callback__data_type
input_typeoutput_typelog_evaluationvalidation_stepsrt   ri   class_colorslog_batch_frequencylog_best_prefixcompute_flops_prediction_batch_sizeintr   r   split	Exception
ValueErrorr   listr;   len_training_data_x_training_data_yprintoperatorlt
monitor_opfloatbestgt
startswithsummary_validation_data_logger_validation_indexes_validation_row_processor_prediction_row_processor_infer_missing_processors_log_evaluation_frequency_model_trained_since_last_eval)r   r   r   moder   r   r   r   r   r=   r   r   r8   r   r   r   r   r   r   r   r   validation_indexesvalidation_row_processorprediction_row_processorinfer_missing_processorslog_evaluation_frequencyr   rF   telr   previous_bestr   r   r   r     s   












zWandbCallback.__init__c                 C   sN   | j j}|  |}tjj||}|j| j jt d d|_	|| _
t | _d S )N)loss	optimizerT)r   inputsr   r
   modelsr^   compiler  r   _wandb_internal_model_grad_accumulator_modelr   _grad_accumulator_callback)r   r  outputsgrad_acc_modelr   r   r   _build_grad_accumulator_model  s   
z+WandbCallback._build_grad_accumulator_modelc                 C   
   | j d uS r0   r   r   r   r   r   _implements_train_batch_hooks)  rk   z+WandbCallback._implements_train_batch_hooksc                 C   r  r0   r  r   r   r   r   _implements_test_batch_hooks,  rk   z*WandbCallback._implements_test_batch_hooksc                 C   r  r0   r  r   r   r   r   _implements_predict_batch_hooks/  rk   z-WandbCallback._implements_predict_batch_hooksc                 C   s
   || _ d S r0   )params)r   r  r   r   r   
set_params2  rk   zWandbCallback.set_paramsc                    s   t  | | jdkrt|jdkrtjj|jd jdd| _| jr9| j	d u r9t|j
dkr9tj|j
d j| _	| jrB|   d S d S )Nr      r   T)risky)r   r   r   r   r  r   r   guess_data_typer   r   r  r   r  r   r   r   r   r   5  s   zWandbCallback.set_modelc              
   C   s   | j rB| jrDz| jstd W d S | jj| j| jj|d d| _W d S  t	yA } ztdt
|  W Y d }~d S d }~ww d S d S )Nz/WandbCallback unable to read model from trainer)r   commitFz+Error during prediction logging for epoch: )r   r   r   r   r   log_predictionsmake_predictionspredictr   r   str)r   r  er   r   r   _attempt_evaluation_log@  s     z%WandbCallback._attempt_evaluation_logc              
   C   s  |d u ri }| j rtj|  dd | jrtj|  dd | jdv s(| jdv rT| jr1t	| j| _
| j
d u r<td n| j
rTt| j
dkrTtjd| j| jdidd | jdkrf|| j dkrf| jdd tjd|idd tj|d	d || j| _| jr| | j| jr| jr| jtjj| j | j < |tjjd
| jd< | jr| jstd|dd| j d| jdd| jd | jr| | | jr| jr| | | j| _d S d S d S )NFr  imageimagessegmentation_maskz9No validation_data set, pass a generator to the callback.r   examples)
num_imagesepochTz{}{}Epoch 05d:  improved from .5f to ) r   r   log_log_weightsr   _log_gradientsr   r   r8   r!   r=   r   r   _log_imagesr   r   r  rD   r   currentr   r   r   r3   r   formatr   r   r   _save_modelr   _save_model_as_artifact)r   r&  r   r   r   r   on_epoch_endP  sP   



&

zWandbCallback.on_epoch_endc                 C   r   r0   r   r   r   r   r   r   r   on_batch_begin  r   zWandbCallback.on_batch_beginc                 C   V   | j r| jstj| jtjjd< d| _| jr'|| j dkr)tj	|dd d S d S d S NgraphTr   r  
r   r   r   Graph
from_kerasr   r3   r   r   r-  r6  r   r   r   r        zWandbCallback.on_batch_endc                 C   s
   d| _ d S )NT)r   r6  r   r   r   on_train_batch_begin  rk   z"WandbCallback.on_train_batch_beginc                 C   r8  r9  r;  r6  r   r   r   on_train_batch_end  r>  z WandbCallback.on_train_batch_endc                 C   r   r0   r   r   r   r   r   r   on_test_begin  r   zWandbCallback.on_test_beginc                 C   r   r0   r   rA  r   r   r   on_test_end  r   zWandbCallback.on_test_endc                 C   r   r0   r   r6  r   r   r   on_test_batch_begin  r   z!WandbCallback.on_test_batch_beginc                 C   r   r0   r   r6  r   r   r   on_test_batch_end  r   zWandbCallback.on_test_batch_endc           	   
   C   sp  | j rzfd }| jr| j}nD| jrL| jstd n8d }d }t| jD ]$}t| j\}}|d u r5||}}q"tj	||ddtj	||dd}}q"||f}ntd |rht
|d |d | j| j| j| j| jd| _W n ty } ztdt|  W Y d }~nd }~ww | jrt rz
|  tjd< W d S  ty } ztd	 t| W Y d }~d S d }~ww d S d S )
NzzWandbCallback is unable to log validation data. When using a generator for validation_data, you must pass validation_stepsr   axiszWandbCallback is unable to read validation_data from trainer and therefore cannot log validation data. Ensure Keras is properly patched by calling `from wandb.keras import WandbCallback` at the top of your script.r  )r  targetsindexesr   r   class_labelsr   zcError initializing ValidationDataLogger in WandbCallback. Skipping logging validation data. Error: GFLOPsz'Unable to compute FLOPs for this model.)r   r=   r8   r   r   r   ranger!   rt   rb   r   r   r   r   r   r   r   r   r  r   r   	get_flopsr   rZ   r[   )	r   r   r=   xy_true_bxby_truer  r   r   r   on_train_begin  sf   
	
zWandbCallback.on_train_beginc                 C   s   | j r	|   d S d S r0   )r   r  rA  r   r   r   on_train_end  s   zWandbCallback.on_train_endc                 C   r   r0   r   rA  r   r   r   on_predict_begin  r   zWandbCallback.on_predict_beginc                 C   r   r0   r   rA  r   r   r   on_predict_end  r   zWandbCallback.on_predict_endc                 C   r   r0   r   r6  r   r   r   on_predict_batch_begin  r   z$WandbCallback.on_predict_batch_beginc                 C   r   r0   r   r6  r   r   r   on_predict_batch_end  r   z"WandbCallback.on_predict_batch_endc              	      s    d j d dkr1tjdkr fdd D }|S tjdkr(td dd  D }|S tjt dd	}tjdkrcg }|D ]}z
|j|  W qF t	y`   || Y qFw |S |}|S )
Nr   r  r   c                    s,   g | ]} d  dkrj d nj d  qS )r   g      ?r  )r   r   logitlogitsr   r   r   r     s    z5WandbCallback._logits_to_captions.<locals>.<listcomp>zpkeras model is producing a single output, so labels should be a length two array: ["False label", "True label"].c                 S   s   g | ]}|d  qS )r   r   rZ  r   r   r   r     r   rF  )
r   r   r   r   r   rt   argmaxstackrb   
IndexError)r   r]  captionsr   labelr   r\  r   _logits_to_captions  s0   z!WandbCallback._logits_to_captionsc                 C   sj   t |d jdks|d jd dkr|S | jd ur| jnttj|d jd }|tj|dd }|S )Nr   r   rY  r  rF  )r   r   r   rt   ri   r   r   r^  )r   masksr   imgsr   r   r   _masks_to_pixels  s   $
zWandbCallback._masks_to_pixelsc                    s  | j d }| j d }t|}||krtjj||dd}nt|}g }g }|D ]}|| }	||	 |||  q&| jjrN| jj	t
|dd}
| j  n#| jj	t
|| jd}
t|
t|krqd| _| jj	t
|| jd}
| jdkr| jdv r| | | jdkr| |
n|
}| jdkr| |n|} fd	d
t|D } fdd
t|D }ttt||S d S | jdv r,| jdkr| |n|}| jdkr| |
  fdd
t|D S | jdv r%| jdkr| |
n|
}| jdkr| |n|}dd
 t|D }dd
 t|D }dd
 t|D }ttt|||S dd
 |D S | jdv rh| jdkr=| |
n|
}| jdkrJ| |n|}dd
 t|D }dd
 t|D }ttt||S d S )Nr   r  F)replace
batch_sizerb  r   r#  c                    s$   g | ]\}}t j| | d dqS )r   )captiongroupingr   Imager   ir   ra  r   r   r   M  s    z-WandbCallback._log_images.<locals>.<listcomp>c                    "   g | ]\}}t j| | d qS )rj  rl  rn  rp  r   r   r   Q      c                    rq  rr  rl  rn  rp  r   r   r   _  rs  c                 S      g | ]\}}t j|d dqS )   rk  rl  rn  r   r   r   r   n      c                 S      g | ]	\}}t |qS r   rl  rn  r   r   r   r   r      c                 S   rx  r   rl  rn  r   r   r   r   u  ry  c                 S   s   g | ]}t |qS r   rl  )r   imgr   r   r   r     s    c                 S   rt  )r   rv  rl  rn  r   r   r   r     rw  c                 S   rx  r   rl  rn  r   r   r   r     ry  )r=   r   rt   randomchoicerL  rb   r   statefulr  r_  reset_statesr   r   r   rc  rf  	enumerater   r   from_iterabler   )r   r%  validation_Xvalidation_yvalidation_lengthr   	test_datatest_outputro  test_exampler   output_image_datareference_image_dataoutput_imagesreference_imagesinput_image_datainput_imagesr   rp  r   r0     s   























zWandbCallback._log_imagesc                 C   s   i }| j jD ]:}| }t|dkr t|d|j d |d  qt|dkr@t|d|j d |d  t|d|j d |d  q|S )Nr  zparameters/z.weightsr   r   z.bias)r   layersr   r   rs   r}   )r   rp   layerweightsr   r   r   r.    s    zWandbCallback._log_weightsc                 C   s   t j}t d | jj| j| jd| jgd t | | jj	}| jj
}i }t||D ]\}}t||d|jdd  d < q*|S )NERRORr   )r   r@   z
gradients/:z	.gradient)	tf_loggerlevelsetLevelr	  rT   r   r   r
  r   r   r   r   r   ro   r}   r   )r   og_levelr  r   rp   weightr   r   r   r   r/    s    

zWandbCallback._log_gradientsc                 C   s8  d\}}}| j r| j d | j d }}| j|}nI| jrc| js'td d S t| jD ]6}t| j\}}| j|}|d u rH|||}}}q,t	j
||ddt	j
||ddt	j
||dd}}}q,| jdv rw| jdkrwtj|||| jdS | jdv r| jd	krtj|||| j| jd
S td| j d| j  d S )N)NNNr   r  zdwhen using a generator for validation data with dataframes, you must pass validation_steps. skippingrF  )r!  r"  rb  )rN  rO  y_predr   r#  )rN  rO  r  r   r   z&unknown dataframe type for input_type=z and output_type=)r=   r   r  r8   r   r   r   rL  r!   rt   rb   r   r   image_categorizer_dataframer   image_segmentation_dataframer   )r   rN  rO  r  rP  rQ  rR  by_predr   r   r   _log_dataframe  sH   



zWandbCallback._log_dataframec                 C   s   t jjrd S | jdkr%td|dd| j d| jdd| jdd| j 
 z| j	r5| j
j| jd	d
 W d S | j
j| jd	d
 W d S  ttttfya } zt d t| W Y d }~d S d }~ww )Nr   r'  r(  r)  r*  r+  r,  z, saving model to T)	overwritezfCan't save model in the h5py format. The model will be saved as as an W&B Artifact in the 'tf' format.)r   r3   disabledr   r   r   r   r1  r   r   r   save_weightsr   rW   RuntimeError	TypeErrorrX   rY   rZ   r[   )r   r&  r  r   r   r   r3    s&   
&zWandbCallback._save_modelc                 C   s   t jjrd S | jj| jd d ddd t jdt jj }t j	|dd}|
| jd d  t jj|dd	| gd
 t| jd d  d S )NTr   )r  save_formatzmodel-r   )typelatestepoch_)aliases)r   r3   r  r   r   r   r   make_artifact_name_safer}   Artifactadd_dirlog_artifactshutilrmtree)r   r&  r}   model_artifactr   r   r   r4    s   z%WandbCallback._save_model_as_artifactr   c           	         s   t | ds
tdt| jtjjjtjjj	fst
dddlm} d  fdd| jjD }t| j|}||\}}tjj }tjjjtjjj    }tjjjj|j|d	|d
}|jd d S )zCalculate FLOPS [GFLOPs] for a tf.keras.Model or tf.keras.Sequential model in inference mode.

        It uses tf.compat.v1.profiler under the hood.
        r   z0self.model must be set before using this method.z]Calculating FLOPS is only supported for `tf.keras.Model` and `tf.keras.Sequential` instances.r   )*convert_variables_to_constants_v2_as_graphr  c                    s*   g | ]}t  g|jd d  |jqS )r  N)r   
TensorSpecr   rg   )r   inprh  r   r   r   )  s    z+WandbCallback.get_flops.<locals>.<listcomp>scope)r:  run_metacmdoptionsg    eAr   )r   r   r   r   r   r   r
   r  
Sequentialr^   r   0tensorflow.python.framework.convert_to_constantsr  r  r   get_concrete_functioncompatv1RunMetadataprofilerProfileOptionBuilderfloat_operationwith_empty_outputbuildprofiler:  total_float_ops)	r   r  r  
real_modelfrozen_funcrP  r  optsflopsr   rh  r   rM    s4   





zWandbCallback.get_flops)r   r   r   FFFTNNNr   NNNFNNNr   TNNNTr   F)Tr0   )r   )&r   r   r   r   r   r  r  r  r  r  r   r  r5  r7  r   r?  r@  rB  rC  rD  rE  rS  rT  rU  rV  rW  rX  rc  rf  r0  r.  r/  r  r3  r4  r   rM  r   r   r   r   r   r7   #  sz    b
 


7

	

	




6



"
u/r7   )0r   loggingr   r   r  sys	itertoolsr   r   rt   
tensorflowr   tensorflow.keras.backendr
   backendr1   r   (wandb.sdk.integration_utils.data_loggingr   wandb.sdk.lib.deprecater   r   r   r   r   boolr   modules	getLoggerr   rZ   r   r(   rf   rj   rs   rm   rn   rl   
get_loggerr  r   _custom_optimizer_parent_classr   r@   Callbackr   r7   r   r   r   r   <module>   sF    



y