-
Notifications
You must be signed in to change notification settings - Fork 0
/
fitness.py
201 lines (151 loc) · 7 KB
/
fitness.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
from feature_squeeze import reduce_precision_np, median_filter_np
import numpy as np
from filters.filters import img_filters
from tensorflow import keras
class fitness:
def __init__(self, tf_model, filters_functions, image_portion=100):
"""
Detection rate fitness
"""
self.tf_model = tf_model
self.filters_functions = filters_functions
self.images_original = None
self._initialize_images(image_portion)
def _initialize_images(self, image_portion):
"""
initialize the images needed for the problem
"""
(x_train, _), (_, _) = keras.datasets.cifar10.load_data()
## working on portion of data because of low available resources
self.images_original = x_train[:image_portion]
self.original_images_predictions = self.tf_model.predict(self.images_original, verbose=0)
def _attack_detection(self, images, threshold=1.7547):
image_squeezed = reduce_precision_np(images, npp=5)
image_locally_smoothed = median_filter_np(images, width=4)
# prediction_image = self.tf_model.predict(images, verbose=0)
prediction_image = self.original_images_predictions
prediction1 = self.tf_model.predict(image_squeezed, verbose=0)
prediction2 = self.tf_model.predict(image_locally_smoothed, verbose=0)
distance1 = np.sum(np.abs(prediction_image - prediction1), axis=1)
distance2 = np.sum(np.abs(prediction_image - prediction2), axis=1)
## True will show that the attack was successful and False unsuccessful
return (distance1 >= threshold) | (distance2 >= threshold)
def _evaluate_dr(self, images_batch):
"""
evaluate the detection rate
Parameters:
------------
images_batch : numpy array
the dimension should be (count of images, width=32, height=32, img_channel=3)
normally the filtered image should be as input here
Returns:
---------
detection_rate : float
showing how the model could detect the adversarial attacks
"""
## if just one image was as input
if images_batch.shape[0] == 1:
images = np.expand_dims(images_batch, axis=1)
else:
images = images_batch
attacks = self._attack_detection(images)
## we can get the adversarial images using the line below
# adversarial_images = images_batch[attacks]
detection_rate = (1 / len(attacks)) * np.sum(attacks)
return detection_rate
def _evaluate_asr(self, images_original, images_filtered):
"""
evaluate the attack success rate
the bigger the value the more success the attacks are
Parameters:
------------
images_original : numpy array
the dimension should be (count of images, width=32, height=32, img_channel=3)
images_filtered : numpy array
original images that some pre-processing happened to them to attack the model
the dimension should be (count of images, width=32, height=32, img_channel=3)
Returns:
---------
detection_rate : float
showing how the model could detect the adversarial attacks
"""
## if they were just one image
## change the dimension to be compatible with model's input shape
if images_original.shape[0] == 1:
images_original_ = np.expand_dims(images_original, axis=0)
else:
images_original_ = images_original
if images_filtered.shape[0] == 1:
images_filtered_ = np.expand_dims(images_filtered, axis=0)
else:
images_filtered_ = images_filtered
# predictions_original = self.tf_model.predict(images_original_, verbose=0)
predictions_original = self.original_images_predictions
predictions_filtered = self.tf_model.predict(images_filtered_, verbose=0)
## the class with maximum probability
predictions_classes_original = np.argmax(predictions_original, axis=1)
predictions_classes_filtered = np.argmax(predictions_filtered, axis=1)
## compare the predictions
same_prediction_count = np.sum(predictions_classes_original != predictions_classes_filtered)
## attack success rate
attack_sr = (1 / len(images_original_)) * same_prediction_count
return attack_sr
def _apply_multiple_filters(self, filter_functions, images_batch):
"""
apply multiple filters on one image
filter_functions are the multiple filters function extracted from a chromosome
returns the manipulated images (filtered ones)
"""
## filtered images are saved in the array
manipulated_images_arr = []
## for images
for image in images_batch:
manipulated_image = np.copy(image)
## Apply multiple filters to the image
for filter_func in filter_functions:
manipulated_image = filter_func.apply(manipulated_image)
manipulated_images_arr.append(manipulated_image)
## convert back to numpy array
manipulated_images_arr = np.array(manipulated_images_arr)
return manipulated_images_arr
def _apply_filter(self, filter_function, images_array):
"""
apply filter for multiple images (images_array)
"""
images_filtered = []
for image in images_array:
images_filtered.append(filter_function.apply(image))
images_filtered = np.array(images_filtered)
return images_filtered
def fitness_dr(self):
"""
get the detection rate of the specified filters parameters in chromosome_filters
# Parameters:
# ------------
# chromosome_filter : array of floats
# float array with length equal to 3
Returns:
---------
detection_rate : float
showing how the model could detect the adversarial attacks
"""
images_filtered = self._apply_multiple_filters(self.filters_functions, self.images_original)
detection_rate = self._evaluate_dr(images_filtered)
return detection_rate
def fitness_asr(self):
"""
find the attack success rate of the specilized image filter on model
the bigger the value the more success the attacks are
# Parameters:
# -------------
# chromosome_filters : array of floats
# float array with length equal to 3
Returns:
---------
detection_rate : float
showing how the model could detect the adversarial attacks
"""
# images_filtered = self._apply_filter(self.images_original, filter_function)
images_filtered = self._apply_multiple_filters(self.filters_functions, self.images_original)
attack_sr = self._evaluate_asr(self.images_original, images_filtered)
return attack_sr