def test_4_pytorch_classifier(self):
        """
        Third test with the PyTorchClassifier.
        :return:
        """
        x_test = np.transpose(self.x_test_mnist, (0, 3, 1, 2)).astype(np.float32)
        x_test_init = np.transpose(self.x_test_init_mnist, (0, 3, 1, 2)).astype(np.float32)
        x_test_original = x_test.copy()

        # Build PyTorchClassifier
        ptc = get_image_classifier_pt()

        # BLACKBOX
        # First attack
        graphite = GRAPHITEBlackbox(
            classifier=ptc,
            noise_size=(28, 28),
            net_size=(28, 28),
            heatmap_mode="Target",
            num_xforms_mask=2,
            num_xforms_boost=10,
            rotation_range=(-5, 5),
            gamma_range=(1.0, 1.1),
            crop_percent_range=(-0.001, 0.001),
            off_x_range=(-0.001, 0.001),
            blur_kernels=[0],
        )
        params = {"y": self.y_test_init_mnist, "x_tar": x_test_init}
        x_test_adv = graphite.generate(x_test, **params)

        self.assertFalse((x_test == x_test_adv).all())
        self.assertTrue((x_test_adv <= 1.0001).all())
        self.assertTrue((x_test_adv >= -0.0001).all())

        target = np.argmax(params["y"], axis=1)
        y_pred_adv = np.argmax(ptc.predict(x_test_adv), axis=1)
        self.assertTrue((target == y_pred_adv).any())

        # Test the masking
        mask = np.random.binomial(n=1, p=0.5, size=np.prod(x_test.shape))
        mask = mask.reshape(x_test.shape)

        params.update(mask=mask)
        x_test_adv = graphite.generate(x_test, **params)
        mask_diff = (1 - mask) * (x_test_adv - x_test)
        self.assertAlmostEqual(float(np.max(np.abs(mask_diff))), 0.0, delta=0.00001)

        unmask_diff = mask * (x_test_adv - x_test)
        self.assertGreater(float(np.sum(np.abs(unmask_diff))), 0.0)

        # Test passing in points
        pts = np.zeros((4, 3, 1))
        pts[0, :, 0] = np.array([0.05, 0.05, 1])
        pts[1, :, 0] = np.array([0.05, 0.95, 1])
        pts[2, :, 0] = np.array([0.95, 0.05, 1])
        pts[3, :, 0] = np.array([0.95, 0.95, 1])

        params.update(pts=pts)
        x_test_adv = graphite.generate(x_test, **params)
        mask_diff = (1 - mask) * (x_test_adv - x_test)
        self.assertAlmostEqual(float(np.max(np.abs(mask_diff))), 0.0, delta=0.00001)

        unmask_diff = mask * (x_test_adv - x_test)
        self.assertGreater(float(np.sum(np.abs(unmask_diff))), 0.0)

        # Check that x_test has not been modified by attack and classifier
        self.assertAlmostEqual(float(np.max(np.abs(x_test_original - x_test))), 0.0, delta=0.00001)

        # WHITEBOX
        # First attack
        graphite = GRAPHITEWhiteboxPyTorch(classifier=ptc, net_size=(28, 28), num_xforms=10)
        params = {"y": self.y_test_init_mnist}
        x_test_adv = graphite.generate(x_test, **params)

        self.assertFalse((x_test == x_test_adv).all())
        self.assertTrue((x_test_adv <= 1.0001).all())
        self.assertTrue((x_test_adv >= -0.0001).all())

        target = np.argmax(params["y"], axis=1)
        y_pred_adv = np.argmax(ptc.predict(x_test_adv), axis=1)
        self.assertTrue((target == y_pred_adv).any())

        # Test the masking
        mask = np.random.binomial(n=1, p=0.5, size=np.prod(x_test.shape))
        mask = mask.reshape(x_test.shape)

        params.update(mask=mask)
        x_test_adv = graphite.generate(x_test, **params)
        mask_diff = (1 - mask) * (x_test_adv - x_test)
        self.assertAlmostEqual(float(np.max(np.abs(mask_diff))), 0.0, delta=0.00001)

        unmask_diff = mask * (x_test_adv - x_test)
        self.assertGreater(float(np.sum(np.abs(unmask_diff))), 0.0)

        # Test passing in points
        pts = np.zeros((4, 3, 1))
        pts[0, :, 0] = np.array([0.05, 0.05, 1])
        pts[1, :, 0] = np.array([0.05, 0.95, 1])
        pts[2, :, 0] = np.array([0.95, 0.05, 1])
        pts[3, :, 0] = np.array([0.95, 0.95, 1])

        params.update(pts=pts)
        x_test_adv = graphite.generate(x_test, **params)
        mask_diff = (1 - mask) * (x_test_adv - x_test)
        self.assertAlmostEqual(float(np.max(np.abs(mask_diff))), 0.0, delta=0.00001)

        unmask_diff = mask * (x_test_adv - x_test)
        self.assertGreater(float(np.sum(np.abs(unmask_diff))), 0.0)

        # Check that x_test has not been modified by attack and classifier
        self.assertAlmostEqual(float(np.max(np.abs(x_test_original - x_test))), 0.0, delta=0.00001)

        Third test with the PyTorchClassifier.
        :return:
        
tests/attacks/test_graphite.py