-
Notifications
You must be signed in to change notification settings - Fork 10
/
utils.py
193 lines (164 loc) · 7.62 KB
/
utils.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
import numpy as np
import keras
import random, math
import unittest
class GeneralUtils():
def __init__(self):
pass
'''
Return True with prob
Input: probability within [0, 1]
Ouput: True or False
'''
def decision(self, prob):
assert prob >= 0, 'Probability should in the range of [0, 1]'
assert prob <= 1, 'Probability should in the range of [0, 1]'
return random.random() < prob
def generate_permutation(self, size_of_permutation, extract_portion):
assert extract_portion <= 1
num_of_extraction = math.floor(size_of_permutation * extract_portion)
permutation = np.random.permutation(size_of_permutation)
permutation = permutation[:num_of_extraction]
return permutation
def shuffle(self, a):
shuffled_a = np.empty(a.shape, dtype=a.dtype)
length = len(a)
permutation = np.random.permutation(length)
index_permutation = np.arange(length)
shuffled_a[permutation] = a[index_permutation]
return shuffled_a
def shuffle_in_uni(self, a, b):
assert len(a) == len(b)
shuffled_a = np.empty(a.shape, dtype=a.dtype)
shuffled_b = np.empty(b.shape, dtype=b.dtype)
length = len(a)
permutation = np.random.permutation(length)
index_permutation = np.arange(length)
shuffled_a[permutation] = a[index_permutation]
shuffled_b[permutation] = b[index_permutation]
return shuffled_a, shuffled_b
def shuffle_in_uni_with_permutation(self, a, b, permutation):
assert len(a) == len(b)
shuffled_a, shuffled_b = a.copy(), b.copy()
shuffled_permutation = self.shuffle(permutation)
shuffled_a[shuffled_permutation] = a[permutation]
shuffled_b[shuffled_permutation] = b[permutation]
return shuffled_a, shuffled_b
'''
SMM stands for source-level mutated model
This function looks quite terrible and messy, should be simplified
'''
def print_messages_SMO(self, mode, train_datas=None, train_labels=None, mutated_datas=None, mutated_labels=None, model=None, mutated_model=None, mutation_ratio=0):
if mode in ['DR', 'DM']:
print('Before ' + mode)
print('Train data shape:', train_datas.shape)
print('Train labels shape:', train_labels.shape)
print('')
print('After ' + mode + ', where the mutation ratio is', mutation_ratio)
print('Train data shape:', mutated_datas.shape)
print('Train labels shape:', mutated_labels.shape)
print('')
elif mode in ['LE', 'DF', 'NP']:
pass
elif mode in ['LR', 'LAs', 'AFRs']:
print('Original untrained model architecture:')
model.summary()
print('')
print('Mutated untrained model architecture:')
mutated_model.summary()
print('')
else:
pass
'''
MMM stands for model-level mutated model
'''
def print_messages_MMM_generators(self, mode, network=None, test_datas=None, test_labels=None, model=None, mutated_model=None, STD=0.1, mutation_ratio=0):
if mode in ['GF', 'WS', 'NEB', 'NAI', 'NS']:
print('Before ' + mode)
network.evaluate_model(model, test_datas, test_labels)
print('After ' + mode + ', where the mutation ratio is', mutation_ratio)
network.evaluate_model(mutated_model, test_datas, test_labels, mode)
elif mode in ['LD', 'LAm', 'AFRm']:
print('Before ' + mode)
model.summary()
network.evaluate_model(model, test_datas, test_labels)
print('After ' + mode)
mutated_model.summary()
network.evaluate_model(mutated_model, test_datas, test_labels, mode)
else:
pass
class ModelUtils():
def __init__(self):
pass
def print_layer_info(self, layer):
layer_config = layer.get_config()
print('Print layer configuration information:')
for key, value in layer_config.items():
print(key, value)
def model_copy(self, model, mode=''):
original_layers = [l for l in model.layers]
suffix = '_copy_' + mode
new_model = keras.models.clone_model(model)
for index, layer in enumerate(new_model.layers):
original_layer = original_layers[index]
original_weights = original_layer.get_weights()
layer.name = layer.name + suffix
layer.set_weights(original_weights)
new_model.name = new_model.name + suffix
return new_model
def get_booleans_of_layers_should_be_mutated(self, num_of_layers, indices):
if indices == None:
booleans_for_layers = np.full(num_of_layers, True)
else:
booleans_for_layers = np.full(num_of_layers, False)
for index in indices:
booleans_for_layers[index] = True
return booleans_for_layers
def print_comparision_of_layer_weights(self, old_model, new_model):
old_layers = [l for l in old_model.layers]
new_layers = [l for l in new_model.layers]
assert len(old_layers) == len(new_layers)
num_of_layers = len(old_layers)
booleans_for_layers = np.full(num_of_layers, True)
names_for_layers = []
for index in range(num_of_layers):
old_layer, new_layer = old_layers[index], new_layers[index]
names_for_layers.append(type(old_layer).__name__)
old_layer_weights, new_layer_weights = old_layer.get_weights(), new_layer.get_weights()
if len(old_layer_weights) == 0:
continue
is_equal_connections = np.array_equal(old_layer_weights[0], new_layer_weights[0])
is_equal_biases = np.array_equal(old_layer_weights[1], new_layer_weights[1])
is_equal = is_equal_connections and is_equal_biases
if not is_equal:
booleans_for_layers[index] = False
print('Comparision of weights between original model and mutated model,')
print('If the weights of specific layer is modified, return True. Otherwise, return False')
print('')
print(' Layer index | Layer name | Is mutated ?')
print(' -------------------------------------------')
for index, result in enumerate(booleans_for_layers):
name = names_for_layers[index]
print(' {index} | {name} | {result}'.format(index=str(index).rjust(11), name=name.rjust(14), result=(not result)))
print('')
class ExaminationalUtils():
def __init__(self):
pass
def mutation_ratio_range_check(self, mutation_ratio):
assert mutation_ratio >= 0, 'Mutation ratio attribute should in the range [0, 1]'
assert mutation_ratio <= 1, 'Mutation ratio attribute should in the range [0, 1]'
pass
def training_dataset_consistent_length_check(self, lst_a, lst_b):
assert len(lst_a) == len(lst_b), 'Training datas and labels should have the same length'
pass
def valid_indices_of_mutated_layers_check(self, num_of_layers, indices):
if indices is not None:
for index in indices:
assert index >= 0, 'Index should be positive'
assert index < num_of_layers, 'Index should not be out of range, where index should be smaller than ' + str(num_of_layers)
pass
def in_suitable_indices_check(self, suitable_indices, indices):
if indices is not None:
for index in indices:
assert index in suitable_indices, 'Index ' + str(index) + ' is an invalid index for this mutation'
pass