55- `fgsm(model, x, y, epsilon=0.01)`: Fast Gradient Sign Method (FGSM) attack.
66- `pgd(model, x, y, epsilon=0.01, alpha=0.01, num_steps=10)`: Projected Gradient Descent (PGD) attack.
77- `bim(model, x, y, epsilon=0.01, alpha=0.01, num_steps=10)`: Basic Iterative Method (BIM) attack.
8-
8+ - `cw(model, x, y, epsilon=0.01, c=1, kappa=0, num_steps=10, alpha=0.01)`: Carlini & Wagner (C&W) attack.
9+ - `deepfool(model, x, y, num_steps=10)`: DeepFool attack.
10+ - `jsma(model, x, y, theta=0.1, gamma=0.1, num_steps=10)`: Jacobian-based Saliency Map Attack (JSMA).
911"""
1012
1113import numpy as np
@@ -100,4 +102,122 @@ def bim(model, x, y, epsilon=0.01, alpha=0.01, num_steps=10):
100102 adversarial_example = tf .clip_by_value (adversarial_example + perturbation , 0 , 1 )
101103 adversarial_example = tf .clip_by_value (adversarial_example , x - epsilon , x + epsilon )
102104
105+ return adversarial_example .numpy ()
106+
107+ def cw (model , x , y , epsilon = 0.01 , c = 1 , kappa = 0 , num_steps = 10 , alpha = 0.01 ):
108+ """
109+ Carlini & Wagner (C&W) attack.
110+
111+ Parameters:
112+ model (tensorflow.keras.Model): The target model to attack.
113+ x (numpy.ndarray): The input example to attack.
114+ y (numpy.ndarray): The true labels of the input example.
115+ epsilon (float): The maximum magnitude of the perturbation (default: 0.01).
116+ c (float): The weight of the L2 norm of the perturbation (default: 1).
117+ kappa (float): The confidence parameter (default: 0).
118+ num_steps (int): The number of C&W iterations (default: 10).
119+ alpha (float): The step size for each iteration (default: 0.01).
120+
121+ Returns:
122+ adversarial_example (numpy.ndarray): The perturbed input example.
123+ """
124+ # Define the loss function
125+ def loss_function (x , y , model , c , kappa ):
126+ prediction = model (x )
127+ loss = tf .keras .losses .CategoricalCrossentropy ()(y , prediction )
128+ return loss + c * tf .norm (x - tf .clip_by_value (x , 0 , 1 )) ** 2 - kappa
129+
130+ # Initialize the adversarial example
131+ adversarial_example = tf .identity (x )
132+
133+ # Perform the C&W attack
134+ for _ in range (num_steps ):
135+ with tf .GradientTape () as tape :
136+ tape .watch (adversarial_example )
137+ loss = loss_function (adversarial_example , y , model , c , kappa )
138+
139+ gradient = tape .gradient (loss , adversarial_example )
140+ perturbation = alpha * tf .sign (gradient )
141+ adversarial_example = tf .clip_by_value (adversarial_example + perturbation , 0 , 1 )
142+ adversarial_example = tf .clip_by_value (adversarial_example , x - epsilon , x + epsilon )
143+
144+ return adversarial_example .numpy ()
145+
146+ def deepfool (model , x , y , num_steps = 10 ):
147+ """
148+ DeepFool attack.
149+
150+ Parameters:
151+ model (tensorflow.keras.Model): The target model to attack.
152+ x (numpy.ndarray): The input example to attack.
153+ y (numpy.ndarray): The true labels of the input example.
154+ num_steps (int): The number of DeepFool iterations (default: 10).
155+
156+ Returns:
157+ adversarial_example (numpy.ndarray): The perturbed input example.
158+ """
159+ # Initialize the adversarial example
160+ adversarial_example = tf .identity (x )
161+
162+ # Perform the DeepFool attack
163+ for _ in range (num_steps ):
164+ with tf .GradientTape () as tape :
165+ tape .watch (adversarial_example )
166+ prediction = model (adversarial_example )
167+ loss = tf .keras .losses .CategoricalCrossentropy ()(y , prediction )
168+
169+ gradient = tape .gradient (loss , adversarial_example )
170+ perturbation = gradient / tf .norm (gradient )
171+ adversarial_example = adversarial_example + perturbation
172+
173+ return adversarial_example .numpy ()
174+
175+ def jsma (model , x , y , theta = 0.1 , gamma = 0.1 , num_steps = 10 ):
176+ """
177+ Jacobian-based Saliency Map Attack (JSMA) attack.
178+
179+ Parameters:
180+ model (tensorflow.keras.Model): The target model to attack.
181+ x (numpy.ndarray): The input example to attack.
182+ y (numpy.ndarray): The true labels of the input example.
183+ theta (float): The threshold for selecting pixels (default: 0.1).
184+ gamma (float): The step size for each iteration (default: 0.1).
185+ num_steps (int): The number of JSMA iterations (default: 10).
186+
187+ Returns:
188+ adversarial_example (numpy.ndarray): The perturbed input example.
189+ """
190+ # Initialize the adversarial example
191+ adversarial_example = tf .identity (x )
192+
193+ # Get the input shape
194+ input_shape = x .shape
195+
196+ # Perform the JSMA attack
197+ for _ in range (num_steps ):
198+ # Calculate the Jacobian matrix
199+ with tf .GradientTape () as tape :
200+ tape .watch (adversarial_example )
201+ prediction = model (adversarial_example )
202+ loss = tf .keras .losses .CategoricalCrossentropy ()(y , prediction )
203+
204+ jacobian = tape .jacobian (loss , adversarial_example )
205+
206+ # Calculate the saliency map
207+ saliency_map = np .zeros (input_shape )
208+ for i in range (input_shape [1 ]):
209+ for j in range (input_shape [2 ]):
210+ for k in range (input_shape [3 ]):
211+ saliency_map [0 , i , j , k ] = np .sum (jacobian [0 , i , j , k , :])
212+
213+ # Select the pixels to perturb
214+ perturbed_pixels = np .where (saliency_map > theta )
215+
216+ # Perturb the selected pixels
217+ for i in range (len (perturbed_pixels [0 ])):
218+ if adversarial_example [0 , perturbed_pixels [0 ][i ], perturbed_pixels [1 ][i ], perturbed_pixels [2 ][i ]] < 1 :
219+ adversarial_example [0 , perturbed_pixels [0 ][i ], perturbed_pixels [1 ][i ], perturbed_pixels [2 ][i ]] += gamma
220+ else :
221+ adversarial_example [0 , perturbed_pixels [0 ][i ], perturbed_pixels [1 ][i ], perturbed_pixels [2 ][i ]] -= gamma
222+
103223 return adversarial_example .numpy ()
0 commit comments