3434 ClassifierGradients ,
3535)
3636from art .attacks .attack import EvasionAttack
37- from art .utils import compute_success
37+ from art .utils import compute_success , is_probability
3838
3939logger = logging .getLogger (__name__ )
4040
@@ -78,6 +78,12 @@ def __init__(
7878 self .nb_grads = nb_grads
7979 self .batch_size = batch_size
8080 self ._check_params ()
81+ if self .estimator .clip_values is None :
82+ logger .warning (
83+ "The `clip_values` attribute of the estimator is `None`, therefore this instance of DeepFool will by "
84+ "default generate adversarial perturbations scaled for input values in the range [0, 1] but not clip "
85+ "the adversarial example."
86+ )
8187
8288 def generate (self , x : np .ndarray , y : Optional [np .ndarray ] = None , ** kwargs ) -> np .ndarray :
8389 """
@@ -90,6 +96,12 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
9096 x_adv = x .astype (ART_NUMPY_DTYPE )
9197 preds = self .estimator .predict (x , batch_size = self .batch_size )
9298
99+ if is_probability (preds [0 ]):
100+ logger .warning (
101+ "It seems that the attacked model is predicting probabilities. DeepFool expects logits as model output "
102+ "to achieve its full attack strength."
103+ )
104+
93105 # Determine the class labels for which to compute the gradients
94106 use_grads_subset = self .nb_grads < self .estimator .nb_classes
95107 if use_grads_subset :
@@ -106,7 +118,7 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
106118 # Compute perturbation with implicit batching
107119 for batch_id in trange (int (np .ceil (x_adv .shape [0 ] / float (self .batch_size ))), desc = "DeepFool" ):
108120 batch_index_1 , batch_index_2 = batch_id * self .batch_size , (batch_id + 1 ) * self .batch_size
109- batch = x_adv [batch_index_1 :batch_index_2 ]
121+ batch = x_adv [batch_index_1 :batch_index_2 ]. copy ()
110122
111123 # Get predictions and gradients for batch
112124 f_batch = preds [batch_index_1 :batch_index_2 ]
@@ -143,7 +155,8 @@ def generate(self, x: np.ndarray, y: Optional[np.ndarray] = None, **kwargs) -> n
143155 # Add perturbation and clip result
144156 if self .estimator .clip_values is not None :
145157 batch [active_indices ] = np .clip (
146- batch [active_indices ] + r_var [active_indices ],
158+ batch [active_indices ]
159+ + r_var [active_indices ] * (self .estimator .clip_values [1 ] - self .estimator .clip_values [0 ]),
147160 self .estimator .clip_values [0 ],
148161 self .estimator .clip_values [1 ],
149162 )
0 commit comments