Trusted-AI/adversarial-robustness-toolbox

Geometric Decision Based Attack (`GeoDA`) uncompatible with `ScikitlearnRandomForestClassifier` - Missing Error Handling

jetlime opened this issue · 5 comments

Describe the bug
Whenever performing an Geometric Decision Based Attack evasion attack on a scikit-learn random forest classifier.

To Reproduce

Steps to reproduce the behavior:

  1. Define and fit a Random Forest Classifier using the sklearn library
model = RandomForestClassifier(verbose=0, n_estimators=1)
model.fit(X_train, y_train)
  1. Define a sklearn classifier object
classifier = SklearnClassifier(model=model)
  1. Generate adversarial samples
attack = GeoDA(classifier)
x_test_true_positives_adv = attack.generate(X_test_true_positives)
  1. See error:
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
Cell In[34], [line 15](notebook-cell:?execution_count=34&line=15)
     [10](notebook-cell:?execution_count=34&line=10) classifier = SklearnClassifier(model=model)
     [11](notebook-cell:?execution_count=34&line=11) X_test_true_positives, y_test_true_positives, prediction_classes, y_test, _, _, _ = scores[
     [12](notebook-cell:?execution_count=34&line=12)     fold
     [13](notebook-cell:?execution_count=34&line=13) ]
---> [15](notebook-cell:?execution_count=34&line=15) attack = GeoDA(classifier)
     [16](notebook-cell:?execution_count=34&line=16) x_test_true_positives_adv = attack.generate(X_test_true_positives)
     [18](notebook-cell:?execution_count=34&line=18) evasion_rate, adversarial_samples_amount = evasion_evaluation(
     [19](notebook-cell:?execution_count=34&line=19)     model, x_test_true_positives_adv, y_test_true_positives
     [20](notebook-cell:?execution_count=34&line=20) )

File ~venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:114, in GeoDA.__init__(self, estimator, batch_size, norm, sub_dim, max_iter, bin_search_tol, lambda_param, sigma, verbose)
    [111](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:111) if self.estimator.input_shape is None:  # pragma: no cover
    [112](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:112)     raise ValueError("The `input_shape` of the is required but None.")
    [113](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:113) self.nb_channels = (
--> [114](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:114)     self.estimator.input_shape[0] if self.estimator.channels_first else self.estimator.input_shape[2]
    [115](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:115) )
    [117](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:117) # Optimal number of iterations
    [118](venv/lib/python3.10/site-packages/art/attacks/evasion/geometric_decision_based_attack.py:118) iteration = round(self.max_iter / 500)

AttributeError: 'ScikitlearnRandomForestClassifier' object has no attribute 'channels_first'

Expected behavior

A clear and concise error explaining that the ScikitlearnRandomForestClassifier is not compatible with the GeoDA attack.
For instance:

EstimatorError: GeoDA requires an estimator derived from ..., the provided classifier is an instance of <class 'art.estimators.classification.scikitlearn.ScikitlearnRandomForestClassifier'> and is derived from (<class 'art.estimators.classification.scikitlearn.ScikitlearnClassifier'>,).

System information (please complete the following information):

  • OS: Ubuntu 22
  • Python version: 3.10
  • ART version or commit number: 1.18.1

Hey @jetlime
Is this issue still open? i would like to contribute.
I came across the ART recently and saw this open issue.
We can do couple of things, consider switching to a neural network-based estimator compatible with GeoDA. Alternatively, we can extend the Random Forest classifier to include the required input_shape and channels_first attributes.

Hi @jetlime Thank you very much, I think this is a bug. We should either define GeoDA to be only compatible with neural network classifiers or extend the scikit-learn classifier's to provide the channels_first property.

@VishalGawade1 Would you still be interested to make a pull request for this issue? I'd be happy to help

Hello @beat-buesser ,
Of course, I'd love to contribute! Let me know how we can proceed.

Hello @beat-buesser ,
I’ve fixed the issue with GeoDA and Scikit-learn's RandomForestClassifier. I added a compatibility check in GeoDA’s constructor, so now it only works with neural network-based classifiers that have input_shape and channels_first.

This approach keeps GeoDA focused on its intended purpose and raises a clear ValueError when it’s used with incompatible models like RandomForestClassifier, without needing to modify scikit-learn itself.

Waiting for your response! Let me know how you want me to proceed

Hi! Sorry for closing the previous PR. I realized I forgot to sign off. I’ve raised a new PR, please let me know if any further adjustments are needed. Thank you!