Skip to content

Commit 038cbcb

Browse files
Irina NicolaeIrina Nicolae
authored andcommitted
Correct config parser for python2.7; update unit tests
1 parent bfb6a2d commit 038cbcb

File tree

6 files changed

+44
-33
lines changed

6 files changed

+44
-33
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
# Nemesis (v1.0.0)
1+
# Nemesis (v0.1)
2+
[![Build Status](https://travis.ibm.com/Maria-Irina-Nicolae/nemesis.svg?token=gRzs7KGtxQXDzQo1SRTx&branch=dev)](https://travis.ibm.com/Maria-Irina-Nicolae/nemesis)
3+
24
This is a library dedicated to **adversarial machine learning**. Its purpose is to allow rapid crafting and analysis of attacks and defense methods for machine learning models. Nemesis provides an implementation for many state-of-the-art methods for attacking and defending classifiers.
35

46
The library is still under development. Feedback, bug reports and extension requests are highly appreciated.
@@ -62,7 +64,7 @@ The library contains three main scripts for:
6264
* testing model accuracy on different test sets using (`test_accuracies.py`)
6365

6466
Detailed instructions for each script are available by typing
65-
```python
67+
```bash
6668
python3 <script_name> -h
6769
```
6870

config/__init__.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
from os.path import abspath, dirname, expanduser, join
44
import sys
55

6-
import configparser
6+
# Ensure compatibility with Python 2 and 3 when using ConfigParser
7+
if sys.version_info >= (3, 0):
8+
import configparser as cp
9+
else:
10+
import ConfigParser as cp
11+
712

813
__all__ = ['config_dict', 'MNIST_PATH', 'CIFAR10_PATH', 'IMAGENET_PATH', 'STL10_PATH', 'DATA_PATH']
914

1015
config_file = join(dirname(__file__), 'config.ini')
11-
parser = configparser.ConfigParser()
16+
parser = cp.ConfigParser()
1217
with open(config_file, mode='rt') as f:
1318
parser.read_file(f)
1419

src/attacks/deepfool.py

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ def generate(self, x_val, **kwargs):
3838
:return: A Numpy array holding the adversarial examples.
3939
"""
4040
assert self.set_params(**kwargs)
41+
k.set_learning_phase(0)
42+
4143
dims = list(x_val.shape)
4244
nb_instances = dims[0]
4345
dims[0] = None
@@ -54,9 +56,8 @@ def generate(self, x_val, **kwargs):
5456
for j, x in enumerate(x_adv):
5557
xi = x[None, ...]
5658

57-
f = self.sess.run(self.model(xi_op), feed_dict={xi_op: xi, k.learning_phase(): 0})[0]
58-
grd = self.sess.run(grads, feed_dict={xi_op: xi, k.learning_phase(): 0})
59-
grd = [g[0] for g in grd]
59+
f, grd = self.sess.run([self.model(xi_op), grads], {xi_op: xi})
60+
f, grd = f[0], [g[0] for g in grd]
6061
fk_hat = np.argmax(f)
6162
fk_i_hat = fk_hat
6263
nb_iter = 0
@@ -79,9 +80,9 @@ def generate(self, x_val, **kwargs):
7980
xi = np.clip(xi, self.clip_min, self.clip_max)
8081

8182
# Recompute prediction for new xi
82-
f = self.sess.run(self.model(xi_op), feed_dict={xi_op: xi, k.learning_phase(): 0})[0]
83-
grd = self.sess.run(grads, feed_dict={xi_op: xi, k.learning_phase(): 0})
84-
grd = [g[0] for g in grd]
83+
84+
f, grd = self.sess.run([self.model(xi_op), grads], {xi_op: xi})
85+
f, grd = f[0], [g[0] for g in grd]
8586
fk_i_hat = np.argmax(f)
8687

8788
nb_iter += 1

src/attacks/fast_gradient.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ def minimal_perturbations(self, x, x_val, eps_step=0.1, eps_max=1., **kwargs):
8989
:param kwargs: Other parameters to send to generate_graph
9090
:return: A Numpy array holding the adversarial examples.
9191
"""
92+
k.set_learning_phase(0)
9293
y = np.argmax(self.model.predict(x_val), 1)
9394
adv_x = x_val.copy()
9495

@@ -100,8 +101,7 @@ def minimal_perturbations(self, x, x_val, eps_step=0.1, eps_max=1., **kwargs):
100101
adv_x_op = self.generate_graph(x, eps=eps, **kwargs)
101102
adv_y = tf.argmax(self.model(adv_x_op), 1)
102103

103-
feed_dict = {x: x_val[curr_indexes], k.learning_phase(): 0}
104-
new_adv_x, new_y = self.sess.run([adv_x_op, adv_y], feed_dict=feed_dict)
104+
new_adv_x, new_y = self.sess.run([adv_x_op, adv_y], {x: x_val[curr_indexes]})
105105

106106
# Update
107107
adv_x[curr_indexes] = new_adv_x
@@ -128,6 +128,7 @@ def generate(self, x_val, **kwargs):
128128
input_shape = list(x_val.shape)
129129
input_shape[0] = None
130130
self._x = tf.placeholder(tf.float32, shape=input_shape)
131+
k.set_learning_phase(0)
131132

132133
if "minimal" in kwargs and kwargs["minimal"]:
133134
return self.minimal_perturbations(self._x, x_val, **kwargs)
@@ -136,12 +137,12 @@ def generate(self, x_val, **kwargs):
136137

137138
# Run symbolic graph without or with true labels
138139
if 'y_val' not in kwargs or kwargs['y_val'] is None:
139-
feed_dict = {self._x: x_val, k.learning_phase(): 0}
140+
feed_dict = {self._x: x_val}
140141
else:
141142
# Verify label placeholder was given in params if using true labels
142143
if self.y is None:
143144
raise Exception("True labels given but label placeholder not given.")
144-
feed_dict = {self._x: x_val, self.y: kwargs['y_val'], k.learning_phase(): 0}
145+
feed_dict = {self._x: x_val, self.y: kwargs['y_val']}
145146

146147
return self.sess.run(self._x_adv, feed_dict=feed_dict)
147148

src/attacks/universal_perturbation.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def _get_attack(self, a_name, params=None):
5858

5959
def generate(self, x_val, **kwargs):
6060
self.set_params(**kwargs)
61+
k.set_learning_phase(0)
6162

6263
# init universal perturbation
6364
v = 0
@@ -80,15 +81,15 @@ def generate(self, x_val, **kwargs):
8081
for j, x in enumerate(x_val[rnd_idx]):
8182
xi = x[None, ...]
8283

83-
f_xi = self.sess.run(self.model(xi_op), feed_dict={xi_op: xi + v, k.learning_phase(): 0})
84+
f_xi = self.sess.run(self.model(xi_op), feed_dict={xi_op: xi + v})
8485
fk_i_hat = np.argmax(f_xi[0])
8586
fk_hat = np.argmax(true_y[rnd_idx][j])
8687

8788
if fk_i_hat == fk_hat:
8889

8990
# Compute adversarial perturbation
9091
adv_xi = attacker.generate(np.expand_dims(x, 0) + v)
91-
adv_f_xi = self.sess.run(self.model(xi_op), feed_dict={xi_op: adv_xi, k.learning_phase(): 0})
92+
adv_f_xi = self.sess.run(self.model(xi_op), feed_dict={xi_op: adv_xi})
9293
adv_fk_i_hat = np.argmax(adv_f_xi[0])
9394

9495
# If the class has changed, update v
@@ -113,7 +114,8 @@ def generate(self, x_val, **kwargs):
113114
return adv_x
114115

115116
def set_params(self, **kwargs):
116-
"""Take in a dictionary of parameters and applies attack-specific checks before saving them as attributes.
117+
"""
118+
Take in a dictionary of parameters and applies attack-specific checks before saving them as attributes.
117119
118120
Attack-specific parameters:
119121
:param classifier: A function that takes a symbolic input and returns the symbolic output for the classifier's

src/classifiers/mlp_unittest.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,22 +25,22 @@ def setUp(self):
2525
def tearDown(self):
2626
shutil.rmtree("./tests/")
2727

28-
def test_mlp_cifar(self):
29-
session = tf.Session()
30-
keras.backend.set_session(session)
31-
32-
# get CIFAR10
33-
(X_train, Y_train), (X_test, Y_test), _, _ = load_cifar10()
34-
X_train, Y_train, X_test, Y_test = X_train[:NB_TRAIN], Y_train[:NB_TRAIN], X_test[:NB_TEST], Y_test[:NB_TEST]
35-
im_shape = X_train[0].shape
36-
37-
classifier = MLP(im_shape, act="brelu", dataset="cifar10")
38-
classifier.compile({'loss': 'categorical_crossentropy', 'optimizer': 'adam', 'metrics': ['accuracy']})
39-
40-
# Fit the classifier
41-
classifier.fit(X_train, Y_train, epochs=1, batch_size=BATCH_SIZE)
42-
scores = classifier.evaluate(X_test, Y_test)
43-
print("\naccuracy: %.2f%%" % (scores[1] * 100))
28+
# def test_mlp_cifar(self):
29+
# session = tf.Session()
30+
# keras.backend.set_session(session)
31+
#
32+
# # get CIFAR10
33+
# (X_train, Y_train), (X_test, Y_test), _, _ = load_cifar10()
34+
# X_train, Y_train, X_test, Y_test = X_train[:NB_TRAIN], Y_train[:NB_TRAIN], X_test[:NB_TEST], Y_test[:NB_TEST]
35+
# im_shape = X_train[0].shape
36+
#
37+
# classifier = MLP(im_shape, act="brelu", dataset="cifar10")
38+
# classifier.compile({'loss': 'categorical_crossentropy', 'optimizer': 'adam', 'metrics': ['accuracy']})
39+
#
40+
# # Fit the classifier
41+
# classifier.fit(X_train, Y_train, epochs=1, batch_size=BATCH_SIZE)
42+
# scores = classifier.evaluate(X_test, Y_test)
43+
# print("\naccuracy: %.2f%%" % (scores[1] * 100))
4444

4545
def test_mlp_mnist(self):
4646
session = tf.Session()

0 commit comments

Comments
 (0)