def test_check_params(self): with self.assertRaises(ValueError): _ = FeatureSqueezing(clip_values=(0, 4), bit_depth=-1) with self.assertRaises(ValueError): _ = FeatureSqueezing(clip_values=(0, 4, 8)) with self.assertRaises(ValueError): _ = FeatureSqueezing(clip_values=(4, 0))
def test_defences_predict(get_default_mnist_subset, image_dl_estimator_defended, image_dl_estimator): (_, _), (x_test_mnist, y_test_mnist) = get_default_mnist_subset classifier, _ = image_dl_estimator_defended( one_classifier=True, defenses=["FeatureSqueezing", "JpegCompression", "SpatialSmoothing"]) if classifier is not None: assert len(classifier.preprocessing_defences) == 3 predictions_classifier = classifier.predict(x_test_mnist) # Apply the same defences by hand x_test_defense = x_test_mnist clip_values = (0, 1) fs = FeatureSqueezing(clip_values=clip_values, bit_depth=2) x_test_defense, _ = fs(x_test_defense, y_test_mnist) jpeg = JpegCompression(clip_values=clip_values, apply_predict=True) x_test_defense, _ = jpeg(x_test_defense, y_test_mnist) smooth = SpatialSmoothing() x_test_defense, _ = smooth(x_test_defense, y_test_mnist) # classifier, _ = get_image_classifier_list(one_classifier=True, from_logits=True) classifier, _ = image_dl_estimator(one_classifier=True) predictions_check = classifier._model.predict(x_test_defense) # Check that the prediction results match np.testing.assert_array_almost_equal(predictions_classifier, predictions_check, decimal=4)
def test_data_range(self): x = np.arange(5) preproc = FeatureSqueezing(clip_values=(0, 4), bit_depth=2) x_squeezed, _ = preproc(x) self.assertTrue(np.array_equal(x, np.arange(5))) self.assertTrue( np.allclose(x_squeezed, [0, 1.33, 2.67, 2.67, 4], atol=1e-1))
def test_defences_predict(self): clip_values = (0, 1) fs = FeatureSqueezing(clip_values=clip_values, bit_depth=2) jpeg = JpegCompression(clip_values=clip_values, apply_predict=True) smooth = SpatialSmoothing() classifier_ = get_image_classifier_kr_tf() classifier = KerasClassifier(clip_values=clip_values, model=classifier_._model, preprocessing_defences=[fs, jpeg, smooth]) self.assertEqual(len(classifier.preprocessing_defences), 3) predictions_classifier = classifier.predict(self.x_test_mnist) # Apply the same defences by hand x_test_defense = self.x_test_mnist x_test_defense, _ = fs(x_test_defense, self.y_test_mnist) x_test_defense, _ = jpeg(x_test_defense, self.y_test_mnist) x_test_defense, _ = smooth(x_test_defense, self.y_test_mnist) classifier = get_image_classifier_kr_tf() predictions_check = classifier._model.predict(x_test_defense) # Check that the prediction results match np.testing.assert_array_almost_equal(predictions_classifier, predictions_check, decimal=4)
def test_pickle(self): filename = "my_classifier.p" full_path = os.path.join(ART_DATA_PATH, filename) folder = os.path.split(full_path)[0] if not os.path.exists(folder): os.makedirs(folder) fs = FeatureSqueezing(bit_depth=1, clip_values=(0, 1)) keras_model = KerasClassifier(self.functional_model, clip_values=(0, 1), input_layer=1, output_layer=1, preprocessing_defences=fs) with open(full_path, "wb") as save_file: pickle.dump(keras_model, save_file) # Unpickle: with open(full_path, "rb") as load_file: loaded = pickle.load(load_file) np.testing.assert_equal(keras_model._clip_values, loaded._clip_values) self.assertEqual(keras_model._channels_first, loaded._channels_first) self.assertEqual(keras_model._use_logits, loaded._use_logits) self.assertEqual(keras_model._input_layer, loaded._input_layer) self.assertEqual(self.functional_model.get_config(), loaded._model.get_config()) self.assertTrue( isinstance(loaded.preprocessing_defences[0], FeatureSqueezing)) os.remove(full_path)
def test_defences_predict(get_default_mnist_subset, get_image_classifier_list): (x_train_mnist, y_train_mnist), (x_test_mnist, y_test_mnist) = get_default_mnist_subset clip_values = (0, 1) fs = FeatureSqueezing(clip_values=clip_values, bit_depth=2) jpeg = JpegCompression(clip_values=clip_values, apply_predict=True) smooth = SpatialSmoothing() classifier_, _ = get_image_classifier_list(one_classifier=True) classifier = KerasClassifier(clip_values=clip_values, model=classifier_.model, preprocessing_defences=[fs, jpeg, smooth]) assert len(classifier.preprocessing_defences) == 3 predictions_classifier = classifier.predict(x_test_mnist) # Apply the same defences by hand x_test_defense = x_test_mnist x_test_defense, _ = fs(x_test_defense, y_test_mnist) x_test_defense, _ = jpeg(x_test_defense, y_test_mnist) x_test_defense, _ = smooth(x_test_defense, y_test_mnist) classifier, _ = get_image_classifier_list(one_classifier=True) predictions_check = classifier.model.predict(x_test_defense) # Check that the prediction results match np.testing.assert_array_almost_equal(predictions_classifier, predictions_check, decimal=4)
def test_with_defences(self): (x_train, y_train), (x_test, y_test) = self.mnist # Get the trained Keras model model = self.classifier_k._model fs = FeatureSqueezing(bit_depth=1, clip_values=(0, 1)) classifier = KerasClassifier(model=model, clip_values=(0, 1), preprocessing_defences=fs) # Create the classifier classifier = QueryEfficientGradientEstimationClassifier( classifier, 20, 1 / 64.0, round_samples=1 / 255.0) attack = FastGradientMethod(classifier, eps=1) x_train_adv = attack.generate(x_train) x_test_adv = attack.generate(x_test) self.assertFalse((x_train == x_train_adv).all()) self.assertFalse((x_test == x_test_adv).all()) train_y_pred = get_labels_np_array(classifier.predict(x_train_adv)) test_y_pred = get_labels_np_array(classifier.predict(x_test_adv)) self.assertFalse((y_train == train_y_pred).all()) self.assertFalse((y_test == test_y_pred).all())
def test_ones(self): m, n = 10, 2 x = np.ones((m, n)) for depth in range(1, 50): preproc = FeatureSqueezing(clip_values=(0, 1), bit_depth=depth) x_squeezed, _ = preproc(x) self.assertTrue((x_squeezed == 1).all())
def test_random(self): m, n = 1000, 20 x = np.random.rand(m, n) x_original = x.copy() x_zero = np.where(x < 0.5) x_one = np.where(x >= 0.5) preproc = FeatureSqueezing(clip_values=(0, 1), bit_depth=1) x_squeezed, _ = preproc(x) self.assertTrue((x_squeezed[x_zero] == 0.0).all()) self.assertTrue((x_squeezed[x_one] == 1.0).all()) preproc = FeatureSqueezing(clip_values=(0, 1), bit_depth=2) x_squeezed, _ = preproc(x) self.assertFalse( np.logical_and(0.0 < x_squeezed, x_squeezed < 0.33).any()) self.assertFalse( np.logical_and(0.34 < x_squeezed, x_squeezed < 0.66).any()) self.assertFalse( np.logical_and(0.67 < x_squeezed, x_squeezed < 1.0).any()) # Check that x has not been modified by attack and classifier self.assertAlmostEqual(float(np.max(np.abs(x_original - x))), 0.0, delta=0.00001)
def test_defences_predict(art_warning, get_default_mnist_subset, image_dl_estimator_defended, image_dl_estimator): try: (_, _), (x_test_mnist, y_test_mnist) = get_default_mnist_subset classifier, _ = image_dl_estimator() y_check_clean = classifier.predict(x_test_mnist) clip_values = (0, 1) classifier_defended, _ = image_dl_estimator_defended( defenses=["FeatureSqueezing"]) assert len(classifier_defended.preprocessing_defences) == 1 y_defended = classifier_defended.predict(x_test_mnist) fs = FeatureSqueezing(clip_values=clip_values, bit_depth=2) x_test_defense, _ = fs(x_test_mnist, y_test_mnist) y_check = classifier.predict(x_test_defense) np.testing.assert_array_almost_equal(y_defended, y_check, decimal=4) np.testing.assert_raises(AssertionError, np.testing.assert_array_equal, y_check, y_check_clean) classifier_defended, _ = image_dl_estimator_defended( defenses=["JpegCompression"]) assert len(classifier_defended.preprocessing_defences) == 1 y_defended = classifier_defended.predict(x_test_mnist) jpeg = JpegCompression( clip_values=clip_values, apply_predict=True, channels_first=classifier_defended.channels_first) x_test_defense, _ = jpeg(x_test_mnist, y_test_mnist) y_check = classifier.predict(x_test_defense) np.testing.assert_array_almost_equal(y_defended, y_check, decimal=4) np.testing.assert_raises(AssertionError, np.testing.assert_array_equal, y_check, y_check_clean) classifier_defended, _ = image_dl_estimator_defended( defenses=["SpatialSmoothing"]) assert len(classifier_defended.preprocessing_defences) == 1 y_defended = classifier_defended.predict(x_test_mnist) smooth = SpatialSmoothing( channels_first=classifier_defended.channels_first) x_test_defense, _ = smooth(x_test_mnist, y_test_mnist) y_check = classifier.predict(x_test_defense) np.testing.assert_array_almost_equal(y_defended, y_check, decimal=4) np.testing.assert_raises(AssertionError, np.testing.assert_array_equal, y_check, y_check_clean) except ARTTestException as e: art_warning(e)
def _image_dl_estimator_defended(one_classifier=False, **kwargs): sess = None classifier = None clip_values = (0, 1) fs = FeatureSqueezing(bit_depth=2, clip_values=clip_values) defenses = [] if kwargs.get("defenses") is None: defenses.append(fs) else: if "FeatureSqueezing" in kwargs.get("defenses"): defenses.append(fs) if "JpegCompression" in kwargs.get("defenses"): defenses.append( JpegCompression(clip_values=clip_values, apply_predict=True)) if "SpatialSmoothing" in kwargs.get("defenses"): defenses.append(SpatialSmoothing()) del kwargs["defenses"] if framework == "tensorflow2": classifier, _ = get_image_classifier_tf(**kwargs) if framework == "keras": classifier = get_image_classifier_kr(**kwargs) if framework == "kerastf": classifier = get_image_classifier_kr_tf(**kwargs) if framework == "pytorch": classifier = get_image_classifier_pt(**kwargs) for i, defense in enumerate(defenses): if "channels_first" in defense.params: defenses[i].channels_first = classifier.channels_first if classifier is not None: classifier.set_params(preprocessing_defences=defenses) else: raise ARTTestFixtureNotImplemented( "no defended image estimator", image_dl_estimator_defended.__name__, framework, {"defenses": defenses}) return classifier, sess
def test_with_defences(self): (x_train, y_train), (x_test, y_test) = self.mnist # Get the ready-trained Keras model model = self.classifier_k._model fs = FeatureSqueezing(bit_depth=1, clip_values=(0, 1)) classifier = KerasClassifier(model=model, clip_values=(0, 1), preprocessing_defences=fs) # Wrap the classifier classifier = QueryEfficientBBGradientEstimation(classifier, 20, 1 / 64.0, round_samples=1 / 255.0) attack = FastGradientMethod(classifier, eps=1) x_train_adv = attack.generate(x_train) x_test_adv = attack.generate(x_test) self.assertFalse((x_train == x_train_adv).all()) self.assertFalse((x_test == x_test_adv).all()) train_y_pred = get_labels_np_array(classifier.predict(x_train_adv)) test_y_pred = get_labels_np_array(classifier.predict(x_test_adv)) self.assertFalse((y_train == train_y_pred).all()) self.assertFalse((y_test == test_y_pred).all()) preds = classifier.predict(x_train_adv) acc = np.sum(np.argmax(preds, axis=1) == np.argmax( y_train, axis=1)) / y_train.shape[0] logger.info( "Accuracy on adversarial train examples with feature squeezing and limited query info: %.2f%%", (acc * 100)) preds = classifier.predict(x_test_adv) acc = np.sum(np.argmax(preds, axis=1) == np.argmax( y_test, axis=1)) / y_test.shape[0] logger.info( "Accuracy on adversarial test examples with feature squeezing and limited query info: %.2f%%", (acc * 100))
def _image_dl_estimator_defended(one_classifier=False, **kwargs): sess = None classifier = None clip_values = (0, 1) fs = FeatureSqueezing(bit_depth=2, clip_values=clip_values) defenses = [] if kwargs.get("defenses") is None: defenses.append(fs) else: if "FeatureSqueezing" in kwargs.get("defenses"): defenses.append(fs) if "JpegCompression" in kwargs.get("defenses"): defenses.append( JpegCompression(clip_values=clip_values, apply_predict=True)) if "SpatialSmoothing" in kwargs.get("defenses"): defenses.append(SpatialSmoothing()) del kwargs["defenses"] if framework == "keras": kr_classifier = get_image_classifier_kr(**kwargs) # Get the ready-trained Keras model classifier = KerasClassifier(model=kr_classifier._model, clip_values=(0, 1), preprocessing_defences=defenses) if framework == "kerastf": kr_tf_classifier = get_image_classifier_kr_tf(**kwargs) classifier = KerasClassifier(model=kr_tf_classifier._model, clip_values=(0, 1), preprocessing_defences=defenses) if classifier is None: raise ARTTestFixtureNotImplemented( "no defended image estimator", image_dl_estimator_defended.__name__, framework, {"defenses": defenses}) return classifier, sess
for i, idx_img in enumerate(idx_sample_imgs): ax[i][0].imshow(norm(X_clean[idx_img])) ax[i][0].axis('off') ax[i][0].set_title(label[np.argmax(labels[idx_img])]) ax[i][1].imshow(norm(X_adv[idx_img])) ax[i][1].axis('off') ax[i][1].set_title(label[preds_adv[idx_img]]) ax[i][2].imshow(norm(X_def[idx_img])) ax[i][2].axis('off') ax[i][2].set_title(label[preds_def[idx_img]]) plt.savefig('assets/plot_mnist_' + method_type + '.png') #### Adversarial defenses ########### ### PREPROCESS ################### # Feature Squeezing https://arxiv.org/abs/1704.01155 preproc = FeatureSqueezing(clip_values=(0, 1), bit_depth=1) X_def, _ = preproc(X_adv) preds_X_def = np.argmax(classifier.predict(X_def), axis=1) fooling_rate = np.sum(preds_X_def != np.argmax(y_test, axis=1)) / y_test.shape[0] logger.info('Fooling rate after Feature Squeezing: %.2f%%', (fooling_rate * 100)) img_plot(y_test, preds_x_test, preds_X_adv, preds_X_def, x_test, X_adv, X_def, "feature_squeezing") # Spatial Smoothing https://arxiv.org/abs/1704.01155 spatial_smoothing = SpatialSmoothing(window_size=4) X_def, _ = spatial_smoothing(X_adv) preds_X_def = np.argmax(classifier.predict(X_def), axis=1) fooling_rate = np.sum(preds_X_def != np.argmax(y_test, axis=1)) / y_test.shape[0] logger.info('Fooling rate after Spatial Smoothing: %.2f%%', (fooling_rate * 100)) img_plot(y_test, preds_x_test, preds_X_adv, preds_X_def, x_test, X_adv, X_def, "spatial_smoothing") # Label Smoothing https://pdfs.semanticscholar.org/b5ec/486044c6218dd41b17d8bba502b32a12b91a.pdf
def defencer(adv_data, defence_method, clip_values, eps=16, bit_depth=8, apply_fit=False, apply_predict=True): ''' :param adv_data: np.ndarray | [N C H W ] :param defence_method: | str :param clip_values:Tuple of the form `(min, max)` representing the minimum and maximum values allowed for features. | `tuple` :param bit_depth: The number of bits per channel for encoding the data. | 'int' :param apply_fit: True if applied during fitting/training. | bool :param apply_predict: True if applied during predicting. | bool :return: defended data | np.ndarray | [N C H W] ''' # step 1. define a defencer if defence_method == "FeatureSqueezing": defence = FeatureSqueezing(clip_values=clip_values, bit_depth=bit_depth, apply_fit=apply_fit, apply_predict=apply_predict) elif defence_method == "PixelDefend": criterion = nn.CrossEntropyLoss() # fm = 64 # pixel_cnn_model = nn.Sequential( # MaskedConv2d('A', 3, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # MaskedConv2d('B', fm, fm, 7, 1, 3, bias=False), nn.BatchNorm2d(fm), nn.ReLU(True), # nn.Conv2d(fm, 256, 1)) pixel_cnn_model = Pixel_cnn_net().cuda() pixel_cnn_model = torch.load("models/pixel_cnn_epoch_29.pth") # pixel_cnn_model = PixelCNN().cuda() # print(pixel_cnn_model) optimizer = optim.Adam(pixel_cnn_model.parameters()) pixel_cnn = PyTorchClassifier( model=pixel_cnn_model, clip_values=(0, 1), loss=criterion, optimizer=optimizer, input_shape=(3, 32, 32), nb_classes=10, ) defence = PixelDefend(clip_values=clip_values, eps=eps, pixel_cnn=pixel_cnn, apply_fit=apply_fit, apply_predict=apply_predict) adv_data = np.transpose(adv_data, [0, 3, 2, 1]) elif defence_method == "ThermometerEncoding": defence = ThermometerEncoding(clip_values=clip_values) elif defence_method == "TotalVarMin": defence = TotalVarMin(clip_values=clip_values) elif defence_method == "JPEGCompression": defence = JpegCompression(clip_values=clip_values) elif defence_method == "SpatialSmoothing": defence = SpatialSmoothing(clip_values=clip_values) adv_data = np.transpose(adv_data, [0, 3, 2, 1]) # step2. defend # print(adv_data.shape) res = defence(adv_data)[0] res = np.transpose(res, [0, 3, 2, 1]) # print(res.shape) return res
def _image_dl_estimator_defended(one_classifier=False, **kwargs): sess = None classifier_list = None clip_values = (0, 1) fs = FeatureSqueezing(bit_depth=2, clip_values=clip_values) defenses = [] if kwargs.get("defenses") is None: defenses.append(fs) else: if "FeatureSqueezing" in kwargs.get("defenses"): defenses.append(fs) if "JpegCompression" in kwargs.get("defenses"): defenses.append( JpegCompression(clip_values=clip_values, apply_predict=True)) if "SpatialSmoothing" in kwargs.get("defenses"): defenses.append(SpatialSmoothing()) del kwargs["defenses"] if framework == "keras": classifier = get_image_classifier_kr(**kwargs) # Get the ready-trained Keras model classifier_list = [ KerasClassifier(model=classifier._model, clip_values=(0, 1), preprocessing_defences=defenses) ] if framework == "tensorflow": logging.warning( "{0} doesn't have a defended image classifier defined yet". format(framework)) if framework == "pytorch": logging.warning( "{0} doesn't have a defended image classifier defined yet". format(framework)) if framework == "scikitlearn": logging.warning( "{0} doesn't have a defended image classifier defined yet". format(framework)) if framework == "kerastf": classifier = get_image_classifier_kr_tf(**kwargs) classifier_list = [ KerasClassifier(model=classifier._model, clip_values=(0, 1), preprocessing_defences=defenses) ] if classifier_list is None: return None, None if one_classifier: return classifier_list[0], sess return classifier_list, sess