| from keras.src import backend |
| from keras.src import ops |
| from keras.src.api_export import keras_export |
| from keras.src.losses.loss import squeeze_or_expand_to_same_rank |
| from keras.src.metrics import reduction_metrics |
|
|
|
|
| def accuracy(y_true, y_pred): |
| y_pred = ops.convert_to_tensor(y_pred) |
| y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype) |
| y_true, y_pred = squeeze_or_expand_to_same_rank(y_true, y_pred) |
| return ops.cast(ops.equal(y_true, y_pred), dtype=backend.floatx()) |
|
|
|
|
| @keras_export("keras.metrics.Accuracy") |
| class Accuracy(reduction_metrics.MeanMetricWrapper): |
| """Calculates how often predictions equal labels. |
| |
| This metric creates two local variables, `total` and `count` that are used |
| to compute the frequency with which `y_pred` matches `y_true`. This |
| frequency is ultimately returned as `binary accuracy`: an idempotent |
| operation that simply divides `total` by `count`. |
| |
| If `sample_weight` is `None`, weights default to 1. |
| Use `sample_weight` of 0 to mask values. |
| |
| Args: |
| name: (Optional) string name of the metric instance. |
| dtype: (Optional) data type of the metric result. |
| |
| Examples: |
| |
| >>> m = keras.metrics.Accuracy() |
| >>> m.update_state([[1], [2], [3], [4]], [[0], [2], [3], [4]]) |
| >>> m.result() |
| 0.75 |
| |
| >>> m.reset_state() |
| >>> m.update_state([[1], [2], [3], [4]], [[0], [2], [3], [4]], |
| ... sample_weight=[1, 1, 0, 0]) |
| >>> m.result() |
| 0.5 |
| |
| Usage with `compile()` API: |
| |
| ```python |
| model.compile(optimizer='sgd', |
| loss='binary_crossentropy', |
| metrics=[keras.metrics.Accuracy()]) |
| ``` |
| """ |
|
|
| def __init__(self, name="accuracy", dtype=None): |
| super().__init__(fn=accuracy, name=name, dtype=dtype) |
| |
| self._direction = "up" |
|
|
| def get_config(self): |
| return {"name": self.name, "dtype": self.dtype} |
|
|
|
|
| @keras_export("keras.metrics.binary_accuracy") |
| def binary_accuracy(y_true, y_pred, threshold=0.5): |
| y_pred = ops.convert_to_tensor(y_pred) |
| y_true = ops.convert_to_tensor(y_true) |
| threshold = ops.convert_to_tensor(threshold) |
| y_true, y_pred = squeeze_or_expand_to_same_rank(y_true, y_pred) |
| y_pred = ops.cast(ops.greater(y_pred, threshold), y_true.dtype) |
| return ops.cast(ops.equal(y_true, y_pred), dtype=backend.floatx()) |
|
|
|
|
| @keras_export("keras.metrics.BinaryAccuracy") |
| class BinaryAccuracy(reduction_metrics.MeanMetricWrapper): |
| """Calculates how often predictions match binary labels. |
| |
| This metric creates two local variables, `total` and `count` that are used |
| to compute the frequency with which `y_pred` matches `y_true`. This |
| frequency is ultimately returned as `binary accuracy`: an idempotent |
| operation that simply divides `total` by `count`. |
| |
| If `sample_weight` is `None`, weights default to 1. |
| Use `sample_weight` of 0 to mask values. |
| |
| Args: |
| name: (Optional) string name of the metric instance. |
| dtype: (Optional) data type of the metric result. |
| threshold: (Optional) Float representing the threshold for deciding |
| whether prediction values are 1 or 0. |
| |
| Example: |
| |
| >>> m = keras.metrics.BinaryAccuracy() |
| >>> m.update_state([[1], [1], [0], [0]], [[0.98], [1], [0], [0.6]]) |
| >>> m.result() |
| 0.75 |
| |
| >>> m.reset_state() |
| >>> m.update_state([[1], [1], [0], [0]], [[0.98], [1], [0], [0.6]], |
| ... sample_weight=[1, 0, 0, 1]) |
| >>> m.result() |
| 0.5 |
| |
| Usage with `compile()` API: |
| |
| ```python |
| model.compile(optimizer='sgd', |
| loss='binary_crossentropy', |
| metrics=[keras.metrics.BinaryAccuracy()]) |
| ``` |
| """ |
|
|
| def __init__(self, name="binary_accuracy", dtype=None, threshold=0.5): |
| super().__init__( |
| fn=binary_accuracy, name=name, dtype=dtype, threshold=threshold |
| ) |
| self.threshold = threshold |
| |
| self._direction = "up" |
|
|
| def get_config(self): |
| return { |
| "name": self.name, |
| "dtype": self.dtype, |
| "threshold": self.threshold, |
| } |
|
|
|
|
| @keras_export("keras.metrics.categorical_accuracy") |
| def categorical_accuracy(y_true, y_pred): |
| y_true = ops.argmax(y_true, axis=-1) |
|
|
| reshape_matches = False |
| y_pred = ops.convert_to_tensor(y_pred) |
| y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype) |
|
|
| y_true_org_shape = ops.shape(y_true) |
| y_pred_rank = len(y_pred.shape) |
| y_true_rank = len(y_true.shape) |
|
|
| |
| if ( |
| (y_true_rank is not None) |
| and (y_pred_rank is not None) |
| and (len(y_true.shape) == len(y_pred.shape)) |
| ): |
| y_true = ops.squeeze(y_true, -1) |
| reshape_matches = True |
| y_pred = ops.argmax(y_pred, axis=-1) |
|
|
| |
| |
| if y_pred.dtype is not y_true.dtype: |
| y_pred = ops.cast(y_pred, dtype=y_true.dtype) |
| matches = ops.cast(ops.equal(y_true, y_pred), backend.floatx()) |
| if reshape_matches: |
| matches = ops.reshape(matches, y_true_org_shape) |
| return matches |
|
|
|
|
| @keras_export("keras.metrics.CategoricalAccuracy") |
| class CategoricalAccuracy(reduction_metrics.MeanMetricWrapper): |
| """Calculates how often predictions match one-hot labels. |
| |
| You can provide logits of classes as `y_pred`, since argmax of |
| logits and probabilities are same. |
| |
| This metric creates two local variables, `total` and `count` that are used |
| to compute the frequency with which `y_pred` matches `y_true`. This |
| frequency is ultimately returned as `categorical accuracy`: an idempotent |
| operation that simply divides `total` by `count`. |
| |
| `y_pred` and `y_true` should be passed in as vectors of probabilities, |
| rather than as labels. If necessary, use `ops.one_hot` to expand `y_true` as |
| a vector. |
| |
| If `sample_weight` is `None`, weights default to 1. |
| Use `sample_weight` of 0 to mask values. |
| |
| Args: |
| name: (Optional) string name of the metric instance. |
| dtype: (Optional) data type of the metric result. |
| |
| Example: |
| |
| >>> m = keras.metrics.CategoricalAccuracy() |
| >>> m.update_state([[0, 0, 1], [0, 1, 0]], [[0.1, 0.9, 0.8], |
| ... [0.05, 0.95, 0]]) |
| >>> m.result() |
| 0.5 |
| |
| >>> m.reset_state() |
| >>> m.update_state([[0, 0, 1], [0, 1, 0]], [[0.1, 0.9, 0.8], |
| ... [0.05, 0.95, 0]], |
| ... sample_weight=[0.7, 0.3]) |
| >>> m.result() |
| 0.3 |
| |
| Usage with `compile()` API: |
| |
| ```python |
| model.compile(optimizer='sgd', |
| loss='categorical_crossentropy', |
| metrics=[keras.metrics.CategoricalAccuracy()]) |
| ``` |
| """ |
|
|
| def __init__(self, name="categorical_accuracy", dtype=None): |
| super().__init__(fn=categorical_accuracy, name=name, dtype=dtype) |
| |
| self._direction = "up" |
|
|
| def get_config(self): |
| return {"name": self.name, "dtype": self.dtype} |
|
|
|
|
| @keras_export("keras.metrics.sparse_categorical_accuracy") |
| def sparse_categorical_accuracy(y_true, y_pred): |
| reshape_matches = False |
| y_pred = ops.convert_to_tensor(y_pred) |
| y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype) |
| y_true_org_shape = ops.shape(y_true) |
| y_pred_rank = len(y_pred.shape) |
| y_true_rank = len(y_true.shape) |
|
|
| |
| if ( |
| (y_true_rank is not None) |
| and (y_pred_rank is not None) |
| and (len(y_true.shape) == len(y_pred.shape)) |
| and ops.shape(y_true)[-1] == 1 |
| ): |
| y_true = ops.squeeze(y_true, -1) |
| reshape_matches = True |
| y_pred = ops.argmax(y_pred, axis=-1) |
|
|
| |
| |
| if y_pred.dtype is not y_true.dtype: |
| y_pred = ops.cast(y_pred, y_true.dtype) |
| matches = ops.cast(ops.equal(y_true, y_pred), backend.floatx()) |
| if reshape_matches: |
| matches = ops.reshape(matches, y_true_org_shape) |
| |
| if len(matches.shape) > 1 and matches.shape[-1] == 1: |
| matches = ops.squeeze(matches, -1) |
| return matches |
|
|
|
|
| @keras_export("keras.metrics.SparseCategoricalAccuracy") |
| class SparseCategoricalAccuracy(reduction_metrics.MeanMetricWrapper): |
| """Calculates how often predictions match integer labels. |
| |
| ```python |
| acc = np.dot(sample_weight, np.equal(y_true, np.argmax(y_pred, axis=1)) |
| ``` |
| |
| You can provide logits of classes as `y_pred`, since argmax of |
| logits and probabilities are same. |
| |
| This metric creates two local variables, `total` and `count` that are used |
| to compute the frequency with which `y_pred` matches `y_true`. This |
| frequency is ultimately returned as `sparse categorical accuracy`: an |
| idempotent operation that simply divides `total` by `count`. |
| |
| If `sample_weight` is `None`, weights default to 1. |
| Use `sample_weight` of 0 to mask values. |
| |
| Args: |
| name: (Optional) string name of the metric instance. |
| dtype: (Optional) data type of the metric result. |
| |
| Example: |
| |
| >>> m = keras.metrics.SparseCategoricalAccuracy() |
| >>> m.update_state([[2], [1]], [[0.1, 0.6, 0.3], [0.05, 0.95, 0]]) |
| >>> m.result() |
| 0.5 |
| |
| >>> m.reset_state() |
| >>> m.update_state([[2], [1]], [[0.1, 0.6, 0.3], [0.05, 0.95, 0]], |
| ... sample_weight=[0.7, 0.3]) |
| >>> m.result() |
| 0.3 |
| |
| Usage with `compile()` API: |
| |
| ```python |
| model.compile(optimizer='sgd', |
| loss='sparse_categorical_crossentropy', |
| metrics=[keras.metrics.SparseCategoricalAccuracy()]) |
| ``` |
| """ |
|
|
| def __init__(self, name="sparse_categorical_accuracy", dtype=None): |
| super().__init__(fn=sparse_categorical_accuracy, name=name, dtype=dtype) |
| |
| self._direction = "up" |
|
|
| def get_config(self): |
| return {"name": self.name, "dtype": self.dtype} |
|
|
|
|
| @keras_export("keras.metrics.top_k_categorical_accuracy") |
| def top_k_categorical_accuracy(y_true, y_pred, k=5): |
| reshape_matches = False |
| y_pred = ops.convert_to_tensor(y_pred) |
| y_true = ops.convert_to_tensor(y_true, dtype=y_pred.dtype) |
| y_true = ops.argmax(y_true, axis=-1) |
| y_true_rank = len(y_true.shape) |
| y_pred_rank = len(y_pred.shape) |
| y_true_org_shape = ops.shape(y_true) |
|
|
| |
| if (y_true_rank is not None) and (y_pred_rank is not None): |
| if y_pred_rank > 2: |
| y_pred = ops.reshape(y_pred, [-1, y_pred.shape[-1]]) |
| if y_true_rank > 1: |
| reshape_matches = True |
| y_true = ops.reshape(y_true, [-1]) |
|
|
| matches = ops.cast( |
| ops.in_top_k(ops.cast(y_true, "int32"), y_pred, k=k), |
| dtype=backend.floatx(), |
| ) |
|
|
| |
| if reshape_matches: |
| matches = ops.reshape(matches, y_true_org_shape) |
|
|
| return matches |
|
|
|
|
| @keras_export("keras.metrics.TopKCategoricalAccuracy") |
| class TopKCategoricalAccuracy(reduction_metrics.MeanMetricWrapper): |
| """Computes how often targets are in the top `K` predictions. |
| |
| Args: |
| k: (Optional) Number of top elements to look at for computing accuracy. |
| Defaults to `5`. |
| name: (Optional) string name of the metric instance. |
| dtype: (Optional) data type of the metric result. |
| |
| Example: |
| |
| >>> m = keras.metrics.TopKCategoricalAccuracy(k=1) |
| >>> m.update_state([[0, 0, 1], [0, 1, 0]], |
| ... [[0.1, 0.9, 0.8], [0.05, 0.95, 0]]) |
| >>> m.result() |
| 0.5 |
| |
| >>> m.reset_state() |
| >>> m.update_state([[0, 0, 1], [0, 1, 0]], |
| ... [[0.1, 0.9, 0.8], [0.05, 0.95, 0]], |
| ... sample_weight=[0.7, 0.3]) |
| >>> m.result() |
| 0.3 |
| |
| Usage with `compile()` API: |
| |
| ```python |
| model.compile(optimizer='sgd', |
| loss='categorical_crossentropy', |
| metrics=[keras.metrics.TopKCategoricalAccuracy()]) |
| ``` |
| """ |
|
|
| def __init__(self, k=5, name="top_k_categorical_accuracy", dtype=None): |
| super().__init__( |
| fn=top_k_categorical_accuracy, |
| name=name, |
| dtype=dtype, |
| k=k, |
| ) |
| self.k = k |
| |
| self._direction = "up" |
|
|
| def get_config(self): |
| return {"name": self.name, "dtype": self.dtype, "k": self.k} |
|
|
|
|
| @keras_export("keras.metrics.sparse_top_k_categorical_accuracy") |
| def sparse_top_k_categorical_accuracy( |
| y_true, y_pred, k=5, from_sorted_ids=False |
| ): |
| """Computes how often integer targets are in the top `K` predictions. |
| |
| Args: |
| y_true: A tensor of shape `(batch_size)` representing indices or IDs of |
| true categories. |
| y_pred: If `from_sorted_ids=False`, a tensor of shape |
| `(batch_size, num_categories)` containing the scores for each sample |
| for all possible categories. If `from_sorted_ids=True`, a tensor of |
| shape `(batch_size, N)` containing indices or IDs of the top `N` |
| categories in order from highest score to lowest score. |
| k: (Optional) Number of top elements to look at for computing accuracy. |
| Defaults to `5`. |
| from_sorted_ids: (Optional) Whether `y_pred` is sorted category IDs or |
| scores for all categories (the default). |
| |
| Returns: |
| A tensor with the same shape as `y_true` containing ones where `y_true` |
| is in the top `k` and zeros elsewhere. |
| """ |
| reshape_matches = False |
| y_pred = ops.convert_to_tensor(y_pred) |
| y_true_dtype = y_pred.dtype if from_sorted_ids else "int32" |
| y_true = ops.convert_to_tensor(y_true, dtype=y_true_dtype) |
| y_true_rank = len(y_true.shape) |
| y_pred_rank = len(y_pred.shape) |
| y_true_org_shape = ops.shape(y_true) |
|
|
| |
| if (y_true_rank is not None) and (y_pred_rank is not None): |
| if y_pred_rank > 2: |
| y_pred = ops.reshape(y_pred, [-1, y_pred.shape[-1]]) |
| if y_true_rank > 1: |
| reshape_matches = True |
| y_true = ops.reshape(y_true, [-1]) |
|
|
| if from_sorted_ids: |
| |
| |
| matches = ops.any( |
| ops.equal(ops.expand_dims(y_true, axis=1), y_pred[:, :k]), axis=1 |
| ) |
| else: |
| matches = ops.in_top_k(y_true, y_pred, k=k) |
|
|
| matches = ops.cast(matches, dtype=backend.floatx()) |
|
|
| |
| if reshape_matches: |
| matches = ops.reshape(matches, y_true_org_shape) |
|
|
| return matches |
|
|
|
|
| @keras_export("keras.metrics.SparseTopKCategoricalAccuracy") |
| class SparseTopKCategoricalAccuracy(reduction_metrics.MeanMetricWrapper): |
| """Computes how often integer targets are in the top `K` predictions. |
| |
| By default, the arguments expected by `update_state()` are: |
| - `y_true`: a tensor of shape `(batch_size)` representing indices of true |
| categories. |
| - `y_pred`: a tensor of shape `(batch_size, num_categories)` containing the |
| scores for each sample for all possible categories. |
| |
| With `from_sorted_ids=True`, the arguments expected by `update_state` are: |
| - `y_true`: a tensor of shape `(batch_size)` representing indices or IDs of |
| true categories. |
| - `y_pred`: a tensor of shape `(batch_size, N)` containing the indices or |
| IDs of the top `N` categories sorted in order from highest score to |
| lowest score. `N` must be greater or equal to `k`. |
| |
| The `from_sorted_ids=True` option can be more efficient when the set of |
| categories is very large and the model has an optimized way to retrieve the |
| top ones either without scoring or without maintaining the scores for all |
| the possible categories. |
| |
| Args: |
| k: (Optional) Number of top elements to look at for computing accuracy. |
| Defaults to `5`. |
| name: (Optional) string name of the metric instance. |
| dtype: (Optional) data type of the metric result. |
| from_sorted_ids: (Optional) When `False`, the default, the tensor passed |
| in `y_pred` contains the unsorted scores of all possible categories. |
| When `True`, `y_pred` contains a the indices or IDs for the top |
| categories. |
| |
| Example: |
| |
| >>> m = keras.metrics.SparseTopKCategoricalAccuracy(k=1) |
| >>> m.update_state([2, 1], [[0.1, 0.9, 0.8], [0.05, 0.95, 0]]) |
| >>> m.result() |
| 0.5 |
| |
| >>> m.reset_state() |
| >>> m.update_state([2, 1], [[0.1, 0.9, 0.8], [0.05, 0.95, 0]], |
| ... sample_weight=[0.7, 0.3]) |
| >>> m.result() |
| 0.3 |
| |
| >>> m = keras.metrics.SparseTopKCategoricalAccuracy(k=1, |
| ... from_sorted_ids=True) |
| >>> m.update_state([2, 1], [[1, 0, 3], [1, 2, 3]]) |
| >>> m.result() |
| 0.5 |
| |
| Usage with `compile()` API: |
| |
| ```python |
| model.compile(optimizer='sgd', |
| loss='sparse_categorical_crossentropy', |
| metrics=[keras.metrics.SparseTopKCategoricalAccuracy()]) |
| ``` |
| """ |
|
|
| def __init__( |
| self, |
| k=5, |
| name="sparse_top_k_categorical_accuracy", |
| dtype=None, |
| from_sorted_ids=False, |
| ): |
| super().__init__( |
| fn=sparse_top_k_categorical_accuracy, |
| name=name, |
| dtype=dtype, |
| k=k, |
| from_sorted_ids=from_sorted_ids, |
| ) |
| self.k = k |
| self.from_sorted_ids = from_sorted_ids |
| |
| self._direction = "up" |
|
|
| def get_config(self): |
| config = {"name": self.name, "dtype": self.dtype, "k": self.k} |
| if self.from_sorted_ids: |
| config["from_sorted_ids"] = True |
| return config |
|
|