o
    xiK                     @  s   d dl mZ d dlZd dlmZ d dlmZmZmZ d dl	Z	er&d dl
mZ ejjdko1ejjdkZG dd	 d	Zd0ddZd1ddZd2ddZ		d3d4ddZ		 	!d5d6d)d*Z		 	+d7d8d.d/ZdS )9    )annotationsN)Sequence)TYPE_CHECKINGAnyCallable)_TableIndex      c                   @  s   e Zd ZU dZded< ded< ded< ded	< d
ed< ded< 										d2d3d"d#Zd4d&d'Z	(	)	*	d5d6d0d1ZdS )7ValidationDataLoggera0  Logs validation data as a wandb.Table.

    ValidationDataLogger is intended to be used inside of library integrations
    in order to facilitate the process of optionally building a validation dataset
    and logging periodic predictions against such validation data using WandB best
    practices.
    Sequence | dict[str, Sequence]validation_inputs%Sequence | dict[str, Sequence] | Nonevalidation_targetszlist[_TableIndex]validation_indexesCallable | Noneprediction_row_processorwandb.Table | Noneclass_labels_tableboolinfer_missing_processorsNinputtargetwb_validation_datavalidation_datasetTinputstargetsindexeslist[_TableIndex] | Nonevalidation_row_processorinput_col_namestrtarget_col_name
table_nameartifact_typeclass_labelslist[str] | NonereturnNonec                 C  sv  t |
trt|
dkrtjdgdd |
D d}nd}|du r|dus%J tjg g d}t |tr?|D ]
}||||  q3n||| t |trX|D ]
}||||  qLn||| |du r||r|t|}t|}|dur||dur|t|||||}|dur|	| t
||	}||d tjrtj| | }nd}|| _|| _|| _|| _|| _|| _|| _|| _dS )a
  Initialize a new ValidationDataLogger.

        Args:
            inputs: A list of input vectors or dictionary of lists of input vectors
                (used if the model has multiple named inputs)
            targets: A list of target vectors or dictionary of lists of target vectors
                (used if the model has multiple named targets/putputs). Defaults to `None`.
                `targets` and `indexes` cannot both be `None`.
            indexes: An ordered list of `wandb.data_types._TableIndex` mapping the
                input items to their source table. This is most commonly retrieved by using
                `indexes = my_data_table.get_index()`. Defaults to `None`. `targets`
                and `indexes` cannot both be `None`.
            validation_row_processor: 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 `inputs` is a list, then `row["input"]` will be the input
                data for the row. Else, it will be keyed based on the name of the input slot
                (corresponding to `inputs`). If `targets` is a list, then
                `row["target"]` will be the target data for the row. Else, it will
                be keyed based on `targets`. 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. If `None`, we will try to guess the appropriate processor.
                Ignored if `log_evaluation` is `False` or `val_keys` are present. Defaults to `None`.
            prediction_row_processor: Same as validation_row_processor, but applied to the
                model's output. `row["output"]` will contain the results of the model output.
                Defaults to `None`.
            input_col_name: The name to use for the input column.
                Defaults to `"input"`.
            target_col_name: The name to use for the target column.
                Defaults to `"target"`.
            table_name: The name to use for the validation table.
                Defaults to `"wb_validation_data"`.
            artifact_type: The artifact type to use for the validation data.
                Defaults to `"validation_dataset"`.
            class_labels: Optional list of labels to use in the inferred
                processors. If the model's `target` or `output` is inferred to be a class,
                we will attempt to map the class to these labels. Defaults to `None`.
            infer_missing_processors: Determines if processors are inferred if
                they are missing. Defaults to True.
        r   labelc                 S  s   g | ]}|gqS  r)   ).0r(   r)   r)   \/home/ubuntu/.local/lib/python3.10/site-packages/wandb/sdk/integration_utils/data_logging.py
<listcomp>\   s    z1ValidationDataLogger.__init__.<locals>.<listcomp>columnsdataNvalidation_data)
isinstancelistlenwandbTabledict
add_column_make_example_infer_validation_row_processoradd_computed_columnsArtifactaddrunuse_artifact	get_indexr   r   r   r   r   r   local_validation_artifactr   )selfr   r   r   r   r   r   r!   r"   r#   r$   r   r   local_validation_tablecol_nameexample_inputexample_targetr@   r)   r)   r+   __init__#   sZ   7




zValidationDataLogger.__init__
predict_fnr   c                 C  s
   || j S )aa  Produce predictions by passing `validation_inputs` to `predict_fn`.

        Args:
            predict_fn (Callable): Any function which can accept `validation_inputs` and produce
                a list of vectors or dictionary of lists of vectors

        Returns:
            (Sequence | Dict[str, Sequence]): The returned value of predict_fn
        )r   )rA   rG   r)   r)   r+   make_predictions   s   

z%ValidationDataLogger.make_predictionsoutputval_rowvalidation_predictionspredictionsprediction_col_nameval_ndx_col_namecommitwandb.data_types.Tablec           
      C  s   t jg g d}t|tr|D ]
}||||  qn||| ||| j | jdu rK| jrKt|}t| j	}	|durK|	durKt
||	| j| j|| _| jdurV|| j t j||i|d |S )a  Log a set of predictions.

        Intended usage:

        vl.log_predictions(vl.make_predictions(self.model.predict))

        Args:
            predictions (Sequence | Dict[str, Sequence]): A list of prediction vectors or dictionary
                of lists of prediction vectors
            prediction_col_name (str, optional): the name of the prediction column. Defaults to "output".
            val_ndx_col_name (str, optional): The name of the column linking prediction table
                to the validation ata table. Defaults to "val_row".
            table_name (str, optional): name of the prediction table. Defaults to "validation_predictions".
            commit (bool, optional): determines if commit should be called on the logged data. Defaults to False.
        r-   N)rO   )r4   r5   r1   r6   r7   r   r   r   r8   r   _infer_prediction_row_processorr   r   r:   log)
rA   rL   rM   rN   r"   rO   
pred_tablerC   example_predictionrD   r)   r)   r+   log_predictions   s,   


z$ValidationDataLogger.log_predictions)
NNNNr   r   r   r   NT)r   r   r   r   r   r   r   r   r   r   r   r    r!   r    r"   r    r#   r    r$   r%   r   r   r&   r'   )rG   r   r&   r   )rI   rJ   rK   T)rL   r   rM   r    rN   r    r"   r    rO   r   r&   rP   )__name__
__module____qualname____doc____annotations__rF   rH   rU   r)   r)   r)   r+   r
      s2   
 
nr
   r/   r   r&   dict | Sequence | Any | Nonec                 C  sJ   t | tri }| D ]
}| | d ||< q	|S t| dr!| d }|S d}|S )z1Used to make an example input, target, or output.r   __len__N)r1   r6   hasattr)r/   examplekeyr)   r)   r+   r8      s   

r8   r^   Sequence | Anyc                 C  sB   g }t | tst| drt| }|g}|dkr|t| d 7 }|S )z)Get the shape of an object if applicable.r\   r   )r1   r    r]   r3   _get_example_shape)r^   shapelengthr)   r)   r+   ra      s   ra   	lambda_fnr   closure_kwargsc                   s   d fdd}|S )	zVCreate a closure around a lambda function by binding `closure_kwargs` to the function.argsr   kwargsr&   c                    s&   i }| | |   | i |S N)update)rf   rg   _kre   rd   r)   r+   closure   s   

z_bind.<locals>.closureN)rf   r   rg   r   r&   r   r)   )rd   re   rl   r)   rk   r+   _bind   s   rm   r   r   possible_base_exampleSequence | Any | Nonedict[str, Callable]c                   s*  t | i } durOtdkrOd t jkrOtjjddd d fdd	|d
< | }t|dkoAt|ddhk}|sMfdd	|d< |S tdkrd dkrt	| d t
spt| drt	|  d t
r dur~ fdd	|d< |S dd	 |d< |S tdkrtjjdddd dkrfdd	|d< fdd	|d< | }t|dkot|ddhk}|sǇfdd	|d< |S tdkrtr dur|durt |kr fdd	|d< |S dd	 |d< |S tdkrtrdd	 |d< |S tdkrtrd d	 |d!< |S )"zInfers a processor from a single example.

    Infers a processor from a single example with optional class_labels_table
    and base_example. Base example is useful for cases such as segmentation masks
    N   r   numpyz"Inferring processors require numpy)requiredr(   c                   s     |S rh   )	index_refargmaxndp)r   npr)   r+   <lambda>  s    z7_infer_single_example_keyed_processor.<locals>.<lambda>	max_class   c                   s    fddt d D S )Nc                   s   i | ]	} | | qS r)   r)   r*   i)class_namesrx   r)   r+   
<dictcomp>  s    zK_infer_single_example_keyed_processor.<locals>.<lambda>.<locals>.<dictcomp>r   rangerv   )r   rb   rx   r+   r{     s    
scoretolistc                   s(   |d t  jk r |d S |d S Nr   )r3   r/   rt   rv   r   r)   r+   r{   '  s   classc                 S  s   |d S r   r)   rv   r)   r)   r+   r{   ,  s    val
   c                   s    fddt d D S )Nc                   s.   g | ]}t  | d r |  n | qS )r   )r]   r   r~   r   r)   r+   r,   6  s     zK_infer_single_example_keyed_processor.<locals>.<lambda>.<locals>.<listcomp>r   r   rv   )rb   r   r+   r{   6  s   
 
nodec                   
     |S rh   )ru   rv   rz   r)   r+   r{   ;     
 ru   c                   r   rh   )argminrv   r   r)   r+   r{   @  r   r   c                   s   t j|d| ddidS )Nmasksr(   )	mask_datar$   )r   )r4   Image
get_columnrv   r   r)   r+   r{   H  s    imagec                 S  
   t |S rh   r4   r   rv   r)   r)   r+   r{   S  r   r   c                 S  r   rh   r   rv   r)   r)   r+   r{   V  r      c                 S  r   rh   )r4   Videorv   r)   r)   r+   r{   Y  r   video)ra   r3   r/   r4   util
get_moduler   uniquesetr1   intr]   r   CAN_INFER_IMAGE_AND_VIDEO)r^   r   rn   
processorsvalues
is_one_hotr)   )r   r   rz   rb   r+   %_infer_single_example_keyed_processor   sr   


B
5/
r   r   r   rD   dict | SequencerE   dict | Sequence | Anyr   r    r!   c           	        sB  i t  tr* D ]}t | }|D ]}tdd || |d| d| < qq	n}t }|D ]}tdd || |d| d| < q2t |trp|D ] }t|| |}|D ]}tdd || |d| d| < qYqNn)|}t||t  ts| nd}|D ]}t fdd|| |d| d| < qfd	d
}|S )z7Infers the composite processor for the validation data.c                 S     || || d S rh   r)   ndxrowkey_processorr_   r)   r)   r+   r{   l  
    z1_infer_validation_row_processor.<locals>.<lambda>r   r_   :c                 S  r   rh   r)   r   r)   r)   r+   r{   y  r   c                 S  r   rh   r)   r   r)   r)   r+   r{     r   Nc                   s$   || || t  ts| S d S rh   )r1   r6   r   rD   r   r)   r+   r{     s    c                       fddD S )Nc                      i | ]
}||  qS r)   r)   r*   r_   r   r   single_processorsr)   r+   r         zF_infer_validation_row_processor.<locals>.processor.<locals>.<dictcomp>r)   r   r   r   r   r+   	processor     z2_infer_validation_row_processor.<locals>.processorr1   r6   r   rm   )	rD   rE   r   r   r!   r_   key_processorsp_keyr   r)   rD   r   r   r+   r9   ^  s^   


r9   rI   rT   output_col_namec           	        s   i t | tr+| D ] }t| | |}|D ]}tdd || |d| d| < qq	n)|}t| |t  ts7 nd}|D ]}t fdd|| |d| d| < q<fdd}|S )	z>Infers the composite processor for the prediction output data.c                 S  r   rh   r)   r   r)   r)   r+   r{     r   z1_infer_prediction_row_processor.<locals>.<lambda>r   r   Nc                   s4   || || t  ts|  d S d S )NrJ   )r1   r6   get_rowgetr   r   r)   r+   r{     s    c                   r   )Nc                   r   r)   r)   r   r   r)   r+   r     r   zF_infer_prediction_row_processor.<locals>.processor.<locals>.<dictcomp>r)   r   r   r   r+   r     r   z2_infer_prediction_row_processor.<locals>.processorr   )	rT   rD   r   r   r   r_   r   r   r   r)   r   r+   rQ     s8   
rQ   )r/   r   r&   r[   )r^   r`   )rd   r   re   r   r&   r   )NN)r^   r`   r   r   rn   ro   r&   rp   )Nr   r   )rD   r   rE   r   r   r   r   r    r!   r    r&   r   )Nr   rI   )rT   r   rD   r   r   r   r   r    r   r    r&   r   )
__future__r   syscollections.abcr   typingr   r   r   r4   wandb.data_typesr   version_infomajorminorr   r
   r8   ra   rm   r   r9   rQ   r)   r)   r)   r+   <module>   s0    
=

kP