Source code for holisticai.robustness.metrics.classification._binary_classification

import numpy as np
import numpy.linalg as la


[docs] def adversarial_accuracy(y, y_pred, y_adv_pred): """ Calculate the adversarial accuracy of a model with array-like inputs. Parameters ---------- y : array-like The true labels. If `None`, the function calculates the accuracy based on `y_pred` and `y_adv_pred` directly. y_pred : array-like The predicted labels for the original input. y_adv_pred : array-like The predicted labels for the adversarial input. Returns ------- float The adversarial accuracy value. Examples -------- >>> import numpy as np >>> from holisticai.robustness.metrics import adversarial_accuracy >>> y = [1, 0, 1, 1] # Example with list input >>> y_pred = [1, 0, 0, 1] >>> y_adv_pred = [0, 0, 1, 1] >>> adversarial_accuracy(y, y_pred, y_adv_pred) 0.6666666666666666 """ try: # Convert inputs to np.ndarray if they are not already y = np.array(y) if y is not None else None y_pred = np.array(y_pred) y_adv_pred = np.array(y_adv_pred) except Exception as e: raise ValueError("One or more inputs could not be converted to a numpy array.") from e if y is None: idxs = y_pred == y_adv_pred return np.sum(idxs) / len(y_adv_pred) y_corr = y_pred == y return np.sum((y_pred == y_adv_pred) & y_corr) / np.sum(y_corr)
[docs] def empirical_robustness( x, adv_x, y_pred, y_adv_pred, norm=2, ) -> float: """ Calculate the empirical robustness of an adversarial example. Parameters ---------- x : array-like The original input. adv_x : array-like The adversarial input. y_pred : array-like The predicted labels for the original input. y_adv_pred : array-like The predicted labels for the adversarial input. norm : int (optional) The norm to be used for calculating the perturbation. Defaults to 2. Returns ------- float The empirical robustness value. Examples -------- >>> import numpy as np >>> from holisticai.robustness.metrics import empirical_robustness >>> x = np.array([[1, 2, 3], [4, 5, 6]]) >>> adv_x = np.array([[1.1, 2.2, 3.3], [4.4, 5.5, 6.6]]) >>> y_pred = np.array([0, 1]) >>> y_adv_pred = np.array([1, 1]) >>> empirical_robustness(x, adv_x, y_pred, y_adv_pred) 0.09999999999999999 """ try: x = np.array(x) adv_x = np.array(adv_x) y_pred = np.array(y_pred) y_adv_pred = np.array(y_adv_pred) except Exception as e: raise ValueError("One or more inputs could not be converted to a numpy array.") from e # Verify that `norm` has the correct type if not isinstance(norm, int): raise TypeError("norm must be of type int") idxs = y_adv_pred != y_pred if np.sum(idxs) == 0.0: return 0.0 perts_norm = la.norm((adv_x - x).reshape(x.shape[0], -1), ord=norm, axis=1) perts_norm = perts_norm[idxs] return np.mean(perts_norm / la.norm(x[idxs].reshape(np.sum(idxs), -1), ord=norm, axis=1))