def _test_preprocessing_defences_backward( get_default_mnist_subset, image_dl_estimator, device_type, preprocessing_defences ): (_, _), (x_test_mnist, y_test_mnist) = get_default_mnist_subset classifier_, _ = image_dl_estimator() clip_values = (0, 1) criterion = nn.CrossEntropyLoss() classifier = PyTorchClassifier( clip_values=clip_values, model=classifier_.model, preprocessing_defences=preprocessing_defences, loss=criterion, input_shape=(1, 28, 28), nb_classes=10, device_type=device_type, ) # The efficient defence-chaining. pseudo_gradients = np.random.randn(*x_test_mnist.shape) gradients_in_chain = classifier._apply_preprocessing_gradient(x_test_mnist, pseudo_gradients) # Apply the same backward pass one by one. x = x_test_mnist x_intermediates = [x] for preprocess in classifier.preprocessing_operations[:-1]: x = preprocess(x)[0] x_intermediates.append(x) gradients = pseudo_gradients for preprocess, x in zip(classifier.preprocessing_operations[::-1], x_intermediates[::-1]): gradients = preprocess.estimate_gradient(x, gradients) np.testing.assert_array_almost_equal(gradients_in_chain, gradients, decimal=4)
def test_device(art_warning): try: class Flatten(nn.Module): def forward(self, x): n, _, _, _ = x.size() result = x.view(n, -1) return result # Define the network model = nn.Sequential(nn.Conv2d(1, 2, 5), nn.ReLU(), nn.MaxPool2d(2, 2), Flatten(), nn.Linear(288, 10)) # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) # First test cpu classifier_cpu = PyTorchClassifier( model=model, clip_values=(0, 1), loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, device_type="cpu", ) assert classifier_cpu._device == torch.device("cpu") assert classifier_cpu._device != torch.device("cuda") # Then test gpu if torch.cuda.device_count() >= 2: with torch.cuda.device(0): classifier_gpu0 = PyTorchClassifier( model=model, clip_values=(0, 1), loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, ) assert classifier_gpu0._device == torch.device("cuda:0") assert classifier_gpu0._device != torch.device("cuda:1") with torch.cuda.device(1): classifier_gpu1 = PyTorchClassifier( model=model, clip_values=(0, 1), loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, ) assert classifier_gpu1._device == torch.device("cuda:1") assert classifier_gpu1._device != torch.device("cuda:0") except ARTTestException as e: art_warning(e)
def _test_preprocessing_defences_forward( get_default_mnist_subset, image_dl_estimator, device_type, preprocessing_defences ): (_, _), (x_test_mnist, y_test_mnist) = get_default_mnist_subset classifier_, _ = image_dl_estimator() clip_values = (0, 1) criterion = nn.CrossEntropyLoss() classifier = PyTorchClassifier( clip_values=clip_values, model=classifier_.model, preprocessing_defences=preprocessing_defences, loss=criterion, input_shape=(1, 28, 28), nb_classes=10, device_type=device_type, ) with torch.no_grad(): predictions_classifier = classifier.predict(x_test_mnist) # Apply the same defences by hand x_test_defense = x_test_mnist for defence in preprocessing_defences: x_test_defense, _ = defence(x_test_defense, y_test_mnist) x_test_defense = torch.tensor(x_test_defense) with torch.no_grad(): predictions_check = classifier_.model(x_test_defense) predictions_check = predictions_check.cpu().numpy() # Check that the prediction results match np.testing.assert_array_almost_equal(predictions_classifier, predictions_check, decimal=4)
def net_generation_and_train(X_train, y_train, net_type): loss = nn.CrossEntropyLoss() net = net_type(n_features=2, n_classes=2) optimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9) clf = PyTorchClassifier(model=net, loss=loss, input_shape=(1,2), nb_classes=2, optimizer=optimizer) clf.fit(X_train, y_train, batch_size=10, nb_epochs=100) return clf
def _weight_grad(classifier: PyTorchClassifier, x: torch.Tensor, target: torch.Tensor) -> torch.Tensor: classifier.model.zero_grad() y = classifier.model(x) loss_ = classifier.loss(y, target) gradspred = torch.autograd.grad(loss_, list( classifier.model.parameters()), create_graph=True, retain_graph=True) d_w = torch.cat([w.flatten() for w in gradspred]) d_w_norm = d_w / torch.sqrt(torch.sum(torch.square(d_w))) return d_w_norm
def test_pickle(art_warning, get_default_mnist_subset, image_dl_estimator): try: (x_train_mnist, y_train_mnist), (x_test_mnist, y_test_mnist) = get_default_mnist_subset from art import config full_path = os.path.join(config.ART_DATA_PATH, "my_classifier") folder = os.path.split(full_path)[0] if not os.path.exists(folder): os.makedirs(folder) # The model used within the common ART pytorch get_image_classifier_list does not support pickling model = Model() loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) myclassifier_2 = PyTorchClassifier(model=model, clip_values=(0, 1), loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10) myclassifier_2.fit(x_train_mnist, y_train_mnist, batch_size=100, nb_epochs=1) pickle.dump(myclassifier_2, open(full_path, "wb")) with open(full_path, "rb") as f: loaded_model = pickle.load(f) np.testing.assert_equal(myclassifier_2._clip_values, loaded_model._clip_values) assert myclassifier_2._channel_index == loaded_model._channel_index assert set(myclassifier_2.__dict__.keys()) == set( loaded_model.__dict__.keys()) # Test predict predictions_1 = myclassifier_2.predict(x_test_mnist) accuracy_1 = np.sum( np.argmax(predictions_1, axis=1) == np.argmax( y_test_mnist, axis=1)) / y_test_mnist.shape[0] predictions_2 = loaded_model.predict(x_test_mnist) accuracy_2 = np.sum( np.argmax(predictions_2, axis=1) == np.argmax( y_test_mnist, axis=1)) / y_test_mnist.shape[0] assert accuracy_1 == accuracy_2 except ARTTestException as e: art_warning(e)
def loss_gradient(self, x: np.ndarray, y: np.ndarray, **kwargs) -> np.ndarray: """ Compute the gradient of the loss function w.r.t. `x`. :param x: Sample input with shape as expected by the model. :param y: Target values (class labels) one-hot-encoded of shape (nb_samples, nb_classes) or indices of shape (nb_samples,). :param sampling: True if loss gradients should be determined with Monte Carlo sampling. :type sampling: `bool` :return: Array of gradients of the same shape as `x`. """ import torch # lgtm [py/repeated-import] sampling = kwargs.get("sampling") if sampling: # Apply preprocessing x_preprocessed, y_preprocessed = self._apply_preprocessing( x, y, fit=False) # Check label shape if self._reduce_labels: y_preprocessed = np.argmax(y_preprocessed, axis=1) # Convert the inputs to Tensors inputs_t = torch.from_numpy(x_preprocessed).to(self._device) inputs_t.requires_grad = True # Convert the labels to Tensors labels_t = torch.from_numpy(y_preprocessed).to(self._device) inputs_repeat_t = inputs_t.repeat_interleave(self.sample_size, 0) noise = torch.randn_like(inputs_repeat_t, device=self._device) * self.scale inputs_noise_t = inputs_repeat_t + noise if self.clip_values is not None: inputs_noise_t.clamp(self.clip_values[0], self.clip_values[1]) model_outputs = self._model(inputs_noise_t)[-1] softmax = torch.nn.functional.softmax(model_outputs, dim=1) average_softmax = (softmax.reshape(-1, self.sample_size, model_outputs.shape[-1]).mean( 1, keepdim=True).squeeze(1)) log_softmax = torch.log(average_softmax.clamp(min=1e-20)) loss = torch.nn.functional.nll_loss(log_softmax, labels_t) # Clean gradients self._model.zero_grad() # Compute gradients loss.backward() gradients = inputs_t.grad.cpu().numpy().copy() # type: ignore gradients = self._apply_preprocessing_gradient(x, gradients) assert gradients.shape == x.shape else: gradients = PyTorchClassifier.loss_gradient(self, x, y, **kwargs) return gradients
def test_fgsm_defences(fix_get_mnist_subset, image_dl_estimator, device_type): clip_values = (0, 1) smooth_3x3 = SpatialSmoothingPyTorch(window_size=3, channels_first=True, device_type=device_type) smooth_5x5 = SpatialSmoothingPyTorch(window_size=5, channels_first=True, device_type=device_type) smooth_7x7 = SpatialSmoothingPyTorch(window_size=7, channels_first=True, device_type=device_type) classifier_, _ = image_dl_estimator(one_classifier=True) criterion = nn.CrossEntropyLoss() classifier = PyTorchClassifier( clip_values=clip_values, model=classifier_.model, preprocessing_defences=[smooth_3x3, smooth_5x5, smooth_7x7], loss=criterion, input_shape=(1, 28, 28), nb_classes=10, device_type=device_type, ) assert len(classifier.preprocessing_defences) == 3 attack = FastGradientMethod(classifier, eps=1, batch_size=128) backend_test_defended_images(attack, fix_get_mnist_subset)
def setUpClass(cls): super().setUpClass() cls.x_train_mnist = np.reshape(cls.x_train_mnist, (cls.x_train_mnist.shape[0], 1, 28, 28)).astype(np.float32) cls.x_test_mnist = np.reshape(cls.x_test_mnist, (cls.x_test_mnist.shape[0], 1, 28, 28)).astype(np.float32) # Define the internal classifier classifier = get_image_classifier_pt() # Define the internal detector conv = nn.Conv2d(1, 16, 5) linear = nn.Linear(2304, 1) torch.nn.init.xavier_uniform_(conv.weight) torch.nn.init.xavier_uniform_(linear.weight) model = nn.Sequential(conv, nn.ReLU(), nn.MaxPool2d(2, 2), Flatten(), linear) model = Model(model) loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) detector = PyTorchClassifier( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=1, clip_values=(0, 1) ) # Define the detector-classifier cls.detector_classifier = DetectorClassifier(classifier=classifier, detector=detector) cls.x_train_mnist = np.reshape(cls.x_train_mnist, (cls.x_train_mnist.shape[0], 28, 28, 1)).astype(np.float32) cls.x_test_mnist = np.reshape(cls.x_test_mnist, (cls.x_test_mnist.shape[0], 28, 28, 1)).astype(np.float32)
def test_check_params(self): model = Model() loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) pixel_cnn = PyTorchClassifier( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(4,), nb_classes=2, clip_values=(0, 1) ) with self.assertRaises(TypeError): _ = PixelDefend(pixel_cnn="pixel_cnn") with self.assertRaises(ValueError): _ = PixelDefend(pixel_cnn=pixel_cnn, eps=-1) with self.assertRaises(ValueError): _ = PixelDefend(pixel_cnn=pixel_cnn, clip_values=(1, 0)) with self.assertRaises(ValueError): _ = PixelDefend(pixel_cnn=pixel_cnn, clip_values=(-1, 1)) with self.assertRaises(ValueError): _ = PixelDefend(pixel_cnn=pixel_cnn, clip_values=(0, 2)) with self.assertRaises(ValueError): _ = PixelDefend(pixel_cnn=pixel_cnn, batch_size=-1) with self.assertRaises(ValueError): _ = PixelDefend(pixel_cnn=pixel_cnn, verbose="False")
def _create_ptclassifier(): """ To create a simple PyTorchClassifier for testing. :return: """ class Model(nn.Module): def __init__(self): super(Model, self).__init__() self.conv = nn.Conv2d(1, 16, 5) self.pool = nn.MaxPool2d(2, 2) self.fc = nn.Linear(2304, 10) def forward(self, x): x = self.pool(f.relu(self.conv(x))) x = x.view(-1, 2304) logit_output = self.fc(x) return logit_output # Define the network model = Model() # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) # Get classifier ptc = PyTorchClassifier(model=model, loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, clip_values=(0, 1)) return ptc
def _predict_classifier(self, x: np.ndarray, batch_size: int, training_mode: bool, **kwargs) -> np.ndarray: x = x.astype(ART_NUMPY_DTYPE) return PyTorchClassifier.predict(self, x=x, batch_size=batch_size, training_mode=training_mode, **kwargs)
def _fit_classifier(self, x: np.ndarray, y: np.ndarray, batch_size: int, nb_epochs: int, **kwargs) -> None: x = x.astype(ART_NUMPY_DTYPE) return PyTorchClassifier.fit(self, x, y, batch_size=batch_size, nb_epochs=nb_epochs, **kwargs)
def test_black_box_with_model(art_warning, decision_tree_estimator, get_iris_dataset): try: attack_feature = 2 # petal length # need to transform attacked feature into categorical def transform_feature(x): x[x > 0.5] = 2.0 x[(x > 0.2) & (x <= 0.5)] = 1.0 x[x <= 0.2] = 0.0 values = [0.0, 1.0, 2.0] (x_train_iris, y_train_iris), (x_test_iris, y_test_iris) = get_iris_dataset # training data without attacked feature x_train_for_attack = np.delete(x_train_iris, attack_feature, 1) # only attacked feature x_train_feature = x_train_iris[:, attack_feature].copy().reshape(-1, 1) transform_feature(x_train_feature) # training data with attacked feature (after transformation) x_train = np.concatenate((x_train_for_attack[:, :attack_feature], x_train_feature), axis=1) x_train = np.concatenate((x_train, x_train_for_attack[:, attack_feature:]), axis=1) # test data without attacked feature x_test_for_attack = np.delete(x_test_iris, attack_feature, 1) # only attacked feature x_test_feature = x_test_iris[:, attack_feature].copy().reshape(-1, 1) transform_feature(x_test_feature) model = nn.Linear(4, 3) # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) attack_model = PyTorchClassifier( model=model, clip_values=(0, 1), loss=loss_fn, optimizer=optimizer, input_shape=(4,), nb_classes=3 ) classifier = decision_tree_estimator() attack = AttributeInferenceBlackBox(classifier, attack_model=attack_model, attack_feature=attack_feature) # get original model's predictions x_train_predictions = np.array([np.argmax(arr) for arr in classifier.predict(x_train_iris)]).reshape(-1, 1) x_test_predictions = np.array([np.argmax(arr) for arr in classifier.predict(x_test_iris)]).reshape(-1, 1) # train attack model attack.fit(x_train) # infer attacked feature inferred_train = attack.infer(x_train_for_attack, x_train_predictions, values=values) inferred_test = attack.infer(x_test_for_attack, x_test_predictions, values=values) # check accuracy # train_acc _ = np.sum(inferred_train == x_train_feature.reshape(1, -1)) / len(inferred_train) # test_acc _ = np.sum(inferred_test == x_test_feature.reshape(1, -1)) / len(inferred_test) # assert train_acc == pytest.approx(0.5523, abs=0.03) # assert test_acc == pytest.approx(0.5777, abs=0.03) except ARTTestException as e: art_warning(e)
def test_black_box_with_model(get_tabular_classifier_list, get_iris_dataset): classifier_list = get_tabular_classifier_list(AttributeInferenceBlackBox) if not classifier_list: logging.warning("Couldn't perform this test because no classifier is defined") return attack_feature = 2 # petal length # need to transform attacked feature into categorical def transform_feature(x): x[x > 0.5] = 2.0 x[(x > 0.2) & (x <= 0.5)] = 1.0 x[x <= 0.2] = 0.0 values = [0.0, 1.0, 2.0] (x_train_iris, y_train_iris), (x_test_iris, y_test_iris) = get_iris_dataset # training data without attacked feature x_train_for_attack = np.delete(x_train_iris, attack_feature, 1) # only attacked feature x_train_feature = x_train_iris[:, attack_feature].copy().reshape(-1, 1) transform_feature(x_train_feature) # training data with attacked feature (after transformation) x_train = np.concatenate((x_train_for_attack[:, :attack_feature], x_train_feature), axis=1) x_train = np.concatenate((x_train, x_train_for_attack[:, attack_feature:]), axis=1) # test data without attacked feature x_test_for_attack = np.delete(x_test_iris, attack_feature, 1) # only attacked feature x_test_feature = x_test_iris[:, attack_feature].copy().reshape(-1, 1) transform_feature(x_test_feature) model = nn.Linear(4, 3) # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) attack_model = PyTorchClassifier( model=model, clip_values=(0, 1), loss=loss_fn, optimizer=optimizer, input_shape=(4,), nb_classes=3 ) for classifier in classifier_list: if type(classifier).__name__ == "ScikitlearnDecisionTreeClassifier": attack = AttributeInferenceBlackBox(classifier, attack_model=attack_model, attack_feature=attack_feature) # get original model's predictions x_train_predictions = np.array([np.argmax(arr) for arr in classifier.predict(x_train_iris)]).reshape(-1, 1) x_test_predictions = np.array([np.argmax(arr) for arr in classifier.predict(x_test_iris)]).reshape(-1, 1) # train attack model attack.fit(x_train) # infer attacked feature inferred_train = attack.infer(x_train_for_attack, x_train_predictions, values=values) inferred_test = attack.infer(x_test_for_attack, x_test_predictions, values=values) # check accuracy train_acc = np.sum(inferred_train == x_train_feature.reshape(1, -1)) / len(inferred_train) test_acc = np.sum(inferred_test == x_test_feature.reshape(1, -1)) / len(inferred_test)
def test_feature_vectors(self): # Define the network model = Model() loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) pixel_cnn = PyTorchClassifier( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(4,), nb_classes=2, clip_values=(0, 1) ) x = np.random.rand(5, 4).astype(np.float32) preprocess = PixelDefend(eps=5, pixel_cnn=pixel_cnn) x_defended, _ = preprocess(x) self.assertEqual(x_defended.shape, x.shape) self.assertTrue((x_defended <= 1.0).all()) self.assertTrue((x_defended >= 0.0).all())
def test_pytorch_binary_pgd(art_warning, get_mnist_dataset): """ This test instantiates a binary classification PyTorch model, then attacks it using PGD """ class BasicModel(nn.Module): def __init__(self): super(BasicModel, self).__init__() self.layer_1 = nn.Linear(20, 32) self.layer_2 = nn.Linear(32, 1) def forward(self, x): x = F.relu(self.layer_1(x)) x = torch.sigmoid(self.layer_2(x)) return x try: device = "cpu" x, y = sklearn.datasets.make_classification(n_samples=10000, n_features=20, n_informative=5, n_redundant=2, n_repeated=0, n_classes=2) train_x, test_x, train_y, test_y = sklearn.model_selection.train_test_split( x, y, test_size=0.2) train_x = test_x.astype(np.float32) train_y = train_y.astype(np.float32) test_x = test_x.astype(np.float32) model = BasicModel() loss_func = nn.BCELoss() model.to(device) opt = optim.Adam(model.parameters(), lr=0.001) classifier = PyTorchClassifier( model=model, loss=loss_func, optimizer=opt, input_shape=(1, 28, 28), nb_classes=2, ) classifier.fit(train_x, train_y, batch_size=64, nb_epochs=3) test_x_batch = test_x[0:16] preds = classifier.predict(test_x_batch) attacker = ProjectedGradientDescent(classifier, eps=0.5) generated = attacker.generate(test_x_batch) adv_predicted = classifier.predict(generated) assert (adv_predicted != preds).all() except ARTTestException as e: art_warning(e)
def _create_ptclassifier(): """ To create a simple PyTorchClassifier for testing. :return: """ # Define the network model = Model() # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) # Get classifier ptc = PyTorchClassifier(model=model, loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, clip_values=(0, 1)) return ptc
def test_one_channel(self): (x_train, _), (_, _), _, _ = load_mnist() x_train = x_train[:2, 10:15, 15:20, :] x_train = x_train.astype(np.float32) x_train_original = x_train.copy() # Define the network model = ModelImage() loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) self.pixelcnn = PyTorchClassifier( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, clip_values=(0, 1) ) preprocess = PixelDefend(eps=5, pixel_cnn=self.pixelcnn) x_defended, _ = preprocess(x_train) self.assertEqual(x_defended.shape, x_train.shape) self.assertTrue((x_defended <= 1.0).all()) self.assertTrue((x_defended >= 0.0).all()) # Check that x_train has not been modified by attack and classifier self.assertAlmostEqual(float(np.max(np.abs(x_train_original - x_train))), 0.0, delta=0.00001)
def test_loss_gradient_amp( art_warning, get_default_mnist_subset, image_dl_estimator, expected_values, mnist_shape, device_type, ): import torch import torch.nn as nn from art.estimators.classification.pytorch import PyTorchClassifier try: (expected_gradients_1, expected_gradients_2) = expected_values() (_, _), (x_test_mnist, y_test_mnist) = get_default_mnist_subset classifier, _ = image_dl_estimator(from_logits=True) optimizer = torch.optim.Adam(classifier.model.parameters(), lr=0.01) # Redefine the classifier with amp clip_values = (0, 1) criterion = nn.CrossEntropyLoss() classifier = PyTorchClassifier( clip_values=clip_values, model=classifier.model, preprocessing_defences=[], loss=criterion, input_shape=(1, 28, 28), nb_classes=10, device_type=device_type, optimizer=optimizer, use_amp=True, loss_scale=1.0, ) # Compute loss gradients gradients = classifier.loss_gradient(x_test_mnist, y_test_mnist) # Test shape assert gradients.shape == (x_test_mnist.shape[0], ) + mnist_shape # First test of gradients sub_gradients = gradients[0, 0, :, 14] np.testing.assert_array_almost_equal( sub_gradients, expected_gradients_1, decimal=4, ) # Second test of gradients sub_gradients = gradients[0, 0, 14, :] np.testing.assert_array_almost_equal( sub_gradients, expected_gradients_2, decimal=4, ) # Compute loss gradients with framework gradients = classifier.loss_gradient_framework( torch.tensor(x_test_mnist).to(classifier.device), torch.tensor(y_test_mnist).to(classifier.device)) gradients = gradients.cpu().numpy() # Test shape assert gradients.shape == (x_test_mnist.shape[0], ) + mnist_shape # First test of gradients sub_gradients = gradients[0, 0, :, 14] np.testing.assert_array_almost_equal( sub_gradients, expected_gradients_1, decimal=4, ) # Second test of gradients sub_gradients = gradients[0, 0, 14, :] np.testing.assert_array_almost_equal( sub_gradients, expected_gradients_2, decimal=4, ) except ARTTestException as e: art_warning(e)
def test_pytorch_classifier(self): """ Third test with the PyTorchClassifier. :return: """ x_train = np.reshape(self.x_train_mnist, (self.x_train_mnist.shape[0], 1, 28, 28)).astype( np.float32) # Build PyTorchClassifier victim_ptc = get_image_classifier_pt() class Model(nn.Module): """ Create model for pytorch. """ def __init__(self): super(Model, self).__init__() self.conv = nn.Conv2d(in_channels=1, out_channels=1, kernel_size=7) self.pool = nn.MaxPool2d(4, 4) self.fullyconnected = nn.Linear(25, 10) # pylint: disable=W0221 # disable pylint because of API requirements for function def forward(self, x): """ Forward function to evaluate the model :param x: Input to the model :return: Prediction of the model """ x = self.conv(x) x = torch.nn.functional.relu(x) x = self.pool(x) x = x.reshape(-1, 25) x = self.fullyconnected(x) x = torch.nn.functional.softmax(x, dim=1) return x # Define the network model = Model() # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.01) # Get classifier thieved_ptc = PyTorchClassifier(model=model, loss=loss_fn, optimizer=optimizer, input_shape=(1, 28, 28), nb_classes=10, clip_values=(0, 1)) # Create attack copycat_cnn = CopycatCNN( classifier=victim_ptc, batch_size_fit=self.batch_size, batch_size_query=self.batch_size, nb_epochs=NB_EPOCHS, nb_stolen=NB_STOLEN, ) thieved_ptc = copycat_cnn.extract(x=x_train, thieved_classifier=thieved_ptc) victim_preds = np.argmax(victim_ptc.predict(x=x_train[:100]), axis=1) thieved_preds = np.argmax(thieved_ptc.predict(x=x_train[:100]), axis=1) acc = np.sum(victim_preds == thieved_preds) / len(victim_preds) self.assertGreater(acc, 0.3)
def test_pytorch_iris(self): """ Third test for PyTorch. :return: """ # Build PyTorchClassifier victim_ptc = get_tabular_classifier_pt() class Model(nn.Module): """ Create Iris model for PyTorch. """ def __init__(self): super(Model, self).__init__() self.fully_connected1 = nn.Linear(4, 10) self.fully_connected2 = nn.Linear(10, 10) self.fully_connected3 = nn.Linear(10, 3) # pylint: disable=W0221 # disable pylint because of API requirements for function def forward(self, x): x = self.fully_connected1(x) x = self.fully_connected2(x) logit_output = self.fully_connected3(x) return logit_output # Define the network model = Model() # Define a loss function and optimizer loss_fn = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=0.001) # Get classifier thieved_ptc = PyTorchClassifier( model=model, loss=loss_fn, optimizer=optimizer, input_shape=(4, ), nb_classes=3, clip_values=(0, 1), channels_first=True, ) # Create attack copycat_cnn = CopycatCNN( classifier=victim_ptc, batch_size_fit=self.batch_size, batch_size_query=self.batch_size, nb_epochs=NB_EPOCHS, nb_stolen=NB_STOLEN, ) thieved_ptc = copycat_cnn.extract(x=self.x_train_iris, thieved_classifier=thieved_ptc) victim_preds = np.argmax(victim_ptc.predict(x=self.x_train_iris[:100]), axis=1) thieved_preds = np.argmax( thieved_ptc.predict(x=self.x_train_iris[:100]), axis=1) acc = np.sum(victim_preds == thieved_preds) / len(victim_preds) self.assertGreater(acc, 0.3)
def _predict_classifier(self, x: np.ndarray, batch_size: int) -> np.ndarray: x = x.astype(ART_NUMPY_DTYPE) return PyTorchClassifier.predict(self, x=x, batch_size=batch_size)