a
    Sicz                     @   s   d Z ddlZddlm  mZ ddlmZ ddlm	Z
 ddlmZ ddlmZ ddlmZ ddlmZ G d	d
 d
ZG dd deZG dd deZdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )zUtilities for `Model.compile`.    N)losses)metrics)
saving_lib)generic_utils)losses_utils)tf_utilsc                   @   sB   e Zd ZdZdddZdd Zdd Zd	d
 Zdd Zdd Z	dS )	ContainerzBase Container class.Nc                 C   s
   || _ d S N)_output_names)selfoutput_names r   V/var/www/html/django/DPS/env/lib/python3.9/site-packages/keras/engine/compile_utils.py__init__"   s    zContainer.__init__c                 C   s   | j d u rt|| _ d S r	   )r
   create_pseudo_output_namesr   y_predr   r   r   build%   s    
zContainer.buildc                    sJ   t || j  t|  tj sFtj|rFtj fdd|  S )a  Convenience method to conform `struct` to `outputs` structure.

        Mappings performed:

        (1) Map a dict to a list of outputs, using the output names.
        (2) Fill missing keys in a dict w/ `None`s.
        (3) Map a single item to all outputs.

        Args:
          outputs: Model predictions.
          struct: Arbitrary nested structure (e.g. of labels, sample_weights,
            losses, or metrics).

        Returns:
          Mapping of `struct` to `outputs` structure.
        c                    s    S r	   r   _structr   r   <lambda>@       z/Container._conform_to_outputs.<locals>.<lambda>)map_to_output_namesr
   map_missing_dict_keystfnest	is_nestedmap_structure)r   outputsr   r   r   r   _conform_to_outputs+   s
    
zContainer._conform_to_outputsc                    sH    sS ttj|dkfdd tj fdd|S )a  Determines if losses / metrics should be applied to all outputs.

        NOTE: This method should only be called for Metrics / Losses, not for
        y_true / sample_weight.

        Args:
          outputs: Model predictions.
          objects: Arbitrary nested structure (e.g. of losses or metrics)

        Returns:
          Arbitrary nested structure of objects, maybe copied to each output.

        Applies a Loss / Metric to all outputs.
           c                      s   rt jj S  S r	   )r   r   r   _copy_objectr   )objectsr   should_copy_objectsr   r   _broadcast_fnZ   s    z<Container._maybe_broadcast_to_outputs.<locals>._broadcast_fnc                    s     S r	   r   r   )r&   r   r   r   _   r   z7Container._maybe_broadcast_to_outputs.<locals>.<lambda>)_should_broadcastlenr   r   flattenr   )r   r    r$   r   )r&   r$   r   r%   r   _maybe_broadcast_to_outputsC   s
    
z%Container._maybe_broadcast_to_outputsc                 C   s   t d S r	   NotImplementedError)r   r$   r   r   r   r'   a   s    zContainer._should_broadcastc                 C   s   t d S r	   r+   r   objr   r   r   r#   d   s    zContainer._copy_object)N)
__name__
__module____qualname____doc__r   r   r!   r*   r'   r#   r   r   r   r   r      s   
r   c                       s   e Zd ZdZd fdd	Zdd Zedd Zed	d
 Z	 fddZ
edd Zdd ZdddZdd Zdd Zdd Zdd Z  ZS )LossesContainera  A container class for losses passed to `Model.compile()`.

    Args:
      losses: Struct of loss function(s). See `Model.compile()` doc for more
        information.
      loss_weights: Weights of the losses contributions of different model
        outputs. See `Model.compile()` doc for more information.
      output_names: List of string. Per-output metric names.
      total_loss_mean: A `keras.metrics.Mean` instance that is used to track the
        mean of all losses (including compiled and regularization losses).
    Nc                    sL   t t| j|d || _|| _|| _|| _d | _|p>tj	dd| _
d| _d S )Nr   lossnameF)superr3   r   _user_losses_user_loss_weights_losses_loss_weights_per_output_metricsmetrics_modMean_total_loss_mean_built)r   r   loss_weightsr   total_loss_mean	__class__r   r   r   u   s    zLossesContainer.__init__c                 C   s.   t j| j| _dd | jD t| jdS )Nc                 S   s   g | ]}|d urt |qS r	   )r   serialize_keras_object).0r.   r   r   r   
<listcomp>   s   z.LossesContainer.get_config.<locals>.<listcomp>)r   rC   )r   r   r)   r;   r   rF   r@   r   r   r   r   
get_config   s    zLossesContainer.get_configc                 C   sP   i }|  D ]4\}}t|tr2dd |D ||< qt|||< q| f i |S )z:Returns the `LossesContainer` instance given the `config`.c                 S   s   g | ]}t |qS r   )r   deserialize_keras_object)rG   itemr   r   r   rH      s   z/LossesContainer.from_config.<locals>.<listcomp>)items
isinstancelistr   rK   )clsconfigZdeserialized_configkeyvaluer   r   r   from_config   s    

zLossesContainer.from_configc                 C   s.   | j s
g S dd tj| jD }| jg| S )zPer-output loss metrics.c                 S   s   g | ]}|d ur|qS r	   r   )rG   
metric_objr   r   r   rH      s   z+LossesContainer.metrics.<locals>.<listcomp>)rA   r   r   r)   r=   r@   )r   per_output_metricsr   r   r   r      s    zLossesContainer.metricsc                    s   t t| | | || j| _| || j| _tj| j	| j| _tj
| j| _| || j| _| || j| _tj
| j| _|   d| _dS )zOne-time setup of loss objects.TN)r8   r3   r   r*   r;   r!   r   r   r   _get_loss_objectr)   r<   _create_metricsrA   r   rD   r   r   r      s     zLossesContainer.buildc                 C   s   | j S r	   rA   rI   r   r   r   built   s    zLossesContainer.builtc                 C   sf   t | jdkrdg| _nJg | _t| j| jD ]4\}}|du rJ| jd q,| jt|d  q,dS )zBCreates per-output loss metrics, but only for multi-output Models.r"   N_loss)r(   r
   r=   zipr;   appendr>   r?   )r   loss_objoutput_namer   r   r   rX      s    
zLossesContainer._create_metricsc                 C   s  |  ||}|  ||}| js(| | tj|}tj|}tj|}g }g }d}|||| j| j| jf}t	| D ]\}	}
}}}}|	du sv|du rqvt
|	|
|\}	}
}t|
|t|
}||	|
|d}|}|jtjjkr|tj j9 }|du rt|	r|	 }nt|	d }|dur6|j||d |durP||9 }||9 }|jtjjksp|jtjjkrzt|}|| || qv|rt|}t|}|| |t| |rt|}t|}| jj||d t|}t|}|S dS dS )a  Computes the overall loss.

        Args:
          y_true: An arbitrary structure of Tensors representing the ground
            truth.
          y_pred: An arbitrary structure of Tensors representing a Model's
            outputs.
          sample_weight: An arbitrary structure of Tensors representing the
            per-sample loss weights. If one Tensor is passed, it is used for all
            losses. If multiple Tensors are passed, the structure should match
            `y_pred`.
          regularization_losses: Additional losses to be added to the total
            loss.

        Returns:
          The total loss as a `tf.Tensor`, or `None` if no loss results.
        Nsample_weightr   ) r!   rA   r   r   r   r)   r;   r<   r=   r\   match_dtype_and_rankr   
apply_maskget_mask	reductionReductionV2SUM
distributeget_strategynum_replicas_in_syncr   	is_raggednrowsshapeupdate_stateSUM_OVER_BATCH_SIZEAUTOscale_loss_for_distributionr]   cast_losses_to_common_dtypeadd_nr@   )r   y_truer   ra   regularization_lossesloss_valuesZtotal_loss_mean_values	batch_dimzip_argsy_ty_pswr^   loss_weightrU   
loss_valueZtotal_loss_mean_valuereg_lossZtotal_total_loss_mean_value
total_lossr   r   r   __call__   s    











zLossesContainer.__call__c                 C   s>   | j s
dS | jgtj| j }|D ]}|dur$|  q$dS )z!Resets the state of loss metrics.N)rA   r@   r   r   r)   r=   reset_stater   r   rU   r   r   r   r   G  s    zLossesContainer.reset_statec                 C   sX   |du rdS t |}t|t jsNt|}|du r@td| t j||d}d|_|S )a  Returns a `Loss` object.

        Converts the user-supplied loss to a `Loss` object. Also allows
        `SUM_OVER_BATCH_SIZE` reduction to be used for this loss.

        Args:
          loss: A string, function, or `Loss` object.

        Returns:
          A `Loss` object.
        Nz%Loss should be a callable, received: r6   T)
losses_modgetrN   Lossget_custom_object_name
ValueErrorLossFunctionWrapper_allow_sum_over_batch_size)r   r5   	loss_namer   r   r   rW   R  s    
z LossesContainer._get_loss_objectc                 C   s   t j| S r	   r   r   r   r-   r   r   r   r'   j  s    z!LossesContainer._should_broadcastc                 C   s   |S r	   r   r-   r   r   r   r#   m  s    zLossesContainer._copy_object)NNN)NN)r/   r0   r1   r2   r   rJ   classmethodrT   propertyr   r   rZ   rX   r   r   rW   r'   r#   __classcell__r   r   rD   r   r3   h   s$    


 
or3   c                       s   e Zd ZdZd" fdd	Zdd Zedd	 Zed
d Zedd Z	 fddZ
edd Zdd Zdd Zd#ddZdd Zdd Zdd Zdd Zd d! Z  ZS )$MetricsContainerz8A container class for metrics passed to `Model.compile`.NFc                    sF   t t| j|d | || || _|| _|| _|| _d| _|| _	dS )a  Initializes a container for metrics.

        Arguments:
          metrics: see the `metrics` argument from `tf.keras.Model.compile`.
          weighted_metrics: see the `weighted_metrics` argument from
            `tf.keras.Model.compile`.
          output_names: A list of strings of names of outputs for the model.
          from_serialized: Whether the model being compiled is from a serialized
            model.  Used to avoid redundantly applying pre-processing renaming
            steps.
        r4   FN)
r8   r   r   _check_duplicated_metrics_user_metrics_user_weighted_metrics_metrics_weighted_metricsrA   _from_serialized)r   r   weighted_metricsr   from_serializedrD   r   r   r   t  s    zMetricsContainer.__init__c                 C   sh   t  }g }tj|tj| D ].}t|tjs4q"||v rF|| || q"|rdt	d| dS )a/  Check and raise error when user provided metrics has any duplications.

        Note that metrics are stateful container, a shared metric instance
        between model.metric and model.weighted_metric will make the same
        intance to be udpated twice, and report wrong value.

        Args:
          metrics: User provided metrics list.
          weighted_metrics: User provided weighted metrics list.

        Raises:
          ValueError, when duplicated metrics instance discovered in user
            provided metrics and weighted metrics.
        zFound duplicated metrics object in the user provided metrics and weighted metrics. This will cause the same metric object to be updated multiple times, and report wrong results. 
Duplicated items: N)
setr   r   r)   rN   r>   Metricr]   addr   )r   r   r   seenZ
duplicatedxr   r   r   r     s    
z*MetricsContainer._check_duplicated_metricsc                 C   s   | j s
g S | jS )zAll metrics in this container.)rA   _metrics_in_orderrI   r   r   r   r     s    zMetricsContainer.metricsc                 C   s   | j s
dS tj| jS )zAMetrics in the container that should not be passed sample_weight.N)rA   r   r   r)   r   rI   r   r   r   unweighted_metrics  s    z#MetricsContainer.unweighted_metricsc                 C   s   | j s
dS tj| jS )z@Metrics in this container that should be passed `sample_weight`.N)rA   r   r   r)   r   rI   r   r   r   r     s    z!MetricsContainer.weighted_metricsc                    s  t t| | | || j| _| || j| _| || j| _| || j| _tjj	
|}tjj	
|}tjj	
| j| _tjj	
| j| _tjj	|| j| j||| _tjj	|| j| j||| _tjj	j|| jdd| _tjj	j|| jdd| _| js|   |   d| _dS )z!One-time setup of metric objects.F)check_typesTN)r8   r   r   r*   r   r!   r   r   __internal__r   list_to_tuplemap_structure_up_to_get_metric_objectsflatten_up_tor   _set_metric_names_create_ordered_metricsrA   )r   r   rt   rD   r   r   r     sF    zMetricsContainer.buildc                 C   s   | j S r	   rY   rI   r   r   r   rZ     s    zMetricsContainer.builtc           	      C   s  t  }t| jdk}| j| j| jf}t| D ]\}}}|D ]J}|du rHq:|r\|d |j |_|j|v rxtd|j d||j q:|D ]}|du rq|r|d |j |v r|d |j |_q|d |j |_n|j|v rd|j |_|j|v rtd|j d	||j qq,dS )
zSets unique metric names.r"   Nr   z&Found two metrics with the same name: z?. All the metrics added to the model need to have unique names.
_weighted_	weighted_z/Found two weighted metrics with the same name: z>.All the metrics added to the model need to have unique names.)	r   r(   r
   r   r   r\   _namer   r   )	r   metric_namesis_multi_outputrx   r_   output_metricsweighted_output_metricsmwmr   r   r   r     s@    

z"MetricsContainer._set_metric_namesc                 C   sn   g | _ t| j| jD ]T\}}tj|D ]}|dur(| j | q(tj|D ]}|durN| j | qNqdS )z@Cache the flat order needed when return metrics, for backcompat.N)r   r\   r   r   r   r   r)   r]   )r   r   output_weighted_metricsr   r   r   r   r   r   .  s    z(MetricsContainer._create_ordered_metricsc                 C   s.  |  ||}|  ||}| js*| || tj|}|durJtj|ng }tj|}|||| j| jf}t| D ]\}}}}}	|du stt	dd |D rt	dd |	D rqtt
|||\}}}t|}
t|||
}|D ]}|du rq|j|||
d q|	D ]$}|du rq|j|||d qqtdS )z(Updates the state of per-output metrics.Nc                 s   s   | ]}|d u V  qd S r	   r   rG   r   r   r   r   	<genexpr>Q  r   z0MetricsContainer.update_state.<locals>.<genexpr>c                 s   s   | ]}|d u V  qd S r	   r   )rG   r   r   r   r   r   R  r   r`   )r!   rA   r   r   r   r)   r   r   r\   allrb   r   rd   rc   rn   )r   rt   r   ra   rx   ry   rz   r{   metric_objsweighted_metric_objsmaskrU   weighted_metric_objr   r   r   rn   ;  s>    

zMetricsContainer.update_statec                 C   sL   | j r| j}ntj| jtj| j }|D ]}t|tj	r.|
  q.dS )z4Resets the state of all `Metric`s in this container.N)rA   r   r   r   r)   r   r   rN   r>   r   r   r   r   r   r   r   d  s    zMetricsContainer.reset_statec                    s"   t j|} fdd|D S )z2Convert user-supplied metrics to `Metric` objects.c                    s   g | ]}  |qS r   )_get_metric_objectr   r   rz   ry   r   r   rH   w  r   z8MetricsContainer._get_metric_objects.<locals>.<listcomp>)r   r   r)   )r   r   ry   rz   r   r   r   r   t  s    z$MetricsContainer._get_metric_objectsc                 C   s0  |du rdS t | dvr(t|}nt|j }t|j }|j d }|j d }|dk}	||k p~|dko~|dk}
t | dv r|	rtj}q|
rtj}qtj	}n|	rtj
}n|
rtj}ntj}t|tjrd|_t|tjs,t|t r|}n t|}|du rtd| tj||d}|S )	zConverts user-supplied metric to a `Metric` object.

        Args:
          metric: A string, function, or `Metric` object.
          y_t: Sample of label.
          y_p: Sample of output.

        Returns:
          A `Metric` object.
        N)accuracyacccrossentropycer"   )r   r   Tz'Metric should be a callable, received: r6   )strlowerr>   r   r(   rm   as_listbinary_accuracysparse_categorical_accuracycategorical_accuracybinary_crossentropysparse_categorical_crossentropycategorical_crossentropyrN   r   r   r   r   r   r   MeanMetricWrapper)r   metricry   rz   rU   y_t_ranky_p_ranky_t_last_dimy_p_last_dim	is_binaryis_sparse_categoricalmetric_namer   r   r   r   y  sH    

z#MetricsContainer._get_metric_objectc                 C   s2   t j|sdS t|ttfo0tdd |D  S )NTc                 s   s   | ]}t j|V  qd S r	   r   )rG   or   r   r   r     s   z5MetricsContainer._should_broadcast.<locals>.<genexpr>)r   r   r   rN   rO   tupleanyr-   r   r   r   r'     s
    z"MetricsContainer._should_broadcastc                 C   s    t |tjr|j| S |S r	   )rN   r>   r   rE   rT   rJ   r-   r   r   r   r#     s    zMetricsContainer._copy_object)NNNF)N)r/   r0   r1   r2   r   r   r   r   r   r   r   rZ   r   r   rn   r   r   r   r'   r#   r   r   r   rD   r   r   q  s0       #


3
,
)?	r   c                 C   s   t | ddS )z2Create pseudo output names for a subclassed Model.output_prefix_create_pseudo_names)r    r   r   r   r     s    r   c                 C   s   t | ddS )z1Create pseudo input names for a subclassed Model.input_r   r   )inputsr   r   r   create_pseudo_input_names  s    r   c                 C   s|   dd }t tjj| }tj||}g }|D ]F}|sB|d }n*ddd |D }t|d trl|| }|	| q0|S )aC  Creates pseudo {input | output} names for subclassed Models.

    Warning: this function should only be used to define default
    names for `Metics` and `SavedModel`. No other use cases should
    rely on a `Model`'s input or output names.

    Example with dict:

    `{'a': [x1, x2], 'b': x3}` becomes:
    `['a_1', 'a_2', 'b']`

    Example with list:

    `[x, y]` becomes:
    `['output_1', 'output_2']`

    Args:
      tensors: `Model`'s outputs or inputs.
      prefix: 'output_' for outputs, 'input_' for inputs.

    Returns:
      Flattened list of pseudo names.
    c                 S   s   t | tr| d S | S )Nr"   )rN   int)eler   r   r   	one_index  s    
z'_create_pseudo_names.<locals>.one_index1r   c                 s   s   | ]}t |V  qd S r	   )r   )rG   pr   r   r   r     r   z'_create_pseudo_names.<locals>.<genexpr>r   )
rO   r   r   r   yield_flat_pathsr   joinrN   r   r]   )tensorsr   r   
flat_pathsnamespathr7   r   r   r   r     s    
r   c                    s   t j|  }| o4t| ttfo4tdd | D  }|s>|rt tr|pRt| }t		   fdd|D } rt
d   d| d  dt|d	kr|d
 S |S  S dS )aA  Maps a dict to a list using `output_names` as keys.

    This is a convenience feature only. When a `Model`'s outputs
    are a list, you can specify per-output losses and metrics as
    a dict, where the keys are the output names. If you specify
    per-output losses and metrics via the same structure as the
    `Model`'s outputs (recommended), no mapping is performed.

    For the Functional API, the output names are the names of the
    last layer of each output. For the Subclass API, the output names
    are determined by `create_pseudo_output_names` (For example:
    `['output_1', 'output_2']` for a list of outputs).

    This mapping preserves backwards compatibility for `compile` and
    `fit`.

    Args:
      y_pred: Sample outputs of the Model, to determine if this convenience
        feature should be applied (`struct` is returned unmodified if `y_pred`
        isn't a flat list).
      output_names: List. The names of the outputs of the Model.
      struct: The structure to map.

    Returns:
      `struct` mapped to a list in same order as `output_names`.
    c                 s   s   | ]}t j|V  qd S r	   r   )rG   rz   r   r   r   r     r   z&map_to_output_names.<locals>.<genexpr>c                    s   g | ]}  |d qS r	   )pop)rG   r7   r   r   r   rH   #  r   z'map_to_output_names.<locals>.<listcomp>zOFound unexpected losses or metrics that do not correspond to any Model output: z. Valid mode output names: z. Received struct is: .r"   r   N)r   r   r   rN   rO   r   r   dictr   copyr   keysr(   )r   r   r   single_outputoutputs_are_flat_list
new_structr   r   r   r     s0    
r   c                 C   sD   t | trt |ts|S t|}|  D ]}||vr*d||< q*|S )z@Replaces missing dict keys in `struct` with `None` placeholders.N)rN   r   r   r   )r   r   kr   r   r   r   2  s    

r   c                 C   s   | j jdkr&|j jdkr&tj| dd} |durT|j jdkrT|j jdkrTtj|dd}| jjrd|jjst| jjr|jjrt| |j} |durt||j}| ||fS )z$Match dtype and rank of predictions.r"      r   )axisN)rm   rankr   expand_dimsdtypeis_floating
is_integercast)ry   rz   r{   r   r   r   rb   =  s    rb   c                 C   s@   t | dr| jS t | dr | jS t | dr8t| jjS dS dS )zReturns the name to use for a custom loss or metric callable.

    Args:
      obj: Custom loss of metric callable

    Returns:
      Name to use, or `None` if the object was not recognized.
    r7   r/   rE   N)hasattrr7   r/   r   to_snake_caserE   )r.   r   r   r   r   R  s    	


r   )r2   r   tensorflow.compat.v2compatv2r   kerasr   r   r   r>   keras.saving.experimentalr   keras.utilsr   r   r   r   r3   r   r   r   r   r   r   rb   r   r   r   r   r   <module>   s,   I    X-4