Ejemplo n.º 1
0
def test_general_wines_lr(wine_dataset):
    """
    Check whether the produced adversaries are correct,
    given Logistic Regression classifier and sklearn wines dataset.
    """
    (x_train, y_train, x_valid, y_valid), _, clip_values = wine_dataset

    # Setup classifier
    lr_clf = LogisticRegression(penalty="none")
    lr_clf.fit(x_train, y_train)
    clf_slr = ScikitlearnLogisticRegression(model=lr_clf,
                                            clip_values=clip_values)

    lpf_slr = LowProFool(classifier=clf_slr, n_steps=80, eta=0.1, lambd=1.25)
    lpf_slr.fit_importances(x_train, y_train)

    sample = x_valid
    # Draw targets different from original labels and then save as one-hot encoded.
    target = np.eye(3)[np.array(
        y_valid.apply(
            lambda x: np.random.choice([i for i in [0, 1, 2] if i != x])))]

    adversaries = lpf_slr.generate(x=sample, y=target)
    expected = np.argmax(target, axis=1)
    predicted = np.argmax(lr_clf.predict_proba(adversaries), axis=1)
    correct = expected == predicted

    success_rate = np.sum(correct) / correct.shape[0]
    expected = 0.75

    logger.info(
        "[Wines, Scikit-learn Logistic Regression] success rate of adversarial attack (expected >{:.2f}):"
        " {:.2f}%".format(expected * 100, success_rate * 100))
    assert success_rate > expected
    def setUpClass(cls):
        master_seed(seed=1234)
        super().setUpClass()

        cls.sklearn_model = LogisticRegression(
            verbose=0, C=1, solver="newton-cg", dual=False, fit_intercept=True, multi_class="ovr"
        )
        cls.classifier = ScikitlearnLogisticRegression(model=cls.sklearn_model)
        cls.classifier.fit(x=cls.x_train_iris, y=cls.y_train_iris)
    def setUpClass(cls):
        master_seed(seed=1234)
        super().setUpClass()

        binary_class_index = np.argmax(cls.y_train_iris, axis=1) < 2
        x_train_binary = cls.x_train_iris[
            binary_class_index,
        ]
        y_train_binary = cls.y_train_iris[binary_class_index,][:, [0, 1]]

        cls.sklearn_model = LogisticRegression(
            verbose=0, C=1, solver="newton-cg", dual=False, fit_intercept=True, multi_class="ovr"
        )
        cls.classifier = ScikitlearnLogisticRegression(model=cls.sklearn_model)
        cls.classifier.fit(x=x_train_binary, y=y_train_binary)
def test_database_reconstruction_logistic_regression(get_iris_dataset):
    (x_train_iris, y_train_iris), (x_test_iris, y_test_iris) = get_iris_dataset
    y_train_iris = np.array([np.argmax(y) for y in y_train_iris])
    y_test_iris = np.array([np.argmax(y) for y in y_test_iris])

    x_private = x_test_iris[0, :].reshape(1, -1)
    y_private = y_test_iris[0]

    x_input = np.vstack((x_train_iris, x_private))
    y_input = np.hstack((y_train_iris, y_private))

    nb_private = LogisticRegression()
    nb_private.fit(x_input, y_input)
    estimator_private = ScikitlearnLogisticRegression(model=nb_private)

    recon = DatabaseReconstruction(estimator=estimator_private)
    x_recon, y_recon = recon.reconstruct(x_train_iris, y_train_iris)

    assert x_recon is not None
    assert x_recon.shape == (1, 4)
    assert y_recon.shape == (1, 3)
    assert np.isclose(x_recon, x_private, rtol=0.05).all()
    assert np.argmax(y_recon, axis=1) == y_private
Ejemplo n.º 5
0
 def test_type(self):
     self.assertIsInstance(
         self.classifier, type(SklearnClassifier(model=self.sklearn_model)))
     with self.assertRaises(TypeError):
         ScikitlearnLogisticRegression(model="sklearn_model")
Ejemplo n.º 6
0
def test_clipping(iris_dataset):
    """
    Check weather adversaries are clipped properly.
    """
    (x_train, y_train, x_valid, y_valid), _, clip_values = iris_dataset

    # Setup classifier
    lr_clf = LogisticRegression(penalty="none")
    lr_clf.fit(x_train, y_train)

    # Dataset min-max clipping values
    bottom_min, top_max = clip_values
    clf_slr_min_max = ScikitlearnLogisticRegression(model=lr_clf,
                                                    clip_values=(bottom_min,
                                                                 top_max))

    # Clip values
    bottom_custom = -3
    top_custom = 3
    clf_slr_custom = ScikitlearnLogisticRegression(model=lr_clf,
                                                   clip_values=(bottom_custom,
                                                                top_custom))

    # Setting up LowProFool classes with different hyper-parameters
    lpf_min_max_default = LowProFool(classifier=clf_slr_min_max,
                                     n_steps=45,
                                     eta=0.02,
                                     lambd=1.5)
    lpf_min_max_high_eta = LowProFool(classifier=clf_slr_min_max,
                                      n_steps=45,
                                      eta=100000,
                                      lambd=1.5)
    lpf_custom_default = LowProFool(classifier=clf_slr_custom,
                                    n_steps=45,
                                    eta=0.02,
                                    lambd=1.5)
    lpf_custom_high_eta = LowProFool(classifier=clf_slr_custom,
                                     n_steps=45,
                                     eta=100000,
                                     lambd=1.5)

    lpf_min_max_default.fit_importances(x_train, y_train)
    lpf_min_max_high_eta.fit_importances(x_train, y_train)
    lpf_custom_default.fit_importances(x_train, y_train)
    lpf_custom_high_eta.fit_importances(x_train, y_train)

    # Generating adversaries
    sample = np.array([[5.5, 2.4, 3.7, 1.0]])
    target = np.array([[0.0, 0.0, 1.0]])

    adversaries_min_max_default = lpf_min_max_default.generate(x=sample,
                                                               y=target)
    adversaries_min_max_high_eta = lpf_min_max_high_eta.generate(x=sample,
                                                                 y=target)
    adversaries_custom_default = lpf_custom_default.generate(x=sample,
                                                             y=target)
    adversaries_custom_high_eta = lpf_custom_high_eta.generate(x=sample,
                                                               y=target)

    # Checking whether adversaries were clipped properly
    eps = 1e-6
    is_valid_1 = (
        (bottom_min - eps).to_numpy() <=
        adversaries_min_max_default).all() and (
            (top_max + eps).to_numpy() >= adversaries_min_max_default).all()
    is_valid_2 = (
        (bottom_min - eps).to_numpy() <=
        adversaries_min_max_high_eta).all() and (
            (top_max + eps).to_numpy() >= adversaries_min_max_high_eta).all()
    is_valid_3 = (
        (bottom_custom - eps) <= adversaries_custom_default).all() and (
            (top_custom + eps) >= adversaries_custom_default).all()
    is_valid_4 = (bottom_custom - eps <= adversaries_custom_high_eta).all(
    ) and (top_custom + eps >= adversaries_custom_high_eta).all()

    is_clipping_valid = is_valid_1 and is_valid_2 and is_valid_3 and is_valid_4
    if is_clipping_valid:
        logger.info(
            "[Iris flower, Scikit-learn Logistic Regression] Clipping is valid."
        )
    else:
        logger.info(
            "[Iris flower, Scikit-learn Logistic Regression] Clipping is invalid."
        )

    assert is_valid_1
    assert is_valid_2
    assert is_valid_3
    assert is_valid_4
Ejemplo n.º 7
0
def test_fit_importances(iris_dataset):
    """
    Check whether feature importance is calculated properly.
    """
    (x_train, y_train, x_valid, y_valid), _, clip_values = iris_dataset

    def pearson_correlations(x, y):
        correlations = [pearsonr(x[:, col], y)[0] for col in range(x.shape[1])]
        absolutes = np.abs(np.array(correlations))
        result = absolutes / np.power(np.sum(absolutes**2), 0.5)
        return result

    # Setup classifier
    lr_clf = LogisticRegression(penalty="none")
    lr_clf.fit(x_train, y_train)
    clf_slr = ScikitlearnLogisticRegression(model=lr_clf,
                                            clip_values=clip_values)

    # User defined vector
    vector = pearson_correlations(np.array(x_train), np.array(y_train))

    # 3 different instances of LowProFool, using 3 different ways of specifying importance

    # Default version - using pearson correlation under the hood
    lpf_slr_default = LowProFool(classifier=clf_slr,
                                 n_steps=45,
                                 eta=0.02,
                                 lambd=1.5,
                                 importance="pearson")

    # Predefined vector, passed in LowProFool initialization
    lpf_slr_vec = LowProFool(classifier=clf_slr,
                             n_steps=45,
                             eta=0.02,
                             lambd=1.5,
                             importance=vector)

    # User defined function
    lpf_slr_fun = LowProFool(classifier=clf_slr,
                             n_steps=45,
                             eta=0.02,
                             lambd=1.5,
                             importance=pearson_correlations)

    lpf_slr_default.fit_importances(x_train, y_train)
    lpf_slr_vec.fit_importances(x_train, y_train)
    lpf_slr_fun.fit_importances(x_train, y_train, normalize=False)

    importance_default = lpf_slr_default.importance_vec
    importance_vec_init = lpf_slr_vec.importance_vec
    importance_function = lpf_slr_fun.importance_vec

    # Predefined vector passed while fitting
    lpf_slr_default.fit_importances(x_train, y_train, importance_array=vector)
    importance_vec_fit = lpf_slr_default.importance_vec

    # Vector normalization
    vector_norm = vector / np.sum(vector)

    is_default_valid = (vector_norm == importance_default).all()
    is_custom_fun_valid = (vector == importance_function).all()
    is_vec_init_valid = (vector_norm == importance_vec_init).all()
    is_vec_fit_valid = (vector_norm == importance_vec_fit).all()

    logger.info(
        "[Iris flower, Scikit-learn Logistic Regression] Importance fitting test:"
    )
    if not is_default_valid:
        logger.info("Fitting importance by default is invalid")
    elif not is_custom_fun_valid:
        logger.info("Fitting importance with custom function is invalid")
    elif not is_vec_init_valid:
        logger.info(
            "Fitting importance with vector provided in initializer is invalid"
        )
    elif not is_vec_fit_valid:
        logger.info(
            "Fitting importance with vector provided in fit_importances() is invalid"
        )
    else:
        logger.info(
            "Fitting importance with all available methods went successfully")

    assert is_default_valid
    assert is_custom_fun_valid
    assert is_vec_init_valid
    assert is_vec_fit_valid