Trusted-AI / adversarial-robustness-toolbox

Adversarial Robustness Toolbox (ART) - Python Library for Machine Learning Security - Evasion, Poisoning, Extraction, Inference - Red and Blue Teams
https://adversarial-robustness-toolbox.readthedocs.io/en/latest/
MIT License
4.87k stars 1.17k forks source link

`art.attack.evasion.LowProFool` encounter bugs when using L_1-norm (or 0<p<2) #1970

Open ZhipengHe opened 1 year ago

ZhipengHe commented 1 year ago

Describe the bug

When using art.attack.evasion.LowProFool method, if I set parameter norm in the range of $p \in (0, 2)$, the attack model will report ValueError.

To Reproduce Steps to reproduce the behavior:

  1. Go to my notebook (gist)
  2. When set the norm>=2 or norm='inf' , the attack model works well. For example,
    success_rate=test_general_cancer_lr(breast_cancer_dataset(splitter()), norm=2)
    print(success_rate)

    Result is :

    1.0
  3. When set the 0<norm<2, the attack model doesn't work. For example,
    success_rate=test_general_cancer_lr(breast_cancer_dataset(splitter()), norm=1)
    print(success_rate)

    Error:

    /usr/local/lib/python3.8/dist-packages/art/attacks/evasion/lowprofool.py:159: RuntimeWarning: divide by zero encountered in power
    self.importance_vec * self.importance_vec * perturbations * np.power(np.abs(perturbations), norm - 2)
    /usr/local/lib/python3.8/dist-packages/art/attacks/evasion/lowprofool.py:159: RuntimeWarning: invalid value encountered in multiply
    self.importance_vec * self.importance_vec * perturbations * np.power(np.abs(perturbations), norm - 2)
    ...
    ...
    ValueError: Input contains NaN, infinity or a value too large for dtype('float32').

    From RuntimeWarning: divide by zero encountered in power, In LowProFool L307-L313 , the attack model initialized the perturbation with np.zero

    
    # Initialize perturbation vectors and learning rate.
    perturbations = np.zeros(samples.shape, dtype=np.float64)
    eta = self.eta

Initialize 'keep-the-best' variables.

best_norm_losses = np.inf * np.ones(samples.shape[0], dtype=np.float64) best_perturbations = perturbations.copy()

In `LowProFool` [L148-L171](https://github.com/Trusted-AI/adversarial-robustness-toolbox/blob/main/art/attacks/evasion/lowprofool.py#L148-L171) , when `0< norm <2`, it will encounter ` divide by zero` error.

```python
  numerator = (
      self.importance_vec * self.importance_vec * perturbations * np.power(np.abs(perturbations), norm - 2)
  )

Expected behavior The attack model should also generate adversarial examples succuessfully.

System information (please complete the following information):

beat-buesser commented 1 year ago

Hi @ZhipengHe Thank you very much for the detailed description of the issue! Please apologize my delayed response. It looks like the issue is that if in the last code segment in our message above for norm < 2 will result in 1 / perturbations^abs(norm). This creates the division by zero error of any element of perturbations is zero. I think for norm < 2 we would have to add a check that perturbations has to be larger than zero at all times.