Example #1
0
    def infer(self,
              x: np.ndarray,
              y: Optional[np.ndarray] = None,
              **kwargs) -> np.ndarray:
        """
        Infer membership in the training set of the target estimator.

        :param x: Input records to attack.
        :param y: True labels for `x`.
        :param probabilities: a boolean indicating whether to return the predicted probabilities per class, or just
                              the predicted class
        :return: An array holding the inferred membership status, 1 indicates a member and 0 indicates non-member,
                 or class probabilities.
        """
        if y is None:  # pragma: no cover
            raise ValueError(
                "MembershipInferenceBlackBox requires true labels `y`.")

        if self.estimator.input_shape is not None:  # pragma: no cover
            if self.estimator.input_shape[0] != x.shape[1]:
                raise ValueError(
                    "Shape of x does not match input_shape of estimator")

        if "probabilities" in kwargs:
            probabilities = kwargs.get("probabilities")
        else:
            probabilities = False

        if not self._regressor_model:
            y = check_and_transform_label_format(y,
                                                 len(np.unique(y)),
                                                 return_one_hot=True)

        if y is None:
            raise ValueError("None value detected.")

        if y.shape[0] != x.shape[0]:  # pragma: no cover
            raise ValueError("Number of rows in x and y do not match")

        if self.input_type == "prediction":
            features = self.estimator.predict(x).astype(np.float32)
        elif self.input_type == "loss":
            features = self.estimator.compute_loss(x, y).astype(
                np.float32).reshape(-1, 1)

        if self._regressor_model:
            y = y.astype(np.float32).reshape(-1, 1)

        if self.default_model and self.attack_model_type == "nn":
            import torch  # lgtm [py/repeated-import] lgtm [py/import-and-import-from]
            from torch.utils.data import DataLoader  # lgtm [py/repeated-import]
            from art.utils import to_cuda, from_cuda

            self.attack_model.eval()  # type: ignore
            inferred: Optional[np.ndarray] = None
            test_set = self._get_attack_dataset(f_1=features, f_2=y)
            test_loader = DataLoader(test_set,
                                     batch_size=self.batch_size,
                                     shuffle=False,
                                     num_workers=0)
            for input1, input2, _ in test_loader:
                input1, input2 = to_cuda(input1), to_cuda(input2)
                outputs = self.attack_model(input1, input2)  # type: ignore
                if not probabilities:
                    predicted = torch.round(outputs)
                else:
                    predicted = outputs
                predicted = from_cuda(predicted)

                if inferred is None:
                    inferred = predicted.detach().numpy()
                else:
                    inferred = np.vstack(
                        (inferred, predicted.detach().numpy()))

            if inferred is not None:
                if not probabilities:
                    inferred_return = np.round(inferred)
                else:
                    inferred_return = inferred
            else:  # pragma: no cover
                raise ValueError("No data available.")
        elif not self.default_model:
            # assumes the predict method of the supplied model returns probabilities
            pred = self.attack_model.predict(np.c_[features,
                                                   y])  # type: ignore
            if probabilities:
                inferred_return = pred
            else:
                inferred_return = np.round(pred)
        else:
            pred = self.attack_model.predict_proba(np.c_[features,
                                                         y])  # type: ignore
            if probabilities:
                inferred_return = pred[:, [1]]
            else:
                inferred_return = np.round(pred[:, [1]])

        return inferred_return
    def infer(self,
              x: np.ndarray,
              y: Optional[np.ndarray] = None,
              **kwargs) -> np.ndarray:
        """
        Infer membership in the training set of the target estimator.

        :param x: Input records to attack.
        :param y: True labels for `x`.
        :return: An array holding the inferred membership status, 1 indicates a member and 0 indicates non-member.
        """
        if y is None:
            raise ValueError(
                "MembershipInferenceBlackBox requires true labels `y`.")

        if self.estimator.input_shape[0] != x.shape[1]:
            raise ValueError(
                "Shape of x does not match input_shape of classifier")

        y = check_and_transform_label_format(y,
                                             len(np.unique(y)),
                                             return_one_hot=True)

        if y.shape[0] != x.shape[0]:
            raise ValueError("Number of rows in x and y do not match")

        if self.input_type == "prediction":
            features = self.estimator.predict(x).astype(np.float32)
        elif self.input_type == "loss":
            features = self.estimator.loss(x, y).astype(np.float32).reshape(
                -1, 1)

        if self.default_model and self.attack_model_type == "nn":
            import torch  # lgtm [py/repeated-import]
            from torch.utils.data import DataLoader  # lgtm [py/repeated-import]
            from art.utils import to_cuda, from_cuda

            self.attack_model.eval()
            inferred = None
            test_set = self._get_attack_dataset(f_1=features, f_2=y)
            test_loader = DataLoader(test_set,
                                     batch_size=self.batch_size,
                                     shuffle=True,
                                     num_workers=0)
            for input1, input2, _ in test_loader:
                input1, input2 = to_cuda(input1), to_cuda(input2)
                outputs = self.attack_model(input1, input2)
                predicted = torch.round(outputs)
                predicted = from_cuda(predicted)

                if inferred is None:
                    inferred = predicted.detach().numpy()
                else:
                    inferred = np.vstack(
                        (inferred, predicted.detach().numpy()))
            inferred = inferred.reshape(-1).astype(np.int)
        else:
            inferred = np.array([
                np.argmax(arr)
                for arr in self.attack_model.predict(np.c_[features, y])
            ])
        return inferred