77import keras .backend as k
88from keras .models import Sequential
99from keras .layers import Dense , Flatten , Conv2D , MaxPooling2D
10+ import torch .nn as nn
11+ import torch .nn .functional as F
12+ import torch .optim as optim
1013
1114from art .attacks .carlini import CarliniL2Method
1215from art .classifiers .tensorflow import TFClassifier
1316from art .classifiers .keras import KerasClassifier
17+ from art .classifiers .pytorch import PyTorchClassifier
1418from art .utils import load_mnist , random_targets
1519
1620
21+ class Model (nn .Module ):
22+ def __init__ (self ):
23+ super (Model , self ).__init__ ()
24+ self .conv = nn .Conv2d (1 , 16 , 5 )
25+ self .pool = nn .MaxPool2d (2 , 2 )
26+ self .fc = nn .Linear (2304 , 10 )
27+
28+ def forward (self , x ):
29+ x = self .pool (F .relu (self .conv (x )))
30+ x = x .view (- 1 , 2304 )
31+ logit_output = self .fc (x )
32+ output = F .softmax (logit_output , dim = 1 )
33+
34+ return logit_output , output
35+
36+
1737class TestCarliniL2 (unittest .TestCase ):
1838 """
1939 A unittest class for testing the Carlini2 attack.
2040 """
41+ def test_failure_attack (self ):
42+ """
43+ Test the corner case when attack is failed.
44+ :return:
45+ """
46+ # Build a TFClassifier
47+ # Define input and output placeholders
48+ self ._input_ph = tf .placeholder (tf .float32 , shape = [None , 28 , 28 , 1 ])
49+ self ._output_ph = tf .placeholder (tf .int32 , shape = [None , 10 ])
50+
51+ # Define the tensorflow graph
52+ conv = tf .layers .conv2d (self ._input_ph , 4 , 5 , activation = tf .nn .relu )
53+ conv = tf .layers .max_pooling2d (conv , 2 , 2 )
54+ fc = tf .contrib .layers .flatten (conv )
55+
56+ # Logits layer
57+ self ._logits = tf .layers .dense (fc , 10 )
58+
59+ # Train operator
60+ self ._loss = tf .reduce_mean (tf .losses .softmax_cross_entropy (logits = self ._logits , onehot_labels = self ._output_ph ))
61+ optimizer = tf .train .AdamOptimizer (learning_rate = 0.01 )
62+ self ._train = optimizer .minimize (self ._loss )
63+
64+ # Tensorflow session and initialization
65+ self ._sess = tf .Session ()
66+ self ._sess .run (tf .global_variables_initializer ())
67+
68+ # Get MNIST
69+ batch_size , nb_train , nb_test = 100 , 1000 , 10
70+ (x_train , y_train ), (x_test , y_test ), _ , _ = load_mnist ()
71+ x_train , y_train = x_train [:nb_train ], y_train [:nb_train ]
72+ x_test , y_test = x_test [:nb_test ], y_test [:nb_test ]
73+
74+ # Train the classifier
75+ tfc = TFClassifier ((0 , 1 ), self ._input_ph , self ._logits , self ._output_ph ,
76+ self ._train , self ._loss , None , self ._sess )
77+ tfc .fit (x_train , y_train , batch_size = batch_size , nb_epochs = 2 )
78+
79+ # Failure attack
80+ cl2m = CarliniL2Method (classifier = tfc , targeted = True , max_iter = 0 , binary_search_steps = 0 ,
81+ learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
82+ params = {'y' : random_targets (y_test , tfc .nb_classes )}
83+ x_test_adv = cl2m .generate (x_test , ** params )
84+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
85+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
86+ np .testing .assert_almost_equal (x_test , x_test_adv , 3 )
87+
2188 def test_tfclassifier (self ):
2289 """
2390 First test with the TFClassifier.
@@ -46,7 +113,7 @@ def test_tfclassifier(self):
46113 self ._sess .run (tf .global_variables_initializer ())
47114
48115 # Get MNIST
49- batch_size , nb_train , nb_test = 100 , 1000 , 10
116+ batch_size , nb_train , nb_test = 100 , 500 , 5
50117 (x_train , y_train ), (x_test , y_test ), _ , _ = load_mnist ()
51118 x_train , y_train = x_train [:nb_train ], y_train [:nb_train ]
52119 x_test , y_test = x_test [:nb_test ], y_test [:nb_test ]
@@ -57,31 +124,38 @@ def test_tfclassifier(self):
57124 tfc .fit (x_train , y_train , batch_size = batch_size , nb_epochs = 2 )
58125
59126 # First attack
60- cl2m = CarliniL2Method (classifier = tfc , targeted = True , max_iter = 100 , binary_search_steps = 10 ,
127+ cl2m = CarliniL2Method (classifier = tfc , targeted = True , max_iter = 10 , binary_search_steps = 10 ,
61128 learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
62129 params = {'y' : random_targets (y_test , tfc .nb_classes )}
63130 x_test_adv = cl2m .generate (x_test , ** params )
64131 self .assertFalse ((x_test == x_test_adv ).all ())
132+ #print(x_test_adv)
133+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
134+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
65135 target = np .argmax (params ['y' ], axis = 1 )
66136 y_pred_adv = np .argmax (tfc .predict (x_test_adv ), axis = 1 )
67137 self .assertTrue ((target == y_pred_adv ).all ())
68138
69139 # Second attack
70- cl2m = CarliniL2Method (classifier = tfc , targeted = False , max_iter = 100 , binary_search_steps = 10 ,
140+ cl2m = CarliniL2Method (classifier = tfc , targeted = False , max_iter = 10 , binary_search_steps = 10 ,
71141 learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
72142 params = {'y' : random_targets (y_test , tfc .nb_classes )}
73143 x_test_adv = cl2m .generate (x_test , ** params )
74144 self .assertFalse ((x_test == x_test_adv ).all ())
145+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
146+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
75147 target = np .argmax (params ['y' ], axis = 1 )
76148 y_pred_adv = np .argmax (tfc .predict (x_test_adv ), axis = 1 )
77149 self .assertTrue ((target != y_pred_adv ).all ())
78150
79151 # Third attack
80- cl2m = CarliniL2Method (classifier = tfc , targeted = False , max_iter = 100 , binary_search_steps = 10 ,
152+ cl2m = CarliniL2Method (classifier = tfc , targeted = False , max_iter = 10 , binary_search_steps = 10 ,
81153 learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
82154 params = {}
83155 x_test_adv = cl2m .generate (x_test , ** params )
84156 self .assertFalse ((x_test == x_test_adv ).all ())
157+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
158+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
85159 y_pred = np .argmax (tfc .predict (x_test ), axis = 1 )
86160 y_pred_adv = np .argmax (tfc .predict (x_test_adv ), axis = 1 )
87161 self .assertTrue ((y_pred != y_pred_adv ).all ())
@@ -96,7 +170,7 @@ def test_krclassifier(self):
96170 k .set_session (session )
97171
98172 # Get MNIST
99- batch_size , nb_train , nb_test = 100 , 1000 , 10
173+ batch_size , nb_train , nb_test = 100 , 500 , 5
100174 (x_train , y_train ), (x_test , y_test ), _ , _ = load_mnist ()
101175 x_train , y_train = x_train [:nb_train ], y_train [:nb_train ]
102176 x_test , y_test = x_test [:nb_test ], y_test [:nb_test ]
@@ -116,35 +190,102 @@ def test_krclassifier(self):
116190 krc .fit (x_train , y_train , batch_size = batch_size , nb_epochs = 2 )
117191
118192 # First attack
119- cl2m = CarliniL2Method (classifier = krc , targeted = True , max_iter = 100 , binary_search_steps = 10 ,
193+ cl2m = CarliniL2Method (classifier = krc , targeted = True , max_iter = 10 , binary_search_steps = 10 ,
120194 learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
121195 params = {'y' : random_targets (y_test , krc .nb_classes )}
122196 x_test_adv = cl2m .generate (x_test , ** params )
123197 self .assertFalse ((x_test == x_test_adv ).all ())
198+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
199+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
124200 target = np .argmax (params ['y' ], axis = 1 )
125201 y_pred_adv = np .argmax (krc .predict (x_test_adv ), axis = 1 )
126202 self .assertTrue ((target == y_pred_adv ).any ())
127203
128204 # Second attack
129- cl2m = CarliniL2Method (classifier = krc , targeted = False , max_iter = 100 , binary_search_steps = 10 ,
205+ cl2m = CarliniL2Method (classifier = krc , targeted = False , max_iter = 10 , binary_search_steps = 10 ,
130206 learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
131207 params = {'y' : random_targets (y_test , krc .nb_classes )}
132208 x_test_adv = cl2m .generate (x_test , ** params )
133209 self .assertFalse ((x_test == x_test_adv ).all ())
210+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
211+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
134212 target = np .argmax (params ['y' ], axis = 1 )
135213 y_pred_adv = np .argmax (krc .predict (x_test_adv ), axis = 1 )
136214 self .assertTrue ((target != y_pred_adv ).all ())
137215
138216 # Third attack
139- cl2m = CarliniL2Method (classifier = krc , targeted = False , max_iter = 100 , binary_search_steps = 10 ,
217+ cl2m = CarliniL2Method (classifier = krc , targeted = False , max_iter = 10 , binary_search_steps = 10 ,
140218 learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
141219 params = {}
142220 x_test_adv = cl2m .generate (x_test , ** params )
143221 self .assertFalse ((x_test == x_test_adv ).all ())
222+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
223+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
144224 y_pred = np .argmax (krc .predict (x_test ), axis = 1 )
145225 y_pred_adv = np .argmax (krc .predict (x_test_adv ), axis = 1 )
146226 self .assertTrue ((y_pred != y_pred_adv ).any ())
147227
228+ def test_ptclassifier (self ):
229+ """
230+ Third test with the PyTorchClassifier.
231+ :return:
232+ """
233+ # Get MNIST
234+ batch_size , nb_train , nb_test = 100 , 1000 , 10
235+ (x_train , y_train ), (x_test , y_test ), _ , _ = load_mnist ()
236+ x_train , y_train = x_train [:nb_train ], np .argmax (y_train [:nb_train ], axis = 1 )
237+ x_test , y_test = x_test [:nb_test ], y_test [:nb_test ]
238+ x_train = np .swapaxes (x_train , 1 , 3 )
239+ x_test = np .swapaxes (x_test , 1 , 3 )
240+
241+ # Create simple CNN
242+ # Define the network
243+ model = Model ()
244+
245+ # Define a loss function and optimizer
246+ loss_fn = nn .CrossEntropyLoss ()
247+ optimizer = optim .Adam (model .parameters (), lr = 0.01 )
248+
249+ # Get classifier
250+ ptc = PyTorchClassifier ((0 , 1 ), model , loss_fn , optimizer , (1 , 28 , 28 ), (10 ,))
251+ ptc .fit (x_train , y_train , batch_size = batch_size , nb_epochs = 1 )
252+
253+ # First attack
254+ cl2m = CarliniL2Method (classifier = ptc , targeted = True , max_iter = 100 , binary_search_steps = 10 ,
255+ learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
256+ params = {'y' : random_targets (y_test , ptc .nb_classes )}
257+ x_test_adv = cl2m .generate (x_test , ** params )
258+ self .assertFalse ((x_test == x_test_adv ).all ())
259+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
260+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
261+ target = np .argmax (params ['y' ], axis = 1 )
262+ y_pred_adv = np .argmax (ptc .predict (x_test_adv ), axis = 1 )
263+ self .assertTrue ((target == y_pred_adv ).any ())
264+
265+ # Second attack
266+ cl2m = CarliniL2Method (classifier = ptc , targeted = False , max_iter = 100 , binary_search_steps = 10 ,
267+ learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
268+ params = {'y' : random_targets (y_test , ptc .nb_classes )}
269+ x_test_adv = cl2m .generate (x_test , ** params )
270+ self .assertFalse ((x_test == x_test_adv ).all ())
271+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
272+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
273+ target = np .argmax (params ['y' ], axis = 1 )
274+ y_pred_adv = np .argmax (ptc .predict (x_test_adv ), axis = 1 )
275+ self .assertTrue ((target != y_pred_adv ).all ())
276+
277+ # Third attack
278+ cl2m = CarliniL2Method (classifier = ptc , targeted = False , max_iter = 100 , binary_search_steps = 10 ,
279+ learning_rate = 2e-2 , initial_const = 3 , decay = 1e-2 )
280+ params = {}
281+ x_test_adv = cl2m .generate (x_test , ** params )
282+ self .assertFalse ((x_test == x_test_adv ).all ())
283+ self .assertTrue ((x_test_adv <= 1.0001 ).all ())
284+ self .assertTrue ((x_test_adv >= - 0.0001 ).all ())
285+ y_pred = np .argmax (ptc .predict (x_test ), axis = 1 )
286+ y_pred_adv = np .argmax (ptc .predict (x_test_adv ), axis = 1 )
287+ self .assertTrue ((y_pred != y_pred_adv ).any ())
288+
148289
149290if __name__ == '__main__' :
150291 unittest .main ()
0 commit comments