
    AVh                       d 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
 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 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 ddl	mZ ddlmZ ddlmZ ddlmZ dvdZd Z d Z!d Z"dwdZ#d Z$ edg       	 	 	 	 dxd!       Z% ed"g       	 	 	 	 dxd#       Z&	 	 dyd$Z'd% Z( ed&g        edd'      	 	 	 	 	 	 	 	 dzd(              Z) ed)g       	 	 	 	 dxd*       Z* ed+g       	 	 	 	 dxd,       Z+ ed-g       	 	 	 	 dxd.       Z, ed/g       	 	 	 	 dxd0       Z- ed1g       	 	 	 	 dxd2       Z. ed3g       	 	 	 	 dxd4       Z/ ed5g       	 	 	 	 dxd6       Z0 ed7g       	 	 	 	 dxd8       Z1	 	 	 d{d9Z2 ed:g       	 	 	 	 dxd;       Z3 ed<g       	 	 	 	 dxd=       Z4 ed>g       	 	 	 	 dxd?       Z5 ed@g       	 	 	 	 dxdA       Z6 edBg       	 	 	 	 dxdC       Z7 edDg       	 	 	 	 dxdE       Z8 edFg       	 	 	 	 dxdG       Z9 edHg       	 	 	 	 dxdI       Z: edJg       	 	 	 	 dxdK       Z; edLg       	 	 	 	 dxdM       Z< edNg       	 	 	 	 dxdO       Z=dydPZ>dQ Z?dwdRZ@	 	 	 d{dSZA	 	 	 	 dxdTZB	 	 dydUZC	 	 	 d{dVZD edWg       	 	 	 	 	 d|dX       ZE edYg       	 	 	 	 	 	 d}dZ       ZF ed[g       	 	 	 	 dxd\       ZG ed]g       	 	 	 	 dxd^       ZH ed_g       	 	 	 	 	 d~d`       ZIddaZJdb ZKdc ZL	 	 	 	 dxddZMde ZN edfg        eddg      	 	 	 	 dxdh              ZO edig       	 	 	 	 dxdj       ZP	 	 dydkZQ	 	 	 	 dxdlZR edmg       	 	 	 	 	 	 d}dn       ZS edog        eddp      	 	 	 	 	 d|dq              ZT edrg       	 	 	 	 	 d|ds       ZU edtg       	 	 	 	 	 d~du       ZVy)z$Implementation of tf.metrics module.    )distribute_lib)context)dtypes)ops)sparse_tensor)	array_ops)array_ops_stack)	check_ops)cond)confusion_matrix)math_ops)nn)sets)
sparse_ops)	state_ops)variable_scope)variable_v1)	variables)weights_broadcast_ops)
tf_logging)
deprecated)	tf_exportNc           	      
    t        j                   fddt        j                  j                  t        j                  j
                  g|t        j                  j                  t        j                  j                  |      S )ap  Create variable in `GraphKeys.(LOCAL|METRIC_VARIABLES)` collections.

  If running in a `DistributionStrategy` context, the variable will be
  "sync on read". This means:

  *   The returned object will be a container with separate variables
      per replica of the model.

  *   When writing to the variable, e.g. using `assign_add` in a metric
      update, the update will be applied to the variable local to the
      replica.

  *   To get a metric's result value, we need to sum the variable values
      across the replicas before computing the final answer. Furthermore,
      the final answer should be computed once instead of in every
      replica. Both of these are accomplished by running the computation
      of the final result value inside
      `distribute_lib.get_replica_context().merge_call(fn)`.
      Inside the `merge_call()`, ops are only added to the graph once
      and access to a sync on read variable in a computation returns
      the sum across all replicas.

  Args:
    shape: Shape of the created variable.
    dtype: Type of the created variable.
    validate_shape: (Optional) Whether shape validation is enabled for
      the created variable.
    name: (Optional) String name of the created variable.

  Returns:
    A (non-trainable) variable initialized to zero, or if inside a
    `DistributionStrategy` scope a sync on read variable container.
  c                  0    t        j                         S N)r   zeros)dtypeshapes   R/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/metrics_impl.py<lambda>z!metric_variable.<locals>.<lambda>L   s    iooeU+     F)	trainablecollectionsvalidate_shapesynchronizationaggregationname)r   
VariableV1r   	GraphKeysLOCAL_VARIABLESMETRIC_VARIABLESr   VariableSynchronizationON_READVariableAggregationSUM)r   r   r$   r'   s   ``  r   metric_variabler0   (   sc    F 
		+
--
'
')G)G $77??//33	
 	r!   c                 8  	
 t        j                  |       } |Ft        j                  ||       \  }} | j	                         j                  |j	                                | |dfS t        j                        j	                         }|j                  }|dk(  r| |fS | j	                         }|j                  }|B|@||z
  dk(  rt        j                  dg      n||z
  dk(  rt        j                  dg      nt        j                        }|t        j                  |       z
  fd	|$|j                  d   j                  d      sfd
nfd
	
fd}t        j                  t        j                  |d      fd	|      | |fS )
af  Squeeze or expand last dim if needed.

  Squeezes last dim of `predictions` or `labels` if their rank differs by 1
  (using confusion_matrix.remove_squeezable_dimensions).
  Squeezes or expands last dim of `weights` if its rank differs by 1 from the
  new rank of `predictions`.

  If `weights` is scalar, it is kept scalar.

  This will use static shape if available. Otherwise, it will add graph
  operations, which could result in a performance hit.

  Args:
    predictions: Predicted values, a `Tensor` of arbitrary dimensions.
    labels: Optional label `Tensor` whose dimensions match `predictions`.
    weights: Optional weight scalar or `Tensor` whose dimensions match
      `predictions`.

  Returns:
    Tuple of `predictions`, `labels` and `weights`. Each of them possibly has
    the last dimension squeezed, `weights` could be extended by one dimension.
  Nr      c                  f    t        j                   t        j                   d      fdfd      S )Nr3   c                  2    t        j                   dg      S Nr3   r   expand_dimsweightss   r   r    zN_remove_squeezable_dimensions.<locals>._maybe_expand_weights.<locals>.<lambda>   s    )''"6 r!   c                       S r    r9   s   r   r    zN_remove_squeezable_dimensions.<locals>._maybe_expand_weights.<locals>.<lambda>   s     r!   r   r   equal)	rank_diffr:   s   r   _maybe_expand_weightsz<_remove_squeezable_dimensions.<locals>._maybe_expand_weights   s)    YY
..B
'
6I Ir!   c                       S r   r<   r9   s   r   r    z/_remove_squeezable_dimensions.<locals>.<lambda>   s    g r!   c                  2    t        j                   dg      S r6   )r   squeezer9   s   r   r    z/_remove_squeezable_dimensions.<locals>.<lambda>   s    i&7&7"&F r!   c                  Z    t        j                   t        j                  d             S )Nr2   r=   )r@   maybe_squeeze_weightsr?   s   r   _maybe_adjust_weightsz<_remove_squeezable_dimensions.<locals>._maybe_adjust_weights   s(    YY
..A
&(=
! !r!   c                       S r   r<   r9   s   r   r    z/_remove_squeezable_dimensions.<locals>.<lambda>   s     r!   )r   convert_to_tensorr   remove_squeezable_dimensions	get_shapeassert_is_compatible_withndimsr   rC   r8   rankdimsis_compatible_withr   r   r>   )predictionslabelsr:   weights_shapeweights_rankpredictions_shapepredictions_rankweights_rank_tensorrF   r@   rE   r?   s     `      @@@r   _remove_squeezable_dimensionsrW   W   s   . %%k2+*GGFK55f6F6F6HI_$$!!'*'##%-$$,Q''!++-&,,")A&&!+!!'B40g	L	(A	-%%gt4g $..1#inn[&AAII 
	!#66q9-F! ii*A.G 
fg	%%r!   c           	          t        j                  dd |f      5 t        j                          t	         t        j
                        rnt        j                  t        j                  t        j                  |      t        j                   j                        dz          fd fd      cddd       S  j                         j                  }||j                         j                  }|g||k(  r cddd       S ||dz   k(  r!t        j                   d      cddd       S t!        d j                          d	|j                          d
      t        j                  t        j                  t        j                  |      t        j                         dz          fd fd      cddd       S # 1 sw Y   yxY w)a  If necessary, expand `labels` along last dimension to match `predictions`.

  Args:
    labels: `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN]. The latter implies
      num_labels=1, in which case the result is an expanded `labels` with shape
      [D1, ... DN, 1].
    predictions: `Tensor` with shape [D1, ... DN, num_classes].

  Returns:
    `labels` with the same rank as `predictions`.

  Raises:
    ValueError: if `labels` has invalid shape.
  Nexpand_labelsr2   c                  t    t        j                   t        j                   j                  dfd            S )N)r2   r   r   r'   )r   sparse_reshaper   concatdense_shaperQ   scopes   r   r    z&_maybe_expand_labels.<locals>.<lambda>   s3    *++$$f&8&8$%?C r!   c                       S r   r<   rQ   s   r   r    z&_maybe_expand_labels.<locals>.<lambda>   s    & r!   r3   r'   zUnexpected labels shape z for predictions shape zS. Predictions rank should be the same rank as labels rank or labels rank plus one .c                  4    t        j                   d      S )Nr3   rc   r7   r_   s   r   r    z&_maybe_expand_labels.<locals>.<lambda>   s    	%%fbu= r!   c                       S r   r<   rb   s   r   r    z&_maybe_expand_labels.<locals>.<lambda>   s    v r!   )r   
name_scoper   "convert_to_tensor_or_sparse_tensor
isinstanceSparseTensorr   r   r>   r   rM   sizer^   rJ   rL   r8   
ValueError)rQ   rP   labels_rankrU   r`   s   `   @r   _maybe_expand_labelsrm      s     ~~dOfk-BC !Ou==fEF &-445YY
..nn[)nnV//0146 !O !O  ""$**K$..066		%{*+!O !O, {Q.&&vr>/!O !O0 &v'7'7'9&: ; **,- .AAB 	B 99y~~k2 ~~f-1	3=~O=!O !O !Os   BF=:>F=F=+BF==Gc                     | j                         j                  d       |j                         j                  d       t        j                  | ||      S )a  Divides two values, returning 0 if the denominator is 0.

  Args:
    numerator: A scalar `float64` `Tensor`.
    denominator: A scalar `float64` `Tensor`.
    name: Name for the returned op.

  Returns:
    0 if `denominator` == 0, else `numerator` / `denominator`
  r2   rc   )rJ   with_rank_at_mostr   
div_no_nan)	numeratordenominatorr'   s      r   _safe_scalar_divrs      sG     ))!,++A.			Y$	??r!   c                    t        ||gt        j                  d      }t        j                  |t        j
                        }t        j                  | t        j
                        } t        j                  |t        j
                        }|j                         j                  dkD  rt        j                  |dg      }| j                         j                  dkD  rt        j                  | dg      } |4|j                         j                  dkD  rt        j                  |dg      }t        j                  | |||t        j                        }t        j                  ||      }||fS )a>  Calculate a streaming confusion matrix.

  Calculates a confusion matrix. For estimation over a stream of data,
  the function creates an  `update_op` operation.

  Args:
    labels: A `Tensor` of ground truth labels with shape [batch size] and of
      type `int32` or `int64`. The tensor will be flattened if its rank > 1.
    predictions: A `Tensor` of prediction results for semantic labels, whose
      shape is [batch size] and type `int32` or `int64`. The tensor will be
      flattened if its rank > 1.
    num_classes: The possible number of labels the prediction task can
      have. This value must be provided, since a confusion matrix of
      dimension = [num_classes, num_classes] will be allocated.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).

  Returns:
    total_cm: A `Tensor` representing the confusion matrix.
    update_op: An operation that increments the confusion matrix.
  total_confusion_matrixrc   r2   r3   )r:   r   )r0   r   float64r   castint64rJ   rL   r   reshaper   r   
assign_add)rQ   rP   num_classesr:   total_cm
current_cm	update_ops          r   _streaming_confusion_matrixr      s%   0 K &..7OQ( k6<<8+==.&k6<<8+ ""Q&##K"6K!vt,F 1 1 3 9 9A =".G  00k;v~~O*""8Z8)	9	r!   c                 \      fd}t        j                         j                  ||      S )z'Aggregate metric value across replicas.c                    t        | j                  d      r| j                  j                  (t        j                  d      5   | g| }ddd       n[| j                  j                  j                           | g| }| j                  j                  j                          n	 | g| }rt        j                         S # 1 sw Y   #xY w)z;Call `metric_value_fn` in the correct control flow context._outer_control_flow_contextN)hasattrextendedr   r   control_dependenciesEnterExitadd_to_collections)distributionametric_valuemetric_value_fnmetrics_collectionss      r   fnz&_aggregate_across_replicas.<locals>.fn  s    |$$&CD 
			:	:	B%%d+ 	;(::,	; 	; 	99??A&|8a899>>@ %\6A6l	0,?	; 	;s   
CC)args)r   get_replica_context
merge_call)r   r   r   r   s   ``  r   _aggregate_across_replicasr     s0    : 
	+	+	-	8	8t 
9 
 r!   zmetrics.mean)v1c                 :   t        j                         rt        d      t        j                  |d| |f      5  t	        j
                  | t        j                        } t        g t        j                  d      }t        g t        j                  d      }|8t	        j
                  t        j                  |       t        j                        }nut        | d|      \  } }}t        j                  t	        j
                  |t        j                        |       }t	        j                  | |      } t	        j                  |      }t!        j"                  |t	        j                  |             }	t%        j&                  | g      5  t!        j"                  ||      }
ddd       d }t)        ||||      }t	        j*                  |	t	        j,                  
d	      d
      }|rt%        j.                  ||       ||fcddd       S # 1 sw Y   kxY w# 1 sw Y   yxY w)a  Computes the (weighted) mean of the given values.

  The `mean` function creates two local variables, `total` and `count`
  that are used to compute the average of `values`. This average is ultimately
  returned as `mean` which is an idempotent operation that simply divides
  `total` by `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the `mean`.
  `update_op` increments `total` with the reduced sum of the product of `values`
  and `weights`, and it increments `count` with the reduced sum of `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    values: A `Tensor` of arbitrary dimensions.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `values`, and must be broadcastable to `values` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `values` dimension).
    metrics_collections: An optional list of collections that `mean`
      should be added to.
    updates_collections: An optional list of collections that `update_op`
      should be added to.
    name: An optional variable_scope name.

  Returns:
    mean: A `Tensor` representing the current mean, the value of `total` divided
      by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `mean_value`.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match `values`,
      or if either `metrics_collections` or `updates_collections` are not a list
      or tuple.
    RuntimeError: If eager execution is enabled.

  @compatibility(TF2)
  `tf.compat.v1.metrics.mean` is not compatible with eager
  execution or `tf.function`.
  Please use `tf.keras.metrics.Mean` instead for TF2 migration. After
  instantiating a `tf.keras.metrics.Mean` object, you can first call the
  `update_state()` method to record the new values, and then call the
  `result()` method to get the mean eagerly. You can also attach it to a
  Keras model with the `add_metric` method.  Please refer to the [migration
  guide](https://www.tensorflow.org/guide/migrate#new-style_metrics_and_losses)
  for more details.

  #### Structural Mapping to TF2

  Before:

  ```python
  mean, update_op = tf.compat.v1.metrics.mean(
    values=values,
    weights=weights,
    metrics_collections=metrics_collections,
    update_collections=update_collections,
    name=name)
  ```

  After:

  ```python
   m = tf.keras.metrics.Mean(
     name=name)

   m.update_state(
     values=values,
     sample_weight=weights)

   mean = m.result()
  ```

  #### How to Map Arguments

  | TF1 Arg Name          | TF2 Arg Name    | Note                       |
  | :-------------------- | :-------------- | :------------------------- |
  | `values`              | `values`        | In `update_state()` method |
  | `weights`             | `sample_weight` | In `update_state()` method |
  | `metrics_collections` | Not supported   | Metrics should be tracked  |
  :                       :                 : explicitly or with Keras   :
  :                       :                 : APIs, for example,         :
  :                       :                 : [add_metric][add_metric],  :
  :                       :                 : instead of via collections :
  | `updates_collections` | Not supported   | -                          |
  | `name`                | `name`          | In constructor             |

  [add_metric]:https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer#add_metric


  #### Before & After Usage Example

  Before:

  >>> g = tf.Graph()
  >>> with g.as_default():
  ...   values = [1, 2, 3]
  ...   mean, update_op = tf.compat.v1.metrics.mean(values)
  ...   global_init = tf.compat.v1.global_variables_initializer()
  ...   local_init = tf.compat.v1.local_variables_initializer()
  >>> sess = tf.compat.v1.Session(graph=g)
  >>> sess.run([global_init, local_init])
  >>> sess.run(update_op)
  >>> sess.run(mean)
  2.0


  After:

  >>> m = tf.keras.metrics.Mean()
  >>> m.update_state([1, 2, 3])
  >>> m.result().numpy()
  2.0

  ```python
  # Used within Keras model
  model.add_metric(tf.keras.metrics.Mean()(values))
  ```

  @end_compatibility
  zAtf.metrics.mean is not supported when eager execution is enabled.meantotalrc   countNrP   rQ   r:   c                 Z    t        j                  |t        j                  |d      d      S Nr   valuerc   r   rp   maximum_tcs      r   compute_meanzmean.<locals>.compute_mean  s$      H$4$4Q$:IIr!   r   r~   )r   executing_eagerlyRuntimeErrorr   r   rw   r   float32r0   r   rj   rW   r   broadcast_weightsmultiply
reduce_sumr   rz   r   r   r   rp   r   r   valuesr:   r   updates_collectionsr'   r   r   
num_valuesr   update_total_opupdate_count_opr   mean_tr~   s                 r   r   r   ;  s   @  
 % & & $$T6FG3DE ]]66>>2FBW=EBW=E==!7Hj8T7<fa%77
--
0&:g  1f&&w/j**5(2E2Ef2MNO		!	!6(	+ @!,,UJ?o@J (\5%9F##))/1=KQI 	0)<9? "@ @# s%   EHHA HH	
HHzmetrics.accuracyc                    t        j                         rt        d      t        || |      \  }} }|j	                         j                  | j	                                | j                  |j                  k7  r t        j                  || j                        }t        j                  t        j                  ||       t        j                        }t        |||||xs d      S )a  Calculates how often `predictions` matches `labels`.

  The `accuracy` function creates two local variables, `total` and
  `count` that are used to compute the frequency with which `predictions`
  matches `labels`. This frequency is ultimately returned as `accuracy`: an
  idempotent operation that simply divides `total` by `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the `accuracy`.
  Internally, an `is_correct` operation computes a `Tensor` with elements 1.0
  where the corresponding elements of `predictions` and `labels` match and 0.0
  otherwise. Then `update_op` increments `total` with the reduced sum of the
  product of `weights` and `is_correct`, and it increments `count` with the
  reduced sum of `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose shape matches
      `predictions`.
    predictions: The predicted values, a `Tensor` of any shape.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `accuracy` should
      be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    accuracy: A `Tensor` representing the accuracy, the value of `total` divided
      by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `accuracy`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.

  @compatibility(TF2)
  `tf.compat.v1.metrics.accuracy` is not compatible with eager
  execution or `tf.function`.
  Please use `tf.keras.metrics.Accuracy` instead for TF2 migration. After
  instantiating a `tf.keras.metrics.Accuracy` object, you can first call the
  `update_state()` method to record the prediction/labels, and then call the
  `result()` method to get the accuracy eagerly. You can also attach it to a
  Keras model when calling the `compile` method. Please refer to [this
  guide](https://www.tensorflow.org/guide/migrate#new-style_metrics_and_losses)
  for more details.

  #### Structural Mapping to Native TF2

  Before:

  ```python
  accuracy, update_op = tf.compat.v1.metrics.accuracy(
    labels=labels,
    predictions=predictions,
    weights=weights,
    metrics_collections=metrics_collections,
    update_collections=update_collections,
    name=name)
  ```

  After:

  ```python
   m = tf.keras.metrics.Accuracy(
     name=name,
     dtype=None)

   m.update_state(
   y_true=labels,
   y_pred=predictions,
   sample_weight=weights)

   accuracy = m.result()
  ```

  #### How to Map Arguments

  | TF1 Arg Name          | TF2 Arg Name    | Note                       |
  | :-------------------- | :-------------- | :------------------------- |
  | `label`               | `y_true`        | In `update_state()` method |
  | `predictions`         | `y_true`        | In `update_state()` method |
  | `weights`             | `sample_weight` | In `update_state()` method |
  | `metrics_collections` | Not supported   | Metrics should be tracked  |
  :                       :                 : explicitly or with Keras   :
  :                       :                 : APIs, for example,         :
  :                       :                 : [add_metric][add_metric],  :
  :                       :                 : instead of via collections :
  | `updates_collections` | Not supported   | -                          |
  | `name`                | `name`          | In constructor             |

  [add_metric]:https://www.tensorflow.org/api_docs/python/tf/keras/layers/Layer#add_metric


  #### Before & After Usage Example

  Before:

  >>> g = tf.Graph()
  >>> with g.as_default():
  ...   logits = [1, 2, 3]
  ...   labels = [0, 2, 3]
  ...   acc, acc_op = tf.compat.v1.metrics.accuracy(logits, labels)
  ...   global_init = tf.compat.v1.global_variables_initializer()
  ...   local_init = tf.compat.v1.local_variables_initializer()
  >>> sess = tf.compat.v1.Session(graph=g)
  >>> sess.run([global_init, local_init])
  >>> print(sess.run([acc, acc_op]))
  [0.0, 0.66667]


  After:

  >>> m = tf.keras.metrics.Accuracy()
  >>> m.update_state([1, 2, 3], [0, 2, 3])
  >>> m.result().numpy()
  0.66667

  ```python
  # Used within Keras model
  model.compile(optimizer='sgd',
                loss='mse',
                metrics=[tf.keras.metrics.Accuracy()])
  ```

  @end_compatibility
  zEtf.metrics.accuracy is not supported when eager execution is enabled.r   accuracy)r   r   r   rW   rJ   rK   r   r   rw   r>   r   r   r   )rQ   rP   r:   r   r   r'   
is_corrects          r   r   r     s    Z  
 / 0 0 "?fg"?+vw33F4D4D4FG\\[&&&--V\\:K}}nn[&)6>>;*	j'#68K j
" "r!   c           
      
   d}||}n|D ]  }||vst        d|        t        j                  t        j                  |t        j                  d|j                        d      t        j                  |t        j                  d|j                        d      g      5  t        t        j                  |t        j                        t        j                  | t        j                        |	      \  }} }ddd       t        |      }t        j                  |d
dg      }t        j                  t        j                  | t        j                        dd
g      }	|j!                         j#                         d   }
|
t        j$                  |      d   }
t        j&                  t        j(                  t        j*                  |      dg      t-        j.                  d|
g            }t        j0                  t        j&                  t        j2                  |      |dg      |      }d|v sd|v rt        j4                  |      }t        j&                  |	|dg      }d|v sd|v rt        j4                  |      }|t7        j8                  t        j                  |t        j                        |      }t        j&                  t        j                  |dd
g      |dg      }|j!                         j;                  |j!                                nd}i }i }d|v rt=        |gt        j                  d      }t        j                  t        j>                  ||      t        j                        }|||z  }tA        jB                  |t        jD                  |d            |d<   ||d<   d|v rt=        |gt        j                  d      }t        j                  t        j>                  |      t        j                        }|||z  }tA        jB                  |t        jD                  |d            |d<   ||d<   d|v rt=        |gt        j                  d      }t        j                  t        j>                        t        j                        }|||z  }tA        jB                  |t        jD                  |d            |d<   ||d<   d|v rt=        |gt        j                  d      }t        j                  t        j>                  |      t        j                        }|||z  }tA        jB                  |t        jD                  |d            |d<   ||d<   ||fS # 1 sw Y   oxY w)aN  Computes true_positives, false_negatives, true_negatives, false_positives.

  This function creates up to four local variables, `true_positives`,
  `true_negatives`, `false_positives` and `false_negatives`.
  `true_positive[i]` is defined as the total weight of values in `predictions`
  above `thresholds[i]` whose corresponding entry in `labels` is `True`.
  `false_negatives[i]` is defined as the total weight of values in `predictions`
  at most `thresholds[i]` whose corresponding entry in `labels` is `True`.
  `true_negatives[i]` is defined as the total weight of values in `predictions`
  at most `thresholds[i]` whose corresponding entry in `labels` is `False`.
  `false_positives[i]` is defined as the total weight of values in `predictions`
  above `thresholds[i]` whose corresponding entry in `labels` is `False`.

  For estimation of these metrics over a stream of data, for each metric the
  function respectively creates an `update_op` operation that updates the
  variable and returns its value.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` whose shape matches `predictions`. Will be cast to
      `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    includes: Tuple of keys to return, from 'tp', 'fn', 'tn', fp'. If `None`,
        default to all four.

  Returns:
    values: Dict of variables of shape `[len(thresholds)]`. Keys are from
        `includes`.
    update_ops: Dict of operations that increments the `values`. Keys are from
        `includes`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      `includes` contains invalid keys.
  )tpr   tnfpNzInvalid key:         r   zpredictions must be in [0, 1])message      ?r   r3   r2   r   r   r   r   r   true_positivesrc   false_negativestrue_negativesfalse_positives)#rk   r   r   r
   assert_greater_equalr   rw   r   assert_less_equalrW   r   r   boollenr   ry   rJ   as_listr   tiler8   constantr	   stackgreater	transposelogical_notr   r   rK   r0   logical_andr   rz   r   )rQ   rP   
thresholdsr:   includesall_includesincludenum_thresholdspredictions_2d	labels_2dnum_predictionsthresh_tiledpred_is_pospred_is_neglabel_is_poslabel_is_negweights_tiledr   
update_opstrue_pis_true_positivefalse_nis_false_negativetrue_nis_true_negativefalse_pis_false_positives                              r   _confusion_matrix_at_thresholdsr   }  s   ^ *,H 4		$=	2334 $$

--;#4#4
513 !!

--;#4#4
513	! 	  $AMM+v~~>}}V6;;7$ K z?. $$[2q':.mmF&++.B9) #,,.668;/ oon5a8OI..z:QC@Q013,
   nnY((8>1:MN+ hDH,&&{3K 	NA+>?,
hDH,''5L#55gv~~.=GNN'Ar7+na-@BM66!# M&*	X	&../?AF}}\;7I -' ++F,4,?,?0@!-EFJt F4L	X	&../@BG \;7I =( ++G,4,?,?0A1-FGJt F4L	X	&../?AF}}\;7I -' ++F,4,?,?0@!-EFJt F4L	X	&../@BG \;7I =( ++G,4,?,?0A1-FGJt F4L		S s   "AU''U1c                 "    d }t        |||       S )Nc                 8    | j                   j                  |      S r   )r   read_var)r   r   s     r   r    z%_aggregate_variable.<locals>.<lambda>!  s    ,"7"7"@"@"G r!   )r   )vr#   fs      r   _aggregate_variabler      s    G!	#KA	66r!   zmetrics.auczzThe value of AUC returned by this may race with the update so this is deprecated. Please use tf.keras.metrics.AUC instead.c
                 `   t        j                         rt        d      t        j                  |d| ||f      5  dk7  rdk7  rt	        d d      d}
|	t        |	      }	t        |	      d	z   n't        d	z
        D cg c]  }|d
z   dz  d
z
  z   }	}d|
z
  g|	z   d|
z   gz   }	t        | ||	|      \  }}dfdfdfd}t        |||      } |d   |d   |d   |d   d      }|rt        j                  ||       ||fcddd       S c c}w # 1 sw Y   yxY w)a  Computes the approximate AUC via a Riemann sum.

  The `auc` function creates four local variables, `true_positives`,
  `true_negatives`, `false_positives` and `false_negatives` that are used to
  compute the AUC. To discretize the AUC curve, a linearly spaced set of
  thresholds is used to compute pairs of recall and precision values. The area
  under the ROC-curve is therefore computed using the height of the recall
  values by the false positive rate, while the area under the PR-curve is the
  computed using the height of the precision values by the recall.

  This value is ultimately returned as `auc`, an idempotent operation that
  computes the area under a discretized curve of precision versus recall values
  (computed using the aforementioned variables). The `num_thresholds` variable
  controls the degree of discretization with larger numbers of thresholds more
  closely approximating the true AUC. The quality of the approximation may vary
  dramatically depending on `num_thresholds`.

  For best results, `predictions` should be distributed approximately uniformly
  in the range [0, 1] and not peaked around 0 or 1. The quality of the AUC
  approximation may be poor if this is not the case. Setting `summation_method`
  to 'minoring' or 'majoring' can help quantify the error in the approximation
  by providing lower or upper bound estimate of the AUC. The `thresholds`
  parameter can be used to manually specify thresholds which split the
  predictions more evenly.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the `auc`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` whose shape matches `predictions`. Will be cast to
      `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    num_thresholds: The number of thresholds to use when discretizing the roc
      curve.
    metrics_collections: An optional list of collections that `auc` should be
      added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    curve: Specifies the name of the curve to be computed, 'ROC' [default] or
      'PR' for the Precision-Recall-curve.
    name: An optional variable_scope name.
    summation_method: Specifies the Riemann summation method used
      (https://en.wikipedia.org/wiki/Riemann_sum): 'trapezoidal' [default] that
      applies the trapezoidal rule; 'careful_interpolation', a variant of it
      differing only by a more correct interpolation scheme for PR-AUC -
      interpolating (true/false) positives but not the ratio that is precision;
      'minoring' that applies left summation for increasing intervals and right
      summation for decreasing intervals; 'majoring' that does the opposite.
      Note that 'careful_interpolation' is strictly preferred to 'trapezoidal'
      (to be deprecated soon) as it applies the same method for ROC, and a
      better one (see Davis & Goadrich 2006 for details) for the PR curve.
    thresholds: An optional list of floating point values to use as the
      thresholds for discretizing the curve. If set, the `num_thresholds`
      parameter is ignored. Values should be in [0, 1]. Endpoint thresholds
      equal to {-epsilon, 1+epsilon} for a small positive epsilon value will be
      automatically included with these to correctly handle predictions equal to
       exactly 0 or 1.

  Returns:
    auc: A scalar `Tensor` representing the current area-under-curve.
    update_op: An operation that increments the `true_positives`,
      `true_negatives`, `false_positives` and `false_negatives` variables
      appropriately and whose value matches `auc`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  z@tf.metrics.auc is not supported when eager execution is enabled.aucROCPRz&Curve must be either ROC or PR. Curve z is unknown.Hz>N   r2   r   r   gư>c                    | ddz
   | dd z
  }| |z   }t        j                  |t        j                  |ddz
   |dd z
  d      d      }| dd t        j                  ||dd       z
  }t	        j
                  t        j                  |ddz
   dkD  |dd dkD        t        j                  |ddz
   t        j                  |dd d      d      t	        j                  |dd             }t        j                  t        j                  |||t        j                  |      z  z   z  t        j                  | dd |dd z   d      d      d      S )	a  Interpolation formula inspired by section 4 of (Davis et al., 2006).

      Note here we derive & use a closed formula not present in the paper
      - as follows:
      Modeling all of TP (true positive weight),
      FP (false positive weight) and their sum P = TP + FP (positive weight)
      as varying linearly within each interval [A, B] between successive
      thresholds, we get
        Precision = (TP_A + slope * (P - P_A)) / P
      with slope = dTP / dP = (TP_B - TP_A) / (P_B - P_A).
      The area within the interval is thus (slope / total_pos_weight) times
        int_A^B{Precision.dP} = int_A^B{(TP_A + slope * (P - P_A)) * dP / P}
        int_A^B{Precision.dP} = int_A^B{slope * dP + intercept * dP / P}
      where intercept = TP_A - slope * P_A = TP_B - slope * P_B, resulting in
        int_A^B{Precision.dP} = TP_B - TP_A + intercept * log(P_B / P_A)
      Bringing back the factor (slope / total_pos_weight) we'd put aside, we get
         slope * [dTP + intercept *  log(P_B / P_A)] / total_pos_weight
      where dTP == TP_B - TP_A.
      Note that when P_A == 0 the above calculation simplifies into
        int_A^B{Precision.dTP} = int_A^B{slope * dTP} = slope * (TP_B - TP_A)
      which is really equivalent to imputing constant precision throughout the
      first bucket having >0 true positives.

      Args:
        tp: true positive counts
        fp: false positive counts
        fn: false negative counts

      Returns:
        pr_auc: an approximation of the area under the P-R curve.

      References:
        The Relationship Between Precision-Recall and ROC Curves:
          [Davis et al., 2006](https://dl.acm.org/citation.cfm?id=1143874)
          ([pdf](https://www.biostat.wisc.edu/~page/rocpr.pdf))
      Nr2   r   
prec_sloperc   recall_relative_ratiopr_auc_incrementinterpolate_pr_auc)
r   rp   r   r   r   wherer   	ones_liker   log)	r   r   r   dtppr   	interceptsafe_p_ratior   s	           r   r   zauc.<locals>.interpolate_pr_auc  s}   J ""#bf,c
r'a&&



10nq01AabE91
=j QR&8,,Z12??i__


q!4.1"4591QR519
E


#!#$qua(*, .7-@-@12-GIl   


C)hll<.H"HHIr!"v122%' $% %r!   c                 H   
dk(  r*dk(  rt        j                  d       ndk(  r
 | ||      S t        j                  | z   | |z   z         }
dk(  r!t        j                  |||z   z         }|}|}n#t        j                  | z   | |z   z         }	|}|	}dv rFt        j                  t        j
                  |ddz
   |dd z
  |ddz
   |dd z   d	z        |
      S dk(  rTt        j                  t        j
                  |ddz
   |dd z
  t        j                  |ddz
   |dd             |
      S dk(  rTt        j                  t        j
                  |ddz
   |dd z
  t        j                  |ddz
   |dd             |
      S t        d d      )z9Computes the roc-auc or pr-auc based on confusion counts.r   trapezoidalziTrapezoidal rule is known to produce incorrect PR-AUCs; please switch to "careful_interpolation" instead.careful_interpolationr   )r   r   Nr2   g       @rc   minoringmajoringzInvalid summation_method: z^ summation_method should be 'trapezoidal', 'careful_interpolation', 'minoring', or 'majoring'.)	loggingwarningr   divider   r   minimumr   rk   )r   r   r   r   r'   recfp_ratexypreccurveepsilonr   r   summation_methods             r   compute_auczauc.<locals>.compute_auc  s   	$},
//BC !88#BB/
/OOBL"r'G*;<c	%//"b2g&78rG|R"Ww->?	E	E ""a 3!!34qu< !4.1"45!"=CE 	 z)""a 3!!34qu<&..q1D.12D/EquMO 	 z)""a 3!!34qu<&..q1D.12D/EquMO 	
 56F5G H) ) * 	*r!   c                 4     |d   |d   |d   |d   d      S )Nr   r   r   r   r   r<   )r   r   r  s     r   compute_auc_valuezauc.<locals>.compute_auc_value  s+    vd|VD\6$< " "r!   r   r   r   r   r~   )r   r   r   r   rk   sortedr   ranger   r   r   r   )rQ   rP   r:   r   r   r   r	  r'   r  r   kepsilonir   r   r  	auc_valuer~   r  r
  r   s      `  ` `        @@@r   r   r   %  s   v  
 % & & $$T5&,k7%CE K ~%4-?w G" " # # H*%j:*n
 #>A#568 UcM^a%78 8j 8
 .!J.#.1AAJ8Z2FJ G7%r(* (*V" +.8IJt,j.>&t,j.>MI 	0)<iWK  K 8K  K s     AD$DA8D$D$$D-zmetrics.mean_absolute_errorc                     t        j                         rt        d      t        || |      \  }} }t	        j
                  || z
        }t        |||||xs d      S )a=  Computes the mean absolute error between the labels and predictions.

  The `mean_absolute_error` function creates two local variables,
  `total` and `count` that are used to compute the mean absolute error. This
  average is weighted by `weights`, and it is ultimately returned as
  `mean_absolute_error`: an idempotent operation that simply divides `total` by
  `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `mean_absolute_error`. Internally, an `absolute_errors` operation computes the
  absolute value of the differences between `predictions` and `labels`. Then
  `update_op` increments `total` with the reduced sum of the product of
  `weights` and `absolute_errors`, and it increments `count` with the reduced
  sum of `weights`

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of the same shape as `predictions`.
    predictions: A `Tensor` of arbitrary shape.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that
      `mean_absolute_error` should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    mean_absolute_error: A `Tensor` representing the current mean, the value of
      `total` divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `mean_absolute_error`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zPtf.metrics.mean_absolute_error is not supported when eager execution is enabled.r   mean_absolute_error)r   r   r   rW   r   absr   )rQ   rP   r:   r   r   r'   absolute_errorss          r   r  r    sq    d  
 : ; ; "?fg"?+vwLLv!56/	ow(;!4#@+@
B Br!   zmetrics.mean_cosine_distancec                    t        j                         rt        d      t        || |      \  }} }t	        j
                  ||       }t	        j                  ||gd      }t        ||dd|xs d      \  }}	t	        j                  d|      }t	        j                  d|	      }	|rt        j                  ||       |rt        j                  ||	       ||	fS )ar  Computes the cosine distance between the labels and predictions.

  The `mean_cosine_distance` function creates two local variables,
  `total` and `count` that are used to compute the average cosine distance
  between `predictions` and `labels`. This average is weighted by `weights`,
  and it is ultimately returned as `mean_distance`, which is an idempotent
  operation that simply divides `total` by `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `mean_distance`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of arbitrary shape.
    predictions: A `Tensor` of the same shape as `labels`.
    dim: The dimension along which the cosine distance is computed.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension). Also,
      dimension `dim` must be `1`.
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.
    name: An optional variable_scope name.

  Returns:
    mean_distance: A `Tensor` representing the current mean, the value of
      `total` divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zQtf.metrics.mean_cosine_distance is not supported when eager execution is enabled.r   T)axiskeepdimsNmean_cosine_distancer   )r   r   r   rW   r   r   r   r   subtractr   r   )
rQ   rP   dimr:   r   r   r'   radial_diffsmean_distancer~   s
             r   r  r  O  s    b  
 5 6 6 "?fg"?+vw"";7,$$
, ",tT F9"8:-##C7-Y/).>.	:			!!r!   zmetrics.mean_per_class_accuracyc                    t        j                         rt        d      t        j                  |d|| |f      5  t	        j
                  | t        j                        } | j                         j                  dkD  rt        j                  | dg      } |j                         j                  dkD  rt        j                  |dg      }|j                         j                  | j                                t        |gt        j                  d      }t        |gt        j                  d      }t        j                  t        j                   |       gt        j                        }	| j"                  |j"                  k7  r t	        j
                  || j"                        }t	        j
                  t	        j$                  ||       t        j                        }
|b|j                         j                  dkD  rt        j                  |dg      }t	        j
                  |t        j                        }|
|z  }
|	|z  }	t'        j(                  || |	      }t'        j(                  || |
      }d	 }t+        ||||      }t	        j,                  |t	        j.                  |d
      d      }|rt1        j2                  ||       ||fcddd       S # 1 sw Y   yxY w)a2  Calculates the mean of the per-class accuracies.

  Calculates the accuracy for each class, then takes the mean of that.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates the accuracy of each class and returns
  them.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of ground truth labels with shape [batch size] and of
      type `int32` or `int64`. The tensor will be flattened if its rank > 1.
    predictions: A `Tensor` of prediction results for semantic labels, whose
      shape is [batch size] and type `int32` or `int64`. The tensor will be
      flattened if its rank > 1.
    num_classes: The possible number of labels the prediction task can
      have. This value must be provided, since two variables with shape =
      [num_classes] will be allocated.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that
      `mean_per_class_accuracy'
      should be added to.
    updates_collections: An optional list of collections `update_op` should be
      added to.
    name: An optional variable_scope name.

  Returns:
    mean_accuracy: A `Tensor` representing the mean per class accuracy.
    update_op: An operation that updates the accuracy tensor.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zTtf.metrics.mean_per_class_accuracy is not supported when eager execution is enabled.mean_accuracyr2   r3   r   rc   r   Nc                     t        j                  |t        j                  |d      d       }t        j                  |d      }|S )Nr   rc   r!  )r   rp   r   reduce_mean)r   r   r   per_class_accuracymean_accuracy_vs        r   compute_mean_accuracyz6mean_per_class_accuracy.<locals>.compute_mean_accuracy  sB    #..
!!%+$8 ,,
?4or!   r   r~   )r   r   r   r   r   rw   r   rx   rJ   rL   r   ry   rK   r0   r   onesrj   r   r>   r   scatter_addr   rp   r   r   r   )rQ   rP   r{   r:   r   r   r'   r   r   r'  r   r   r   r&  r%  r~   s                   r   mean_per_class_accuracyr)    sW   `  
 : ; ; $$T?&167%CE 2&]]66<<0F !#  ".f$$q(%%kB48k 55f6F6F6HI[M6>>HE[M6>>HE>>9>>&12FNNCD||{(((MM+v||<k{F+V^^=J 					"	"Q	&##GbT2gv~~6gGj
god++E64@O++E6:FO 12E5BO ##))/1=KQI	0)<I%e2& 2& 2&s   JKKzmetrics.mean_iouc                 t   t        j                         rt        d      t        j                  |d|| |f      5  |j	                         j                  | j	                                t        | |||      \  }}d }	t        ||	|      }
|rt        j                  ||       |
|fcddd       S # 1 sw Y   yxY w)a  Calculate per-step mean Intersection-Over-Union (mIOU).

  Mean Intersection-Over-Union is a common evaluation metric for
  semantic image segmentation, which first computes the IOU for each
  semantic class and then computes the average over classes.
  IOU is defined as follows:
    IOU = true_positive / (true_positive + false_positive + false_negative).
  The predictions are accumulated in a confusion matrix, weighted by `weights`,
  and mIOU is then calculated from it.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the `mean_iou`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of ground truth labels with shape [batch size] and of
      type `int32` or `int64`. The tensor will be flattened if its rank > 1.
    predictions: A `Tensor` of prediction results for semantic labels, whose
      shape is [batch size] and type `int32` or `int64`. The tensor will be
      flattened if its rank > 1.
    num_classes: The possible number of labels the prediction task can
      have. This value must be provided, since a confusion matrix of
      dimension = [num_classes, num_classes] will be allocated.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `mean_iou`
      should be added to.
    updates_collections: An optional list of collections `update_op` should be
      added to.
    name: An optional variable_scope name.

  Returns:
    mean_iou: A `Tensor` representing the mean intersection-over-union.
    update_op: An operation that increments the confusion matrix.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zEtf.metrics.mean_iou is not supported when eager execution is enabled.mean_iouc                 *   t        j                  t        j                  |d      t        j                        }t        j                  t        j                  |d      t        j                        }t        j                  t        j                  |      t        j                        }||z   |z
  }t        j                  t        j                  t        j                  |d      t        j                              }t        j                  t        j                  |d      |t        j                  |            }t        j                  ||      }t        j                  t        j                  |d      t        j                  |d      |z  d      }|S )zBCompute the mean intersection-over-union via the confusion matrix.r   r2   r   r+  rc   )r   rw   r   r   r   r   	diag_part	not_equalr   r   r   r  )	r   r|   sum_over_rowsum_over_colcm_diagrr   num_valid_entriesiouresults	            r   compute_mean_iouz"mean_iou.<locals>.compute_mean_iouB  s2   ]]


h
*FNN<l]]


h
*FNN<li11(;V^^Lg </'9k
 #--
--  a0HI OO


;
*K


k
*,k OOG[1c 


,a
0


c

36G
GLf mr!   N)
r   r   r   r   rJ   rK   r   r   r   r   )rQ   rP   r{   r:   r   r   r'   r|   r~   r5  
mean_iou_vs              r   r+  r+    s    h  
 5 6 6 $$T:&167%CE ,! 55f6F6F6HI5fk6A7LHi< ,-x9J 	0)<y Y,! ,! ,!s   A*B..B7zmetrics.mean_relative_errorc           
         t        j                         rt        d      t        || |      \  }} }t	        j
                  ||      \  }}|j                         j                  |j                                t        j                  t        j                  |d      t        j                  |       t        j                  t        j                  | |z
        |            }t        |||||xs d      S )a  Computes the mean relative error by normalizing with the given values.

  The `mean_relative_error` function creates two local variables,
  `total` and `count` that are used to compute the mean relative absolute error.
  This average is weighted by `weights`, and it is ultimately returned as
  `mean_relative_error`: an idempotent operation that simply divides `total` by
  `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `mean_reative_error`. Internally, a `relative_errors` operation divides the
  absolute value of the differences between `predictions` and `labels` by the
  `normalizer`. Then `update_op` increments `total` with the reduced sum of the
  product of `weights` and `relative_errors`, and it increments `count` with the
  reduced sum of `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of the same shape as `predictions`.
    predictions: A `Tensor` of arbitrary shape.
    normalizer: A `Tensor` of the same shape as `predictions`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that
      `mean_relative_error` should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    mean_relative_error: A `Tensor` representing the current mean, the value of
      `total` divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `mean_relative_error`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zPtf.metrics.mean_relative_error is not supported when eager execution is enabled.r   r   mean_relative_error)r   r   r   rW   r   rI   rJ   rK   r   r   r   r>   
zeros_liker  r  r   )rQ   rP   
normalizerr:   r   r   r'   relative_errorss           r   r8  r8  i  s    h  
 5 6 6 "?fg"?+vw -II:+z33J4H4H4JKOOnnZ%y';';F'Coohll6K#78*EG/ 
ow(;!4#@+@
B Br!   zmetrics.mean_squared_errorc                     t        j                         rt        d      t        || |      \  }} }t	        j
                  | |      }t        |||||xs d      S )a5  Computes the mean squared error between the labels and predictions.

  The `mean_squared_error` function creates two local variables,
  `total` and `count` that are used to compute the mean squared error.
  This average is weighted by `weights`, and it is ultimately returned as
  `mean_squared_error`: an idempotent operation that simply divides `total` by
  `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `mean_squared_error`. Internally, a `squared_error` operation computes the
  element-wise square of the difference between `predictions` and `labels`. Then
  `update_op` increments `total` with the reduced sum of the product of
  `weights` and `squared_error`, and it increments `count` with the reduced sum
  of `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of the same shape as `predictions`.
    predictions: A `Tensor` of arbitrary shape.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that
      `mean_squared_error` should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    mean_squared_error: A `Tensor` representing the current mean, the value of
      `total` divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `mean_squared_error`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zOtf.metrics.mean_squared_error is not supported when eager execution is enabled.r   mean_squared_error)r   r   r   rW   r   squared_differencer   )rQ   rP   r:   r   r   r'   squared_errors          r   r=  r=    so    d  
 5 6 6 "?fg"?+vw--fkB-	mW&9;N**
, ,r!   zmetrics.mean_tensorc                    t        j                         rt        d      t        j                  |d| |f      5  t	        j
                  | t        j                        } t        | j                         t        j                  d      }t        | j                         t        j                  d      }t        j                  |       }|vt        | d|      \  } }}t        j                  t	        j
                  |t        j                        |       }t	        j                  | |      } t	        j                  ||      }t!        j"                  ||       }	t%        j&                  | g      5  t!        j"                  ||      }
ddd       d }t)        ||||      }t	        j*                  |	t	        j,                  
d	      d
      }|rt%        j.                  ||       ||fcddd       S # 1 sw Y   kxY w# 1 sw Y   yxY w)aw  Computes the element-wise (weighted) mean of the given tensors.

  In contrast to the `mean` function which returns a scalar with the
  mean,  this function returns an average tensor with the same shape as the
  input tensors.

  The `mean_tensor` function creates two local variables,
  `total_tensor` and `count_tensor` that are used to compute the average of
  `values`. This average is ultimately returned as `mean` which is an idempotent
  operation that simply divides `total` by `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the `mean`.
  `update_op` increments `total` with the reduced sum of the product of `values`
  and `weights`, and it increments `count` with the reduced sum of `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    values: A `Tensor` of arbitrary dimensions.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `values`, and must be broadcastable to `values` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `values` dimension).
    metrics_collections: An optional list of collections that `mean`
      should be added to.
    updates_collections: An optional list of collections that `update_op`
      should be added to.
    name: An optional variable_scope name.

  Returns:
    mean: A float `Tensor` representing the current mean, the value of `total`
      divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `mean_value`.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match `values`,
      or if either `metrics_collections` or `updates_collections` are not a list
      or tuple.
    RuntimeError: If eager execution is enabled.
  zHtf.metrics.mean_tensor is not supported when eager execution is enabled.r   total_tensorrc   count_tensorNr   c                 Z    t        j                  |t        j                  |d      d      S r   r   r   s      r   r    zmean_tensor.<locals>.<lambda>2  s%    8#6#6	8Aq!$1 r!   r   r~   )r   r   r   r   r   rw   r   r   r0   rJ   r   r   rW   r   r   r   r   rz   r   r   r   rp   r   r   r   s                 r   mean_tensorrD    s   ^  
 5 6 6 $$T6FG3DE ]]66>>2FFNNAEFNNAE $$V,J8T7<fa%77
--
0&:g  1f$$Z9j**5&9O		!	!6(	+ @!,,UJ?o@1L (\5%9F ##))/1=KQI	0)<9? "@ @# s%   D2G8+G,A G8,G5	1G88Hzmetrics.percentage_belowc                     t        j                         rt        d      t        j                  t        j
                  | |      t        j                        }t        |||||xs d      S )a  Computes the percentage of values less than the given threshold.

  The `percentage_below` function creates two local variables,
  `total` and `count` that are used to compute the percentage of `values` that
  fall below `threshold`. This rate is weighted by `weights`, and it is
  ultimately returned as `percentage` which is an idempotent operation that
  simply divides `total` by `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `percentage`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    values: A numeric `Tensor` of arbitrary size.
    threshold: A scalar threshold.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `values`, and must be broadcastable to `values` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `values` dimension).
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.
    name: An optional variable_scope name.

  Returns:
    percentage: A `Tensor` representing the current mean, the value of `total`
      divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match `values`,
      or if either `metrics_collections` or `updates_collections` are not a list
      or tuple.
    RuntimeError: If eager execution is enabled.
  zMtf.metrics.percentage_below is not supported when eager execution is enabled.percentage_below_threshold)	r   r   r   r   rw   lessr   r   r   )r   	thresholdr:   r   r   r'   is_below_thresholds          r   percentage_belowrJ  @  sj    Z  
 5 6 6  }}mmFI&8	 '+>!4#G+G
I Ir!   c           	         t        j                  | t        j                         t	        g t        j
                  d      }t        j                  | t        j
                        } |t        j                  t        j                  |dt        j                  |       f      f      5  t        j                  |t        j
                        }t        j                  | |      } ddd       t        ||      }t        j                   |t        j"                  |             }|rt        j$                  ||       ||fS # 1 sw Y   ZxY w)a  Sums the weights of cases where the given values are True.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    values: A `bool` `Tensor` of arbitrary size.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `values`, and must be broadcastable to `values` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `values` dimension).
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.

  Returns:
    value_tensor: A `Tensor` representing the current value of the metric.
    update_op: An operation that accumulates the error from a batch of data.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match `values`,
      or if either `metrics_collections` or `updates_collections` are not a list
      or tuple.
  r   rc   Nr   )r
   assert_typer   r   r0   r   r   rw   r   r   assert_rank_inr   rM   r   r   r   rz   r   r   )r   r:   r   r   r   value_tensorr~   s          r   _count_conditionrO  w  s    6 ,
"fnn7
;%==0&		!	!9#;#;!Y^^F+,$. #0 
1 2gv~~6g  1f2
 %U,?@,""5(*=*=f*EF).	:	y	  2 2s   &;D::Ezmetrics.false_negativesc                    t        j                         rt        d      t        j                  |d|| |f      5  t	        t        j                  |t        j                        t        j                  | t        j                        |      \  }} }t        j                  t        j                  | d      t        j                  |d            }t        ||||      cddd       S # 1 sw Y   yxY w)a  Computes the total number of false negatives.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: The predicted values, a `Tensor` of arbitrary dimensions. Will
      be cast to `bool`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.
    name: An optional variable_scope name.

  Returns:
    value_tensor: A `Tensor` representing the current value of the metric.
    update_op: An operation that accumulates the error from a batch of data.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match `values`,
      or if either `metrics_collections` or `updates_collections` are not a list
      or tuple.
    RuntimeError: If eager execution is enabled.
  zLtf.metrics.false_negatives is not supported when eager execution is enabled.r   r   r   TFNr   r   r   r   rW   r   rw   r   r   r   r>   rO  )rQ   rP   r:   r   r   r'   r   s          r   r   r     s    F  
 5 6 6 $$T+<&167%CE 
1 $AMM+V[[A}}V6;;7$ K !,,vt$hnn[%&HJ-w8K/1
1 
1 
1   B$C((C1z%metrics.false_negatives_at_thresholdsc                 (   t        j                         rt        d      t        j                  |d|| |f      5  t	        | |||d      \  }}t        |d   |      }	|rt        j                  ||d          |	|d   fcddd       S # 1 sw Y   yxY w)at  Computes false negatives at provided threshold values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` whose shape matches `predictions`. Will be cast to
      `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `false_negatives`
      should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    false_negatives:  A float `Tensor` of shape `[len(thresholds)]`.
    update_op: An operation that updates the `false_negatives` variable and
      returns its current value.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zZtf.metrics.false_negatives_at_thresholds is not supported when eager execution is enabled.r   )r   r:   r   r   Nr   r   r   r   r   r   r   r   )
rQ   rP   r   r:   r   r   r'   r   r   fn_values
             r   false_negatives_at_thresholdsrW        N  
 D E E $$T+<&167%CE 
&8Z7LFJ #6$<1DEH	0*T2BCZ%%
& 
& 
&   ABBzmetrics.false_positivesc                    t        j                         rt        d      t        j                  |d|| |f      5  t	        t        j                  |t        j                        t        j                  | t        j                        |      \  }} }t        j                  t        j                  | d      t        j                  |d            }t        ||||      cddd       S # 1 sw Y   yxY w)a+  Sum the weights of false positives.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: The predicted values, a `Tensor` of arbitrary dimensions. Will
      be cast to `bool`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.
    name: An optional variable_scope name.

  Returns:
    value_tensor: A `Tensor` representing the current value of the metric.
    update_op: An operation that accumulates the error from a batch of data.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zLtf.metrics.false_positives is not supported when eager execution is enabled.r   r   r   FTNrQ  )rQ   rP   r:   r   r   r'   r   s          r   r   r     s    H  
 5 6 6 $$T+<&167%CE 
1 $AMM+V[[A}}V6;;7$ K !,,vu%x~~k4'HJ-w8K/1
1 
1 
1rR  z%metrics.false_positives_at_thresholdsc                 (   t        j                         rt        d      t        j                  |d|| |f      5  t	        | |||d      \  }}t        |d   |      }	|rt        j                  ||d          |	|d   fcddd       S # 1 sw Y   yxY w)at  Computes false positives at provided threshold values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` whose shape matches `predictions`. Will be cast to
      `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `false_positives`
      should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    false_positives:  A float `Tensor` of shape `[len(thresholds)]`.
    update_op: An operation that updates the `false_positives` variable and
      returns its current value.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zZtf.metrics.false_positives_at_thresholds is not supported when eager execution is enabled.r   )r   rT  r   NrU  )
rQ   rP   r   r:   r   r   r'   r   r   fp_values
             r   false_positives_at_thresholdsr]  F  rX  rY  zmetrics.true_negativesc                    t        j                         rt        d      t        j                  |d|| |f      5  t	        t        j                  |t        j                        t        j                  | t        j                        |      \  }} }t        j                  t        j                  | d      t        j                  |d            }t        ||||      cddd       S # 1 sw Y   yxY w)a*  Sum the weights of true_negatives.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: The predicted values, a `Tensor` of arbitrary dimensions. Will
      be cast to `bool`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.
    name: An optional variable_scope name.

  Returns:
    value_tensor: A `Tensor` representing the current value of the metric.
    update_op: An operation that accumulates the error from a batch of data.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zKtf.metrics.true_negatives is not supported when eager execution is enabled.r   r   r   FNrQ  )rQ   rP   r:   r   r   r'   r   s          r   r   r   ~  s    H  
 D E E $$T+;&167%CE 
1 $AMM+V[[A}}V6;;7$ K  ++vu%x~~k5'IK,g7J/1
1 
1 
1rR  z$metrics.true_negatives_at_thresholdsc                 (   t        j                         rt        d      t        j                  |d|| |f      5  t	        | |||d      \  }}t        |d   |      }	|rt        j                  ||d          |	|d   fcddd       S # 1 sw Y   yxY w)ap  Computes true negatives at provided threshold values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` whose shape matches `predictions`. Will be cast to
      `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `true_negatives`
      should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    true_negatives:  A float `Tensor` of shape `[len(thresholds)]`.
    update_op: An operation that updates the `true_negatives` variable and
      returns its current value.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zYtf.metrics.true_negatives_at_thresholds is not supported when eager execution is enabled.r   )r   rT  r   NrU  )
rQ   rP   r   r:   r   r   r'   r   r   tn_values
             r   true_negatives_at_thresholdsra        N  
 D E E $$T+;&167%CE 
&8Z7LFJ #6$<1DEH	0*T2BCZ%%
& 
& 
&rY  zmetrics.true_positivesc                    t        j                         rt        d      t        j                  |d|| |f      5  t	        t        j                  |t        j                        t        j                  | t        j                        |      \  }} }t        j                  t        j                  | d      t        j                  |d            }t        ||||      cddd       S # 1 sw Y   yxY w)a*  Sum the weights of true_positives.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: The predicted values, a `Tensor` of arbitrary dimensions. Will
      be cast to `bool`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that the metric
      value variable should be added to.
    updates_collections: An optional list of collections that the metric update
      ops should be added to.
    name: An optional variable_scope name.

  Returns:
    value_tensor: A `Tensor` representing the current value of the metric.
    update_op: An operation that accumulates the error from a batch of data.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zKtf.metrics.true_positives is not supported when eager execution is enabled.r   r   r   TNrQ  )rQ   rP   r:   r   r   r'   r   s          r   r   r     s    H  
 D E E $$T+;&167%CE 
1 $AMM+V[[A}}V6;;7$ K  ++vt$hnn[$&GI,g7J/1
1 
1 
1rR  z$metrics.true_positives_at_thresholdsc                 (   t        j                         rt        d      t        j                  |d|| |f      5  t	        | |||d      \  }}t        |d   |      }	|rt        j                  ||d          |	|d   fcddd       S # 1 sw Y   yxY w)ap  Computes true positives at provided threshold values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` whose shape matches `predictions`. Will be cast to
      `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `true_positives`
      should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    true_positives:  A float `Tensor` of shape `[len(thresholds)]`.
    update_op: An operation that updates the `true_positives` variable and
      returns its current value.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zYtf.metrics.true_positives_at_thresholds is not supported when eager execution is enabled.r   )r   rT  r   NrU  )
rQ   rP   r   r:   r   r   r'   r   r   tp_values
             r   true_positives_at_thresholdsrf     rb  rY  zmetrics.precisionc           	         t        j                         rt        d      t        j                  |d|| |f      5  t	        t        j                  |t        j                        t        j                  | t        j                        |      \  }} }t        | ||ddd      \  }}t        | ||ddd      \  }}	d fd}
t        ||
||      } ||	d	      }|rt        j                  ||       ||fcddd       S # 1 sw Y   yxY w)
a  Computes the precision of the predictions with respect to the labels.

  The `precision` function creates two local variables,
  `true_positives` and `false_positives`, that are used to compute the
  precision. This value is ultimately returned as `precision`, an idempotent
  operation that simply divides `true_positives` by the sum of `true_positives`
  and `false_positives`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `precision`. `update_op` weights each prediction by the corresponding value in
  `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: The predicted values, a `Tensor` of arbitrary dimensions. Will
      be cast to `bool`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `precision` should
      be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    precision: Scalar float `Tensor` with the value of `true_positives`
      divided by the sum of `true_positives` and `false_positives`.
    update_op: `Operation` that increments `true_positives` and
      `false_positives` variables appropriately and whose value matches
      `precision`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zFtf.metrics.precision is not supported when eager execution is enabled.	precisionr   r   Nr   r   r'   c                     t        j                  t        j                  | |z   d      t        j                  | | |z         d|      S Nr   r   r   r   r   r  )r   r   r'   s      r   compute_precisionz$precision.<locals>.compute_precision  s>    __


27A
&BG(DaO Or!   c                      ||d      S Nr   r<   )r   r   r   rm  s      r   once_across_replicasz'precision.<locals>.once_across_replicas  s    vw88r!   r~   )r   r   r   r   rW   r   rw   r   r   r   r   r   r   r   )rQ   rP   r:   r   r   r'   r   true_positives_update_opr   false_positives_update_oprp  r   r~   rm  s                @r   rh  rh  X  s1   d  
 D E E $$T;&167%CE & $AMM+V[[A}}V6;;7$ K
 (6  ($F$ *9  *&G&O9 	##68L#)7	4A "":";[JI	0)<i<M& & &   B<DD
zmetrics.precision_at_thresholdsc                 T   t        j                         rt        d      t        j                  |d|| |f      5  t	        | |||d      \  }}dfdfd}	t        ||	|      }
 |d   |d	   d
      }|rt        j                  ||       |
|fcddd       S # 1 sw Y   yxY w)al  Computes precision values for different `thresholds` on `predictions`.

  The `precision_at_thresholds` function creates four local variables,
  `true_positives`, `true_negatives`, `false_positives` and `false_negatives`
  for various values of thresholds. `precision[i]` is defined as the total
  weight of values in `predictions` above `thresholds[i]` whose corresponding
  entry in `labels` is `True`, divided by the total weight of values in
  `predictions` above `thresholds[i]` (`true_positives[i] / (true_positives[i] +
  false_positives[i])`).

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `precision`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `auc` should be
      added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    precision: A float `Tensor` of shape `[len(thresholds)]`.
    update_op: An operation that increments the `true_positives`,
      `true_negatives`, `false_positives` and `false_negatives` variables that
      are used in the computation of `precision`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zTtf.metrics.precision_at_thresholds is not supported when eager execution is enabled.precision_at_thresholds)r   r   r   r   c                 F    t        j                  | | z   |z   d|z         S )N
precision_rc   r   r  )r   r   r'   r
  s      r   rm  z2precision_at_thresholds.<locals>.compute_precision  s$    __R2!29LMMr!   c                 $     |d   |d   d      S )Nr   r   r   r<   )r   r   rm  s     r   precision_across_replicasz:precision_at_thresholds.<locals>.precision_across_replicas  s    vd|VD\7CCr!   r   r   r~   Nr   r   r   r   r   r   r   r   )rQ   rP   r   r:   r   r   r'   r   r   r{  r  r~   rm  r
  s               @@r   ru  ru    s    h  
 D E E $$T+D&167%CE 8Z<IFJ GND &6@D "*T"2Jt4D"-/I	0)<?-     ABB'zmetrics.recallc           	         t        j                         rt        d      t        j                  |d|| |f      5  t	        t        j                  |t        j                        t        j                  | t        j                        |      \  }} }t        | ||ddd      \  }}t        | ||ddd      \  }}	d fd}
t        ||
||      } ||	d	      }|rt        j                  ||       ||fcddd       S # 1 sw Y   yxY w)
a  Computes the recall of the predictions with respect to the labels.

  The `recall` function creates two local variables, `true_positives`
  and `false_negatives`, that are used to compute the recall. This value is
  ultimately returned as `recall`, an idempotent operation that simply divides
  `true_positives` by the sum of `true_positives` and `false_negatives`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` that updates these variables and returns the `recall`. `update_op`
  weights each prediction by the corresponding value in `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: The predicted values, a `Tensor` of arbitrary dimensions. Will
      be cast to `bool`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `recall` should
      be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    recall: Scalar float `Tensor` with the value of `true_positives` divided
      by the sum of `true_positives` and `false_negatives`.
    update_op: `Operation` that increments `true_positives` and
      `false_negatives` variables appropriately and whose value matches
      `recall`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zTtf.metrics.recall is not supported is not supported when eager execution is enabled.recallr   r   Nri  c                     t        j                  t        j                  | |z   d      t        j                  | | |z         d|      S rk  rl  )r   r   r'   s      r   compute_recallzrecall.<locals>.compute_recallR	  s?    __


6G+Q
/
//&&7"2
3Q> >r!   c                      ||d      S ro  r<   )r   r   r   r  s      r   rp  z$recall.<locals>.once_across_replicasW	  s    FGW55r!   r~   )r   r   r   r   rW   r   rw   r   r   r   r   r   r   r   )rQ   rP   r:   r   r   r'   r   rq  r   false_negatives_update_oprp  r  r~   r  s                @r   r  r  	  s-   `  
 D E E $$T8&167%CE &#@MM+V[[A}}V6;;7$ K
 (6  ($F$ *9  *&G&>
6 %167DC 78+GI	0)<	>M& & &rs  c                 6    |d| |fz  } nd| z  } |d| |fz  } | S )Nz%s_at_%dz%s_at_kz
%s_class%dr<   )r'   kclass_ids      r   
_at_k_namer  e	  s9    ]q	!DD4**D	+r!   c                    t        j                  |       } t        | t         j                        r4t	        j
                  | t        j                  | j                  |            S t        j                  | t        j                        }t        j                  |      dz
  }t        j                  |t        j                  |dg            }t        j                   |t        j"                  |t        j                              }t%        j&                  ||       }t        j                  |j(                  |j                  |      S )a  Filter all but `selected_id` out of `ids`.

  Args:
    ids: `int64` `Tensor` or `SparseTensor` of IDs.
    selected_id: Int id to select.

  Returns:
    `SparseTensor` of same dimensions as `ids`. This contains only the entries
    equal to `selected_id`.
  )out_typer2   indicesr   r^   )r   rg   rh   ri   r   sparse_retainr   r>   r   r   r   r   rx   rj   reduced_shapery   fillrw   r   set_intersectionr  )idsselected_id	ids_shapeids_last_dimfilled_selected_id_shapefilled_selected_idr4  s          r   _select_class_idr  o	  s    	88=#]//0##C

8C*E F F oocFLL9)	*Q.,%33I4=4E4E8Dqc5KL
 !~~&>&.mmK&NP  !3S9&		#	#nnV]]	
K Kr!   c                 >    || |fS t        | |      t        ||      fS )a  If class ID is specified, filter all other classes.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: `int64` `Tensor` of class IDs, with shape [D1, ... DN, k]
      where N >= 1. Commonly, N=1 and `predictions_idx` has shape
      [batch size, k].
    selected_id: Int id to select.

  Returns:
    Tuple of `labels` and `predictions_idx`, possibly with classes removed.
  )r  )rQ   predictions_idxr  s      r   _maybe_select_class_idr  	  s3    " ?""
6;
/
?K
8
: :r!   c                    t        j                  |d|| |f      5  t        | ||      \  } }t        j                  t        j
                  ||             }t        j                  |t        j                        }|mt        j                  t        j                  ||      f      5  t        j                  |t        j                        }t        j                  ||      }ddd       |cddd       S # 1 sw Y   xY w# 1 sw Y   yxY w)a  Calculates true positives for recall@k and precision@k.

  If `class_id` is specified, calculate binary true positives for `class_id`
      only.
  If `class_id` is not specified, calculate metrics for `k` predicted vs
      `n` label classes, where `n` is the 2nd dimension of `labels_sparse`.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: 1-D or higher `int64` `Tensor` with last dimension `k`,
      top `k` predicted classes. For rank `n`, the first `n-1` dimensions must
      match `labels`.
    class_id: Class for which we want binary metrics.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    name: Name of operation.

  Returns:
    A [D1, ... DN] `Tensor` of true positive counts.
  r   N)r   rf   r  r   set_sizer  r   rw   r   rv   r   r   assert_broadcastabler   )rQ   r  r  r:   r'   r   s         r   _sparse_true_positive_at_kr  	  s    > ~~d,&8: 4V_5=?FO	t,,_fE	FB	r6>>	*B##%:%O%O
2& %  ,--8r7+,  , , s$   B
C?%;C3 	C?3C<	8C??Dc                 r   t        j                  |t        d||      || |f      5 }t        || ||      }t	        j
                  t	        j                  |      t        j                        }t        g t        j                  |      }	|	t        j                  |	|d      fcddd       S # 1 sw Y   yxY w)a  Calculates weighted per step true positives for recall@k and precision@k.

  If `class_id` is specified, calculate binary true positives for `class_id`
      only.
  If `class_id` is not specified, calculate metrics for `k` predicted vs
      `n` label classes, where `n` is the 2nd dimension of `labels`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: 1-D or higher `int64` `Tensor` with last dimension `k`,
      top `k` predicted classes. For rank `n`, the first `n-1` dimensions must
      match `labels`.
    k: Integer, k for @k metric. This is only used for default op name.
    class_id: Class for which we want binary metrics.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    name: Name of new variable, and namespace for other dependent ops.

  Returns:
    A tuple of `Variable` and update `Operation`.

  Raises:
    ValueError: If `weights` is not `None` and has an incompatible shape.
  true_positiver  r  rQ   r  r:   rc   updateN)r   rf   r  r  r   rw   r   r   rv   r0   r   rz   )
rQ   r  r  r  r:   r'   r`   r   batch_total_tpvars
             r   $_streaming_sparse_true_positive_at_kr  	  s    L ~~dJHM&8: 
I=B	#'	
B
 ]]8#6#6r#:FNNKN
"fnn5
9C	$$S.xHH
I 
I 
I   A<B--B6c                    t        j                  dd|| |f      5  t        | ||      \  } }t        j                  t        j
                  || d            }t        j                  |t        j                        }|mt        j                  t        j                  ||      f      5  t        j                  |t        j                        }t        j                  ||      }ddd       |cddd       S # 1 sw Y   xY w# 1 sw Y   yxY w)a{  Calculates false negatives for recall@k.

  If `class_id` is specified, calculate binary true positives for `class_id`
      only.
  If `class_id` is not specified, calculate metrics for `k` predicted vs
      `n` label classes, where `n` is the 2nd dimension of `labels_sparse`.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: 1-D or higher `int64` `Tensor` with last dimension `k`,
      top `k` predicted classes. For rank `n`, the first `n-1` dimensions must
      match `labels`.
    class_id: Class for which we want binary metrics.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).

  Returns:
    A [D1, ... DN] `Tensor` of false negative counts.
  Nr   Faminusbr   rf   r  r   r  set_differencer   rw   r   rv   r   r   r  r   )rQ   r  r  r:   r   s        r   _sparse_false_negative_at_kr  
  s    : ~~d-&8: 4V_5=?FO	OVUC
EB	r6>>	*B##%:%O%O
2& %  ,--8r7+,  , , $   BD';C5"	D5C>	:DD
c                 r   t        j                  |t        d||      || |f      5 }t        || ||      }t	        j
                  t	        j                  |      t        j                        }t        g t        j                  |      }	|	t        j                  |	|d      fcddd       S # 1 sw Y   yxY w)a  Calculates weighted per step false negatives for recall@k.

  If `class_id` is specified, calculate binary true positives for `class_id`
      only.
  If `class_id` is not specified, calculate metrics for `k` predicted vs
      `n` label classes, where `n` is the 2nd dimension of `labels`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: 1-D or higher `int64` `Tensor` with last dimension `k`,
      top `k` predicted classes. For rank `n`, the first `n-1` dimensions must
      match `labels`.
    k: Integer, k for @k metric. This is only used for default op name.
    class_id: Class for which we want binary metrics.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    name: Name of new variable, and namespace for other dependent ops.

  Returns:
    A tuple of `Variable` and update `Operation`.

  Raises:
    ValueError: If `weights` is not `None` and has an incompatible shape.
  false_negativer  r  rc   r  N)r   rf   r  r  r   rw   r   r   rv   r0   r   rz   )
rQ   r  r  r  r:   r'   r`   r   batch_total_fnr  s
             r   %_streaming_sparse_false_negative_at_kr  4
      L ~~dJ'7XN&8: 
I=B	$'	
B
 ]]8#6#6r#:FNNKN
"fnn5
9C	$$S.xHH
I 
I 
Ir  zmetrics.recall_at_kc                    t        j                         rt        d      t        j                  |t        d||      || |f      5 }t        j                  ||      \  }	}
t        | |
||||||      cddd       S # 1 sw Y   yxY w)a  Computes recall@k of the predictions with respect to sparse labels.

  If `class_id` is specified, we calculate recall by considering only the
      entries in the batch for which `class_id` is in the label, and computing
      the fraction of them for which `class_id` is in the top-k `predictions`.
  If `class_id` is not specified, we'll calculate recall as how often on
      average a class among the labels of a batch entry is in the top-k
      `predictions`.

  `sparse_recall_at_k` creates two local variables,
  `true_positive_at_<k>` and `false_negative_at_<k>`, that are used to compute
  the recall_at_k frequency. This frequency is ultimately returned as
  `recall_at_<k>`: an idempotent operation that simply divides
  `true_positive_at_<k>` by total (`true_positive_at_<k>` +
  `false_negative_at_<k>`).

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `recall_at_<k>`. Internally, a `top_k` operation computes a `Tensor`
  indicating the top `k` `predictions`. Set operations applied to `top_k` and
  `labels` calculate the true positives and false negatives weighted by
  `weights`. Then `update_op` increments `true_positive_at_<k>` and
  `false_negative_at_<k>` using these values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions`. Values
      should be in range [0, num_classes), where num_classes is the last
      dimension of `predictions`. Values outside this range always count
      towards `false_negative_at_<k>`.
    predictions: Float `Tensor` with shape [D1, ... DN, num_classes] where
      N >= 1. Commonly, N=1 and predictions has shape [batch size, num_classes].
      The final dimension contains the logit values for each class. [D1, ... DN]
      must match `labels`.
    k: Integer, k for @k metric.
    class_id: Integer class ID for which we want binary metrics. This should be
      in range [0, num_classes), where num_classes is the last dimension of
      `predictions`. If class_id is outside this range, the method returns NAN.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    metrics_collections: An optional list of collections that values should
      be added to.
    updates_collections: An optional list of collections that updates should
      be added to.
    name: Name of new update operation, and namespace for other dependent ops.

  Returns:
    recall: Scalar `float64` `Tensor` with the value of `true_positives` divided
      by the sum of `true_positives` and `false_negatives`.
    update_op: `Operation` that increments `true_positives` and
      `false_negatives` variables appropriately, and whose value matches
      `recall`.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match
    `predictions`, or if either `metrics_collections` or `updates_collections`
    are not a list or tuple.
    RuntimeError: If eager execution is enabled.
  zHtf.metrics.recall_at_k is not supported when eager execution is enabled.r  r  rQ   r  r  r  r:   r   r   r'   N)	r   r   r   r   rf   r  r   top_krecall_at_top_krQ   rP   r  r  r:   r   r   r'   r`   r   	top_k_idxs              r   recall_at_kr  g
  s    V  
 D E E ~~dJxXF"FG46 9>88K+LAy!
//     ,A<<Bzmetrics.recall_at_top_kc                    t        j                  |t        d||      || |f      5 t        | |      } t	        j
                  |t        j                        }t        || |||      \  }	}
t        || |||      \  }}fd}t        |||	|      }t	        j                  |
t	        j                  |
|      d      }|rt        j                  ||       ||fcddd       S # 1 sw Y   yxY w)aK	  Computes recall@k of top-k predictions with respect to sparse labels.

  Differs from `recall_at_k` in that predictions must be in the form of top `k`
  class indices, whereas `recall_at_k` expects logits. Refer to `recall_at_k`
  for more details.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions`. Values
      should be in range [0, num_classes), where num_classes is the last
      dimension of `predictions`. Values outside this range always count
      towards `false_negative_at_<k>`.
    predictions_idx: Integer `Tensor` with shape [D1, ... DN, k] where N >= 1.
      Commonly, N=1 and predictions has shape [batch size, k]. The final
      dimension contains the top `k` predicted class indices. [D1, ... DN] must
      match `labels`.
    k: Integer, k for @k metric. Only used for the default op name.
    class_id: Integer class ID for which we want binary metrics. This should be
      in range [0, num_classes), where num_classes is the last dimension of
      `predictions`. If class_id is outside this range, the method returns NAN.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    metrics_collections: An optional list of collections that values should
      be added to.
    updates_collections: An optional list of collections that updates should
      be added to.
    name: Name of new update operation, and namespace for other dependent ops.

  Returns:
    recall: Scalar `float64` `Tensor` with the value of `true_positives` divided
      by the sum of `true_positives` and `false_negatives`.
    update_op: `Operation` that increments `true_positives` and
      `false_negatives` variables appropriately, and whose value matches
      `recall`.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match
    `predictions`, or if either `metrics_collections` or `updates_collections`
    are not a list or tuple.
  r  r  r  rQ   r  r  r:   c                 \    t        j                  |t        j                  ||            S Nrc   r   r  add)r   r   r   r`   s      r   r  z'recall_at_top_k.<locals>.compute_recall  !    __Rb"!5EBBr!   r  rc   N)r   rf   r  rm   r   rw   r   rx   r  r  r   r  r  r   )rQ   r  r  r  r:   r   r   r'   r  r   	tp_updater   	fn_updater  metricr  r`   s                   @r   r  r  
  s    l ~~dJxXF&8: =B!&/:Fov||<I8!
MB	 :!
MB	C (^R5F __8<<	95HFF	0&96>7  s   B1C##C,zmetrics.recall_at_thresholdsc                 T   t        j                         rt        d      t        j                  |d|| |f      5  t	        | |||d      \  }}dfdfd}	t        ||	|      }
 |d   |d	   d
      }|rt        j                  ||       |
|fcddd       S # 1 sw Y   yxY w)aM  Computes various recall values for different `thresholds` on `predictions`.

  The `recall_at_thresholds` function creates four local variables,
  `true_positives`, `true_negatives`, `false_positives` and `false_negatives`
  for various values of thresholds. `recall[i]` is defined as the total weight
  of values in `predictions` above `thresholds[i]` whose corresponding entry in
  `labels` is `True`, divided by the total weight of `True` values in `labels`
  (`true_positives[i] / (true_positives[i] + false_negatives[i])`).

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the `recall`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    thresholds: A python list or tuple of float thresholds in `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that `recall` should be
      added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    recall: A float `Tensor` of shape `[len(thresholds)]`.
    update_op: An operation that increments the `true_positives`,
      `true_negatives`, `false_positives` and `false_negatives` variables that
      are used in the computation of `recall`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zQtf.metrics.recall_at_thresholds is not supported when eager execution is enabled.recall_at_thresholds)r   r   rv  r   c                 F    t        j                  | | z   |z   d|z         S )Nrecall_rc   ry  )r   r   r'   r
  s      r   r  z,recall_at_thresholds.<locals>.compute_recallV  s$    __R2!2T9IJJr!   c                 $     |d   |d   d      S )Nr   r   r   r<   )r   r   r  s     r   recall_across_replicasz4recall_at_thresholds.<locals>.recall_across_replicasY  s    F4L&,@@r!   r   r   r~   Nr|  )rQ   rP   r   r:   r   r   r'   r   r   r  r  r~   r  r
  s               @@r   r  r    s    d  
 D E E $$T+A&167%CE 8Z<IFJ GKA %3V=C z$/D1A;OI	0)<	>+  r}  zmetrics.root_mean_squared_errorc           	         t        j                         rt        d      t        || |      \  }} }t	        | ||dd|xs d      \  }}d }t        |||      }	t        j                  |      }
|rt        j                  ||
       |	|
fS )aw  Computes the root mean squared error between the labels and predictions.

  The `root_mean_squared_error` function creates two local variables,
  `total` and `count` that are used to compute the root mean squared error.
  This average is weighted by `weights`, and it is ultimately returned as
  `root_mean_squared_error`: an idempotent operation that takes the square root
  of the division of `total` by `count`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `root_mean_squared_error`. Internally, a `squared_error` operation computes
  the element-wise square of the difference between `predictions` and `labels`.
  Then `update_op` increments `total` with the reduced sum of the product of
  `weights` and `squared_error`, and it increments `count` with the reduced sum
  of `weights`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: A `Tensor` of the same shape as `predictions`.
    predictions: A `Tensor` of arbitrary shape.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    metrics_collections: An optional list of collections that
      `root_mean_squared_error` should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    root_mean_squared_error: A `Tensor` representing the current mean, the value
      of `total` divided by `count`.
    update_op: An operation that increments the `total` and `count` variables
      appropriately and whose value matches `root_mean_squared_error`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, or if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      either `metrics_collections` or `updates_collections` are not a list or
      tuple.
    RuntimeError: If eager execution is enabled.
  zTtf.metrics.root_mean_squared_error is not supported when eager execution is enabled.r   Nroot_mean_squared_errorc                 ,    t        j                  |      S r   )r   sqrt)r   mses     r   r    z)root_mean_squared_error.<locals>.<lambda>  s    c(: r!   )
r   r   r   rW   r=  r   r   r  r   r   )rQ   rP   r:   r   r   r'   r  update_mse_oprp  rmseupdate_rmse_ops              r   r  r  f  s    d  
 D E E "?fg"?+vw)&+w*. 1D*CE#} ;	#/
6$ ==/..?	~	r!   z"metrics.sensitivity_at_specificityc                    t        j                         rt        d      dk  sdkD  rt        d d      t	        j                  |d|| |f      5  dt        |dz
        D cg c]  }|dz   d	z  |dz
  z   }	}d
z
  g|	z   d	z   gz   }	t        | ||	|      \  }
}fdfd}t        |||
      } |d   |d   |d   |d   d      }|rt        j                  ||       ||fcddd       S c c}w # 1 sw Y   yxY w)a	  Computes the specificity at a given sensitivity.

  The `sensitivity_at_specificity` function creates four local
  variables, `true_positives`, `true_negatives`, `false_positives` and
  `false_negatives` that are used to compute the sensitivity at the given
  specificity value. The threshold for the given specificity value is computed
  and used to evaluate the corresponding sensitivity.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `sensitivity`. `update_op` increments the `true_positives`, `true_negatives`,
  `false_positives` and `false_negatives` counts with the weight of each case
  found in the `predictions` and `labels`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  For additional information about specificity and sensitivity, see the
  following: https://en.wikipedia.org/wiki/Sensitivity_and_specificity

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    specificity: A scalar value in range `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    num_thresholds: The number of thresholds to use for matching the given
      specificity.
    metrics_collections: An optional list of collections that `sensitivity`
      should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    sensitivity: A scalar `Tensor` representing the sensitivity at the given
      `specificity` value.
    update_op: An operation that increments the `true_positives`,
      `true_negatives`, `false_positives` and `false_negatives` variables
      appropriately and whose value matches `sensitivity`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      `specificity` is not between 0 and 1, or if either `metrics_collections`
      or `updates_collections` are not a list or tuple.
    RuntimeError: If eager execution is enabled.
  zWtf.metrics.sensitivity_at_specificity is not supported when eager execution is enabled.r   r2   zH`specificity` must be in the range [0, 1]. Currently, `specificity` got .sensitivity_at_specificityr   r   r   r   c                 (   t        j                  |||z   z         }t        j                  t        j                  |z
        d      }t        j                  |t
        j                        }t        j                  | |   | |   ||   z   z   |      S rk  )r   r  argminr  rw   r   int32)	r   r   r   r   r'   specificitiestf_indexr  specificitys	          r   "compute_sensitivity_at_specificityzFsensitivity_at_specificity.<locals>.compute_sensitivity_at_specificity  s    oob"r'H*<=mmk.I!JANhx6h __R\\BxL88CTK Kr!   c                 4     |d   |d   |d   |d   d      S Nr   r   r   r   r   r<   )r   r   r  s     r   sensitivity_across_replicasz?sensitivity_at_specificity.<locals>.sensitivity_across_replicas  -    /
,tfTlF4L'K Kr!   r   r   r   r   r~   N
r   r   r   rk   r   r  r   r   r   r   )rQ   rP   r  r:   r   r   r   r'   r  r   r   r   r  sensitivityr~   r  r  s     `            @@r   r  r    sq   v  
 D E E 1_a
 **5a9 : : $$T+G&167%CE !"H6;NQ<N6O12Q#!+,J  .!J.#.1AAJ8Z2FJKK -8&BK 34*T*Jt,<j>NI 	0)<	!C!" !"!" !"   C;)C6>A.C;6C;;Dc           
         |dk  rt        d| d      t        j                  |d| ||f      5 }t        j                  |       } t        | t        j                        r|dk  r8t        j                  t        j                  | j                        |z   dg      }n|g}t        j                  t        j                  | j                  dg|      dgt        j                  | j                  |dg      fdd      }t        j                  | |d	
      }|dk(  r|cddd       S t        j                  |dk  r|dz
  n||g|z  |      cddd       S t        j                   | |dk\  r|n|dz
  d	      }|dk(  r|cddd       S t        j"                  t        j$                  |             }t        j                  |d| |f||d fdd      }	t        j&                  ||	|      cddd       S # 1 sw Y   yxY w)a/  Slice `tensor` shape in 2, then tile along the sliced dimension.

  A new dimension is inserted in shape of `tensor` before `dim`, then values are
  tiled `multiple` times along the new dimension.

  Args:
    tensor: Input `Tensor` or `SparseTensor`.
    multiple: Integer, number of times to tile.
    dim: Integer, dimension along which to tile.
    name: Name of operation.

  Returns:
    `Tensor` result of expanding and tiling `tensor`.

  Raises:
    ValueError: if `multiple` is less than 1, or `dim` is not in
    `[-rank(tensor), rank(tensor)]`.
  r2   zInvalid argument multiple=z= for expand_and_tile  call. `multiple` must be an integer > 0expand_and_tiler   r3   expanded_shaperc   expandr[   N	multiples)rk   r   rf   r   rg   rh   ri   r   ry   rj   r^   r]   slicer   r\   sparse_concatr8   r   r   r   )
tensormultipler  r'   r`   r8   r  expandedr'  tile_multipless
             r   _expand_and_tiler    s	   & \
1( <P P Q Q
~~d-x-/ @27==fEF&-445	q''NN6--.4qc; e ''??6--sK@1#??6--{RDAC
	!n
 **
X7h	Q%@ @& %%1W#'#zH'<5J'@ @. $$qaxAH1}5@ @6 yv67D%%	dsh[$st*-q{DN>>(N?=@ @ @s   C*G/#%G/(G/A!G//G8c           
      F   |dk  rt        d|       t        j                  dd| f      5 }t        j                  |       } t        | t        j                        r4t        j                  t        j                  |       ||      cddd       S t        j                  t        j                  t        j                  | d      t        j                  |       t        j                   |             d      }t        j                  |||      cddd       S # 1 sw Y   yxY w)	a  Computes number of relevant values for each row in labels.

  For labels with shape [D1, ... DN, num_labels], this is the minimum of
  `num_labels` and `k`.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels].
    k: Integer, k for @k metric.

  Returns:
    Integer `Tensor` of shape [D1, ... DN], where each value is the number of
    relevant values for that row.

  Raises:
    ValueError: if inputs have invalid dtypes or values.
  r2   
Invalid k=Nnum_relevantrc   r   r3   )r  )rk   r   rf   r   rg   rh   ri   r   r  r   r  r   r   where_v2greater_equalr   r9  )rQ   r  r`   
num_labelss       r   _num_relevantr  K  s    ( U
z!%
&&
~~dNVI6 7%==fEF&-445dmmF3QUC	7 7 $$811&!<$..v6$//7	9 	J
 J67 7 7s   ADA=DD c                 H   t        j                  dd|| f      5 }t        j                  |t        j
                  d      }|j                         j                  dk(  rt        d      |j                         j                         d   }|t        d      t        | |      } t        j                  |dd	      }t        | |dd
      }t        ||d      }t        j                  |dd      }t        j                  t        j                   |      dd      }t        j"                  t        j                  |t        j$                        t        j                  |t        j$                        d      }	t        j&                  |	t        j                  |t        j$                        d      }
t        j(                  |
dd      }t        j                  t+        | |      t        j$                        }t        j"                  |||      cddd       S # 1 sw Y   yxY w)a  Computes average precision@k of predictions with respect to sparse labels.

  From en.wikipedia.org/wiki/Information_retrieval#Average_precision, formula
  for each row is:

    AveP = sum_{i=1...k} P_{i} * rel_{i} / num_relevant_items

  A "row" is the elements in dimension [D1, ... DN] of `predictions_idx`,
  `labels`, and the result `Tensors`. In the common case, this is [batch_size].
  Each row of the results contains the average precision for that row.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions_idx`.
      Values should be non-negative. Negative values are ignored.
    predictions_idx: Integer `Tensor` with shape [D1, ... DN, k] where N >= 1.
      Commonly, N=1 and `predictions_idx` has shape [batch size, k]. The final
      dimension must be set and contains the top `k` predicted class indices.
      [D1, ... DN] must match `labels`. Values should be in range
      [0, num_classes).

  Returns:
    `float64` `Tensor` of shape [D1, ... DN], where each value is the average
    precision for that row.

  Raises:
    ValueError: if the last dimension of predictions_idx is not set.
  Naverage_precisionr  rc   r   z1The rank of `predictions_idx` must be at least 1.r3   zIThe last dimension of predictions_idx must be set. Currently, it is None.predictions_idx_per_klabels_per_k)r  r  r'   relevant_per_ktp_per_k)r  r'   retrieved_per_kprecision_per_krelevant_precision_per_k)r3   precision_sum)r   rf   r   rw   r   rx   rJ   rL   rk   r   rm   r   r8   r  r  cumsumr   r  rv   r   r   r  )rQ   r  r`   r  r  r  r  r  r  r  r  r   num_relevant_itemss                r   "_sparse_average_precision_at_top_kr  q  s   @ ~~d/&/1 7J49mm,=?O  "((A-JKK!!#++-b1Ay 0 1 1!&/:F
 &11"9; $9L 0+2BDN~BZHHooN+";LNOooh/ov~~6 O  (00nfnn5' ) '' u?DM
 "}VQ'?P??=*<5Io7J 7J 7Js   G4HH!c                    t        j                  |d|| |f      5 }t        ||       }|Nt        j                  t        j                  |t        j                        |      }t        j                  ||      }t        j                  dd|f      5 }t        g t        j                  |      }	|:t        j                  t        j                  |d      t        j                        }
nt        j                  |d      }
t        j                  |	|
d      }ddd       t        j                  dd|f      5 }t        g t        j                  |      }t        j                  |d	      }t        j                  ||d      }ddd       d
 }t!        ||	      }t#        |      }|rt        j$                  ||       ||fcddd       S # 1 sw Y   xY w# 1 sw Y   YxY w# 1 sw Y   yxY w)aX	  Computes average precision@k of predictions with respect to sparse labels.

  `sparse_average_precision_at_top_k` creates two local variables,
  `average_precision_at_<k>/total` and `average_precision_at_<k>/max`, that
  are used to compute the frequency. This frequency is ultimately returned as
  `average_precision_at_<k>`: an idempotent operation that simply divides
  `average_precision_at_<k>/total` by `average_precision_at_<k>/max`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `precision_at_<k>`. Set operations applied to `top_k` and `labels` calculate
  the true positives and false positives weighted by `weights`. Then `update_op`
  increments `true_positive_at_<k>` and `false_positive_at_<k>` using these
  values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions_idx`.
      Values should be non-negative. Negative values are ignored.
    predictions_idx: Integer `Tensor` with shape [D1, ... DN, k] where N >= 1.
      Commonly, N=1 and `predictions_idx` has shape [batch size, k]. The final
      dimension contains the top `k` predicted class indices. [D1, ... DN] must
      match `labels`. Values should be in range [0, num_classes).
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    metrics_collections: An optional list of collections that values should
      be added to.
    updates_collections: An optional list of collections that updates should
      be added to.
    name: Name of new update operation, and namespace for other dependent ops.

  Returns:
    mean_average_precision: Scalar `float64` `Tensor` with the mean average
      precision values.
    update: `Operation` that increments variables appropriately, and whose
      value matches `metric`.
  average_precision_at_top_k)r  rQ   Nmaxrc   	batch_maxr  r   batch_totalc                     t        ||d      S )Nr   rc   )rs   )r   	total_varmax_vars      r   r{  zO_streaming_sparse_average_precision_at_top_k.<locals>.precision_across_replicas  s    iv>>r!   )r   rf   r  r   r   r   rw   r   rv   r   r0   r   rj   r   r   rz   r   rs   r   )rQ   r  r:   r   r   r'   r`   r  	max_scoper  r  
max_updatetotal_scoper
  r  total_updater{  mean_average_precisionr  s                      r   ,_streaming_sparse_average_precision_at_top_kr    s   d ~~d8&8: (*=B:'8%77
--
02CEg"++,=wG 
e&7%9	: Ki
  FNNCg	MMNN,;?Q	 ''kB	''JjK 
g(9';	< Q!"fnn;Gi''(9Nk)))[xPlQ? 86	7L lJUCF	0&9!6)Q(* (*K KQ Q1(* (*s?   A6G)BG G)9AGAG)G	G)G&	"G))G2c                       fdfd fd}t        j                          r j                  n       }t        j                  t        j                  |      | fd      S )a  Replaces large out-of-range labels by small out-of-range labels.

  Replaces any value in `labels` that is greater or equal to `num_classes` by
  -1. Do this conditionally for efficiency in case there are no such values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor`.
    num_classes: `int64` scalar `Tensor`.
  Returns:
    An `int64` `Tensor` or `SparseTensor` as `labels` with indices greater
    or equal to num_classes replaced by -1.
  c                  X    t         t        j                  t        j                  f      S )z,Returns true is `labels` is a sparse tensor.)rh   r   ri   SparseTensorValuerb   s   r   _labels_is_sparsez6_clean_out_of_range_indices.<locals>._labels_is_sparse6  s+    f}99,>>@ A Ar!   c                     t        j                  t        j                  |       dt        j                  |       z  |       S )z/Replaces by -1 any large out-of-range `values`.r3   )r   r  r   r  r   )r   r{   s    r   _clean_out_of_rangez8_clean_out_of_range_indices.<locals>._clean_out_of_range;  s<    h44V[I 9#6#6v#>>H Hr!   c                              r8 t              j                    j                        j                        S         S )z9Replaces by -1 ane large out-of-range values in `labels`.r  )typer  r   r^   )r  r  rQ   s   r   _clean_labels_out_of_rangez?_clean_out_of_range_indices.<locals>._clean_labels_out_of_range@  sD    T&\&..!4V]]!C&,&8&8: : !((r!   c                       S r   r<   rb   s   r   r    z-_clean_out_of_range_indices.<locals>.<lambda>N  s    f r!   )r   
reduce_maxr   r   r  )rQ   r{   r  
max_labelsr  r  s   ``  @@r   _clean_out_of_range_indicesr  (  s[    A
H
) ""(*fmm8*	Z5 
 r!   z%metrics.sparse_average_precision_at_kz"Use average_precision_at_k insteadc           	      &    t        | ||||||      S )zDRenamed to `average_precision_at_k`, please use that method instead.rQ   rP   r  r:   r   r   r'   )average_precision_at_kr   s          r   sparse_average_precision_at_kr"  Q  s&     
 	--
 r!   zmetrics.average_precision_at_kc           	         t        j                         rt        d      |dk  rt        d| d      t	        j
                  |t        d|      || |f      5 }t        j                  ||      \  }}	t        | t        j                  t        j                  |      d   t        j                              } t!        | |	||||      cddd       S # 1 sw Y   yxY w)	a
  Computes average precision@k of predictions with respect to sparse labels.

  `average_precision_at_k` creates two local variables,
  `average_precision_at_<k>/total` and `average_precision_at_<k>/max`, that
  are used to compute the frequency. This frequency is ultimately returned as
  `average_precision_at_<k>`: an idempotent operation that simply divides
  `average_precision_at_<k>/total` by `average_precision_at_<k>/max`.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `precision_at_<k>`. Internally, a `top_k` operation computes a `Tensor`
  indicating the top `k` `predictions`. Set operations applied to `top_k` and
  `labels` calculate the true positives and false positives weighted by
  `weights`. Then `update_op` increments `true_positive_at_<k>` and
  `false_positive_at_<k>` using these values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions`. Values
      should be in range [0, num_classes), where num_classes is the last
      dimension of `predictions`. Values outside this range are ignored.
    predictions: Float `Tensor` with shape [D1, ... DN, num_classes] where
      N >= 1. Commonly, N=1 and `predictions` has shape
      [batch size, num_classes]. The final dimension contains the logit values
      for each class. [D1, ... DN] must match `labels`.
    k: Integer, k for @k metric. This will calculate an average precision for
      range `[1,k]`, as documented above.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    metrics_collections: An optional list of collections that values should
      be added to.
    updates_collections: An optional list of collections that updates should
      be added to.
    name: Name of new update operation, and namespace for other dependent ops.

  Returns:
    mean_average_precision: Scalar `float64` `Tensor` with the mean average
      precision values.
    update: `Operation` that increments variables appropriately, and whose
      value matches `metric`.

  Raises:
    ValueError: if k is invalid.
    RuntimeError: If eager execution is enabled.
  zZtf.metrics.sparse_average_precision_at_k is not supported when eager execution is enabled.r2   r  z. `k` should be >= 1.r  r3   )rQ   r  r:   r   r   r'   N)r   r   r   rk   r   rf   r  r   r  r  r   rw   r   r   r   rx   r  )
rQ   rP   r  r:   r   r   r'   r`   r   r  s
             r   r!  r!  e  s    x  
 D E E U
z!$9:
;;
~~dJ':A>"FG46 9>+q1A
 )iook:2>MOF7'//  s   A.CCc                    t        j                  dd|| |f      5  t        | ||      \  } }t        j                  t        j
                  || d            }t        j                  |t        j                        }|mt        j                  t        j                  ||      f      5  t        j                  |t        j                        }t        j                  ||      }ddd       |cddd       S # 1 sw Y   xY w# 1 sw Y   yxY w)a~  Calculates false positives for precision@k.

  If `class_id` is specified, calculate binary true positives for `class_id`
      only.
  If `class_id` is not specified, calculate metrics for `k` predicted vs
      `n` label classes, where `n` is the 2nd dimension of `labels_sparse`.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: 1-D or higher `int64` `Tensor` with last dimension `k`,
      top `k` predicted classes. For rank `n`, the first `n-1` dimensions must
      match `labels`.
    class_id: Class for which we want binary metrics.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).

  Returns:
    A [D1, ... DN] `Tensor` of false positive counts.
  Nr   Tr  r  )rQ   r  r  r:   r   s        r   _sparse_false_positive_at_kr%    s    : ~~d-&8: 4V_5=?FO	OVTB
DB	r6>>	*B##%:%O%O
2& %  ,--8r7+,  , , r  c                 r   t        j                  |t        d||      || |f      5 }t        || ||      }t	        j
                  t	        j                  |      t        j                        }t        g t        j                  |      }	|	t        j                  |	|d      fcddd       S # 1 sw Y   yxY w)a  Calculates weighted per step false positives for precision@k.

  If `class_id` is specified, calculate binary true positives for `class_id`
      only.
  If `class_id` is not specified, calculate metrics for `k` predicted vs
      `n` label classes, where `n` is the 2nd dimension of `labels`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels], where N >= 1 and num_labels is the number of
      target classes for the associated prediction. Commonly, N=1 and `labels`
      has shape [batch_size, num_labels]. [D1, ... DN] must match
      `predictions_idx`.
    predictions_idx: 1-D or higher `int64` `Tensor` with last dimension `k`,
      top `k` predicted classes. For rank `n`, the first `n-1` dimensions must
      match `labels`.
    k: Integer, k for @k metric. This is only used for default op name.
    class_id: Class for which we want binary metrics.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    name: Name of new variable, and namespace for other dependent ops.

  Returns:
    A tuple of `Variable` and update `Operation`.

  Raises:
    ValueError: If `weights` is not `None` and has an incompatible shape.
  false_positiver  r  rc   r  N)r   rf   r  r%  r   rw   r   r   rv   r0   r   rz   )
rQ   r  r  r  r:   r'   r`   r   batch_total_fpr  s
             r   %_streaming_sparse_false_positive_at_kr)    r  r  zmetrics.precision_at_top_kc                    t        j                         rt        d      t        j                  |t        d||      || |f      5 t        | |      } t        j                  |t        j                        }t        || |||      \  }	}
t        || |||      \  }}fd}t        |||	|      }t        j                  |
t        j                  |
|      d      }|rt        j                   ||       ||fcddd       S # 1 sw Y   yxY w)	a	  Computes precision@k of the predictions with respect to sparse labels.

  Differs from `sparse_precision_at_k` in that predictions must be in the form
  of top `k` class indices, whereas `sparse_precision_at_k` expects logits.
  Refer to `sparse_precision_at_k` for more details.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions`. Values
      should be in range [0, num_classes), where num_classes is the last
      dimension of `predictions`. Values outside this range are ignored.
    predictions_idx: Integer `Tensor` with shape [D1, ... DN, k] where
      N >= 1. Commonly, N=1 and predictions has shape [batch size, k].
      The final dimension contains the top `k` predicted class indices.
      [D1, ... DN] must match `labels`.
    k: Integer, k for @k metric. Only used for the default op name.
    class_id: Integer class ID for which we want binary metrics. This should be
      in range [0, num_classes], where num_classes is the last dimension of
      `predictions`. If `class_id` is outside this range, the method returns
      NAN.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    metrics_collections: An optional list of collections that values should
      be added to.
    updates_collections: An optional list of collections that updates should
      be added to.
    name: Name of new update operation, and namespace for other dependent ops.

  Returns:
    precision: Scalar `float64` `Tensor` with the value of `true_positives`
      divided by the sum of `true_positives` and `false_positives`.
    update_op: `Operation` that increments `true_positives` and
      `false_positives` variables appropriately, and whose value matches
      `precision`.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match
      `predictions`, or if either `metrics_collections` or `updates_collections`
      are not a list or tuple.
    RuntimeError: If eager execution is enabled.
  zOtf.metrics.precision_at_top_k is not supported when eager execution is enabled.rh  r  r  c                 \    t        j                  |t        j                  ||            S r  r  )r   r   r   r`   s      r   r{  z5precision_at_top_k.<locals>.precision_across_replicase  r  r!   r  rc   N)r   r   r   r   rf   r  rm   r   rw   r   rx   r  r)  r   r  r  r   )rQ   r  r  r  r:   r   r   r'   r  r   r  r   	fp_updater{  r  r  r`   s                   @r   precision_at_top_kr-    s   n  
 D E E ~~dJ{AI&8: =B!&/:Fov||<I8!
MB	 :!
MB	C (6B@F __8<<	95HFF	0&96>7  s   B1DDzmetrics.sparse_precision_at_kzUse precision_at_k insteadc           
      (    t        | |||||||      S )z<Renamed to `precision_at_k`, please use that method instead.rQ   rP   r  r  r:   r   r   r'   )precision_at_kr/  s           r   sparse_precision_at_kr1  r  s)     
	--
 r!   zmetrics.precision_at_kc                    t        j                         rt        d      t        j                  |t        d||      || |f      5 }t        j                  ||      \  }	}
t        | |
||||||      cddd       S # 1 sw Y   yxY w)a$  Computes precision@k of the predictions with respect to sparse labels.

  If `class_id` is specified, we calculate precision by considering only the
      entries in the batch for which `class_id` is in the top-k highest
      `predictions`, and computing the fraction of them for which `class_id` is
      indeed a correct label.
  If `class_id` is not specified, we'll calculate precision as how often on
      average a class among the top-k classes with the highest predicted values
      of a batch entry is correct and can be found in the label for that entry.

  `precision_at_k` creates two local variables,
  `true_positive_at_<k>` and `false_positive_at_<k>`, that are used to compute
  the precision@k frequency. This frequency is ultimately returned as
  `precision_at_<k>`: an idempotent operation that simply divides
  `true_positive_at_<k>` by total (`true_positive_at_<k>` +
  `false_positive_at_<k>`).

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `precision_at_<k>`. Internally, a `top_k` operation computes a `Tensor`
  indicating the top `k` `predictions`. Set operations applied to `top_k` and
  `labels` calculate the true positives and false positives weighted by
  `weights`. Then `update_op` increments `true_positive_at_<k>` and
  `false_positive_at_<k>` using these values.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  Args:
    labels: `int64` `Tensor` or `SparseTensor` with shape
      [D1, ... DN, num_labels] or [D1, ... DN], where the latter implies
      num_labels=1. N >= 1 and num_labels is the number of target classes for
      the associated prediction. Commonly, N=1 and `labels` has shape
      [batch_size, num_labels]. [D1, ... DN] must match `predictions`. Values
      should be in range [0, num_classes), where num_classes is the last
      dimension of `predictions`. Values outside this range are ignored.
    predictions: Float `Tensor` with shape [D1, ... DN, num_classes] where
      N >= 1. Commonly, N=1 and predictions has shape [batch size, num_classes].
      The final dimension contains the logit values for each class. [D1, ... DN]
      must match `labels`.
    k: Integer, k for @k metric.
    class_id: Integer class ID for which we want binary metrics. This should be
      in range [0, num_classes], where num_classes is the last dimension of
      `predictions`. If `class_id` is outside this range, the method returns
      NAN.
    weights: `Tensor` whose rank is either 0, or n-1, where n is the rank of
      `labels`. If the latter, it must be broadcastable to `labels` (i.e., all
      dimensions must be either `1`, or the same as the corresponding `labels`
      dimension).
    metrics_collections: An optional list of collections that values should
      be added to.
    updates_collections: An optional list of collections that updates should
      be added to.
    name: Name of new update operation, and namespace for other dependent ops.

  Returns:
    precision: Scalar `float64` `Tensor` with the value of `true_positives`
      divided by the sum of `true_positives` and `false_positives`.
    update_op: `Operation` that increments `true_positives` and
      `false_positives` variables appropriately, and whose value matches
      `precision`.

  Raises:
    ValueError: If `weights` is not `None` and its shape doesn't match
      `predictions`, or if either `metrics_collections` or `updates_collections`
      are not a list or tuple.
    RuntimeError: If eager execution is enabled.
  zRtf.metrics.sparse_precision_at_k is not supported when eager execution is enabled.rh  r  r  N)	r   r   r   r   rf   r  r   r  r-  r  s              r   r0  r0    s    X  
 D E E ~~dJ{AI"FG46 9>88K+LAy!
//  r  z"metrics.specificity_at_sensitivityc                    t        j                         rt        d      dk  sdkD  rt        d d      t	        j                  |d|| |f      5  dt        |dz
        D cg c]  }|dz   d	z  |dz
  z   }	}d
z
  g|	z   d	z
  gz   }	t        | ||	|      \  }
}fdfd}t        |||
      } |d   |d   |d   |d   d      }|rt        j                  ||       ||fcddd       S c c}w # 1 sw Y   yxY w)a	  Computes the specificity at a given sensitivity.

  The `specificity_at_sensitivity` function creates four local
  variables, `true_positives`, `true_negatives`, `false_positives` and
  `false_negatives` that are used to compute the specificity at the given
  sensitivity value. The threshold for the given sensitivity value is computed
  and used to evaluate the corresponding specificity.

  For estimation of the metric over a stream of data, the function creates an
  `update_op` operation that updates these variables and returns the
  `specificity`. `update_op` increments the `true_positives`, `true_negatives`,
  `false_positives` and `false_negatives` counts with the weight of each case
  found in the `predictions` and `labels`.

  If `weights` is `None`, weights default to 1. Use weights of 0 to mask values.

  For additional information about specificity and sensitivity, see the
  following: https://en.wikipedia.org/wiki/Sensitivity_and_specificity

  Args:
    labels: The ground truth values, a `Tensor` whose dimensions must match
      `predictions`. Will be cast to `bool`.
    predictions: A floating point `Tensor` of arbitrary shape and whose values
      are in the range `[0, 1]`.
    sensitivity: A scalar value in range `[0, 1]`.
    weights: Optional `Tensor` whose rank is either 0, or the same rank as
      `labels`, and must be broadcastable to `labels` (i.e., all dimensions must
      be either `1`, or the same as the corresponding `labels` dimension).
    num_thresholds: The number of thresholds to use for matching the given
      sensitivity.
    metrics_collections: An optional list of collections that `specificity`
      should be added to.
    updates_collections: An optional list of collections that `update_op` should
      be added to.
    name: An optional variable_scope name.

  Returns:
    specificity: A scalar `Tensor` representing the specificity at the given
      `sensitivity` value.
    update_op: An operation that increments the `true_positives`,
      `true_negatives`, `false_positives` and `false_negatives` variables
      appropriately and whose value matches `specificity`.

  Raises:
    ValueError: If `predictions` and `labels` have mismatched shapes, if
      `weights` is not `None` and its shape doesn't match `predictions`, or if
      `sensitivity` is not between 0 and 1, or if either `metrics_collections`
      or `updates_collections` are not a list or tuple.
    RuntimeError: If eager execution is enabled.
  zWtf.metrics.specificity_at_sensitivity is not supported when eager execution is enabled.r   r2   zG`sensitivity` must be in the range [0, 1]. Currently, `sensitivity` is r  specificity_at_sensitivityr   r   r   r   c                    t        j                  | | |z   	z         }t        j                  t        j                  |
z
              }t        j                  t        j                  |
z
        |      }t        j
                  |t        j                        }t        j                  |      }t        j                  |d      }t        j
                  |t        j                        }t        j                  ||   ||   ||   z   	z   |      S )a&  Computes the specificity at the given sensitivity.

      Args:
        tp: True positives.
        tn: True negatives.
        fp: False positives.
        fn: False negatives.
        name: The name of the operation.

      Returns:
        The specificity using the aggregated values.
      r   )r   r  
reduce_minr  r>   rw   r   rx   r  argmaxr  )r   r   r   r   r'   sensitivitiesmin_valindices_at_minvalr  r  r  s            r   "compute_specificity_at_sensitivityzFspecificity_at_sensitivity.<locals>.compute_specificity_at_sensitivity4  s     oob"r'H*<=m ##HLL1L$MNg"..
,,}{2
3W>"--(96<<H"//*;<!2A6hx6h __R\\BxL88CTK Kr!   c                 4     |d   |d   |d   |d   d      S r  r<   )r   r   r;  s     r   specificity_across_replicasz?specificity_at_sensitivity.<locals>.specificity_across_replicasQ  r  r!   r   r   r   r   r~   Nr  )rQ   rP   r  r:   r   r   r   r'   r  r   r   r   r=  r  r~   r;  r  s     `            @@r   r4  r4    sq   v  
 D E E 1_a
 ))4Q8 9 9 $$T+G&167%CE 5"H6;NQ<N6O12Q#!+,J  .!J.#.1AAJ8Z2FJK:K -8&BK 34*T*Jt,<j>NI 	0)<	!k5" 5"5" 5"r  )TNr   )NNNN)NN)N   NNr   Nr   N)NNN)NNNNN)NNNNNN)Nr>  NNN)r   N)W__doc__tensorflow.python.distributer   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   tensorflow.python.opsr   r	   r
   r   r   r   r   r   r   r   r   r   r   r   tensorflow.python.platformr   r   "tensorflow.python.util.deprecationr    tensorflow.python.util.tf_exportr   r0   rW   rm   rs   r   r   r   r   r   r   r   r  r  r)  r+  r8  r=  rD  rJ  rO  r   rW  r   r]  r   ra  r   rf  rh  ru  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r"  r!  r%  r)  r-  r1  r0  r4  r<   r!   r   <module>rG     so   + 7 + . + 5 + 1 + & 2 * $ & , + 0 - + 7 < 9 6,^I&X1Oh@ .b F ~!!	b  bJ !"# !%!%X" $X"| -1-1	`F7
 }oDKL
   &f L f R ,-. !%,0,0!9B /9Bx -./ "&-1-1"F" 0F"R 012 %)0404!%e& 3e&P !"# !%!%c! $c!L ,-. !%,0,0!AB /ABH +,-  $+/+/ 9, .9,x $%&$($(	Q 'Qh )*+ ")-)-3I ,3In ")-)-+!\ ()* !(,(,01 +01f 678 +/6:6:'+4& 94&n ()* !(,(,11 +11h 678 +/6:6:'+4& 94&n '()  '+'+11 *11h 567 *.5959&*4& 84&n '()  '+'+11 *11h 567 *.5959&*4& 84&n "#$ "&"&[ %[| 012 %)0404!%M 3M`  ! ##Y "YxKD:2 )-'+$(	*^ ,02615.20Ij *.(,)^ 4826/30If $%& $($(Y 'Yx ()* ! (,(,P +Pf -./ "&-1-1"J 0JZ 012 %)0404!%C 3CL 345 (,.13737$(c" 6c"L4@n#7LWJx :>EIEI6:Z*z&R 678D67 +/6:6:'+ 8 9$ /01 $(/3/3 $Q 2Ql *.(,)\ -13726/30If +,-  $#+/+/ U .Up ./0D./ $("&.2.2# 0 1( '() !'+'+Z *Zz 345 (,.13737$(w" 6w"r!   