pralab / secml_malware

Create adversarial attacks against machine learning Windows malware detectors
https://secml-malware.readthedocs.io/
GNU General Public License v3.0
203 stars 46 forks source link

self.stagnation value is not respected when global min is stuck at inf #16

Closed MariaRigaki closed 3 years ago

MariaRigaki commented 3 years ago

Description In black-box GAMMA attacks sometimes the global min gets stuck at inf. There is a numpy warning after 5 iterations and the optimization continues instead of stopping. Please see below the output for the exact issue:

>0 - Global min: inf
>1 - Global min: inf
>2 - Global min: inf
>3 - Global min: inf
>4 - Global min: inf
2021-06-30 15:20:30,339 - py.warnings - WARNING - /home/mari/miniconda3/envs/adv_mal/lib/python3.8/site-packages/secml_malware/attack/blackbox/ga/c_base_genetic_engine.py:237: RuntimeWarning: invalid value encountered in subtract
  if len(last_n_best_fits) == self.stagnation and all((np.array(last_n_best_fits) - best_fitness) < 1e-6):

>5 - Global min: inf
>6 - Global min: inf
>7 - Global min: inf
>8 - Global min: inf
>9 - Global min: inf
>10 - Global min: inf
>11 - Global min: inf
>12 - Global min: inf
>13 - Global min: inf
>14 - Global min: inf

Expected behavior The optimization should end with a Stagnating result! as output in case debug is enabled.

System info:

zangobot commented 3 years ago

Hello, thank you for this issue! I'll have a look (you are using the hard-labels attack, right?) shortly! I think I know how to patch that, the comparison with the numpy infinity is causing the problem.

MariaRigaki commented 3 years ago

Yes, I have only seen this when using the hard-labels.

zangobot commented 3 years ago

I should have fixed it, tell me if it works!

MariaRigaki commented 3 years ago

I can confirm that it works, thanks! The warning still appears. Not a big deal to be honest, but if you change the order of the terms in the or clause the check for np.infty will be executed first and the warning will disappear completely :)

all(np.array(last_n_best_fits) == np.infty) or all((np.array(last_n_best_fits) - best_fitness) < 1e-6)

zangobot commented 3 years ago

Ok, I'll do that soon! You're right, I was not thinking about the annoying warning!