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:
- Define and fit a Random Forest Classifier using the sklearn library
model = RandomForestClassifier(verbose=0, n_estimators=1)
model.fit(X_train, y_train)
- Define a sklearn classifier object
classifier = SklearnClassifier(model=model)
- Generate adversarial samples
attack = GeoDA(classifier)
x_test_true_positives_adv = attack.generate(X_test_true_positives)
- 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!