model_mutation_operators.py 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740
  1. import sys
  2. sys.path.append("../")
  3. from scripts.tools import utils
  4. import math
  5. from typing import *
  6. from scripts.mutation.mutation_utils import *
  7. from scripts.mutation.layer_matching import LayerMatching
  8. import random
  9. import os
  10. import warnings
  11. from scripts.logger.lemon_logger import Logger
  12. import datetime
  13. warnings.filterwarnings("ignore")
  14. os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2' # 只显示 warning 和 Error
  15. os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
  16. os.environ["CUDA_VISIBLE_DEVICES"] = ""
  17. mylogger = Logger()
  18. def _assert_indices(mutated_layer_indices: List[int] , depth_layer: int):
  19. assert max(mutated_layer_indices) < depth_layer,"Max index should be less than layer depth"
  20. assert min(mutated_layer_indices) >= 0,"Min index should be greater than or equal to zero"
  21. def _shuffle_conv2d(weights, mutate_ratio):
  22. new_weights = []
  23. for val in weights:
  24. # val is bias if len(val.shape) == 1
  25. if len(val.shape) > 1:
  26. val_shape = val.shape
  27. filter_width, filter_height, num_of_input_channels, num_of_output_channels = val_shape
  28. mutate_output_channels = utils.ModelUtils.generate_permutation(num_of_output_channels, mutate_ratio)
  29. for output_channel in mutate_output_channels:
  30. copy_list = val.copy()
  31. copy_list = np.reshape(copy_list,(filter_width * filter_height * num_of_input_channels, num_of_output_channels))
  32. selected_list = copy_list[:,output_channel]
  33. shuffle_selected_list = utils.ModelUtils.shuffle(selected_list)
  34. copy_list[:, output_channel] = shuffle_selected_list
  35. val = np.reshape(copy_list,(filter_width, filter_height, num_of_input_channels, num_of_output_channels))
  36. new_weights.append(val)
  37. return new_weights
  38. def _shuffle_dense(weights,mutate_ratio):
  39. new_weights = []
  40. for val in weights:
  41. # val is bias if len(val.shape) == 1
  42. if len(val.shape) > 1:
  43. val_shape = val.shape
  44. input_dim,output_dim = val_shape
  45. mutate_output_dims = utils.ModelUtils.generate_permutation(output_dim, mutate_ratio)
  46. copy_list = val.copy()
  47. for output_dim in mutate_output_dims:
  48. selected_list = copy_list[:, output_dim]
  49. shuffle_selected_list = utils.ModelUtils.shuffle(selected_list)
  50. copy_list[:, output_dim] = shuffle_selected_list
  51. val = copy_list
  52. new_weights .append(val)
  53. return new_weights
  54. def _LA_model_scan(model, new_layers, mutated_layer_indices=None):
  55. layer_utils = LayerUtils()
  56. layers = model.layers
  57. # new layers can never be added after the last layer
  58. positions_to_add = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  59. _assert_indices(positions_to_add, len(layers))
  60. insertion_points = {}
  61. available_new_layers = [layer for layer in
  62. layer_utils.available_model_level_layers.keys()] if new_layers is None else new_layers
  63. for i, layer in enumerate(layers):
  64. if hasattr(layer, 'activation') and 'softmax' in layer.activation.__name__.lower():
  65. break
  66. if i in positions_to_add:
  67. for available_new_layer in available_new_layers:
  68. if layer_utils.is_input_legal[available_new_layer](layer.output.shape):
  69. if i not in insertion_points.keys():
  70. insertion_points[i] = [available_new_layer]
  71. else:
  72. insertion_points[i].append(available_new_layer)
  73. return insertion_points
  74. def _MLA_model_scan(model, new_layers, mutated_layer_indices=None):
  75. layer_matching = LayerMatching()
  76. layers = model.layers
  77. # new layers can never be added after the last layer
  78. positions_to_add = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  79. _assert_indices(positions_to_add, len(layers))
  80. insertion_points = {}
  81. available_new_layers = [layer for layer in layer_matching.layer_concats.keys()] if new_layers is None else new_layers
  82. for i, layer in enumerate(layers):
  83. if hasattr(layer, 'activation') and 'softmax' in layer.activation.__name__.lower():
  84. break
  85. if i in positions_to_add:
  86. for available_new_layer in available_new_layers:
  87. # print('{} test shape: {} as list: {}'.format(available_new_layer, layer.output.shape,
  88. # layer.output.shape.as_list()))
  89. if layer_matching.input_legal[available_new_layer](layer.output.shape):
  90. # print('shape {} can be inserted'. format(layer.output.shape))
  91. if i not in insertion_points.keys():
  92. insertion_points[i] = [available_new_layer]
  93. else:
  94. insertion_points[i].append(available_new_layer)
  95. return insertion_points
  96. def _LC_and_LR_scan(model, mutated_layer_indices):
  97. layers = model.layers
  98. # the last layer should not be copied or removed
  99. mutated_layer_indices = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  100. _assert_indices(mutated_layer_indices, len(layers))
  101. available_layer_indices = []
  102. for i, layer in enumerate(layers):
  103. if hasattr(layer, 'activation') and 'softmax' in layer.activation.__name__.lower():
  104. break
  105. if i in mutated_layer_indices:
  106. # InputLayer should not be copied or removed
  107. from keras.engine.input_layer import InputLayer
  108. if isinstance(layer, InputLayer):
  109. continue
  110. # layers with multiple input tensors can't be copied or removed
  111. if isinstance(layer.input, list) and len(layer.input) > 1:
  112. continue
  113. layer_input_shape = layer.input.shape.as_list()
  114. layer_output_shape = layer.output.shape.as_list()
  115. if layer_input_shape == layer_output_shape:
  116. available_layer_indices.append(i)
  117. np.random.shuffle(available_layer_indices)
  118. return available_layer_indices
  119. def _LS_scan(model):
  120. layers = model.layers
  121. shape_dict = {}
  122. for i,layer in enumerate(layers):
  123. if hasattr(layer, 'activation') and 'softmax' in layer.activation.__name__.lower():
  124. break
  125. if isinstance(layer.input, list) and len(layer.input) > 1:
  126. continue
  127. layer_input_shape = [str(i) for i in layer.input.shape.as_list()[1:]]
  128. layer_output_shape = [str(i) for i in layer.output.shape.as_list()[1:]]
  129. input_shape = "-".join(layer_input_shape)
  130. output_shape = "-".join(layer_output_shape)
  131. k = "+".join([input_shape,output_shape])
  132. if k not in shape_dict.keys():
  133. shape_dict[k] = [i]
  134. else:
  135. shape_dict[k].append(i)
  136. return shape_dict
  137. def GF_mut(model, mutation_ratio, distribution='normal', STD=0.1, lower_bound=None, upper_bound=None):
  138. valid_distributions = ['normal', 'uniform']
  139. assert distribution in valid_distributions, 'Distribution %s is not support.' % distribution
  140. if distribution == 'uniform' and (lower_bound is None or upper_bound is None):
  141. mylogger.error('Lower bound and Upper bound is required for uniform distribution.')
  142. raise ValueError('Lower bound and Upper bound is required for uniform distribution.')
  143. mylogger.info('copying model...')
  144. GF_model = utils.ModelUtils.model_copy(model, 'GF')
  145. mylogger.info('model copied')
  146. chosed_index = np.random.randint(0, len(GF_model.layers))
  147. layer = GF_model.layers[chosed_index]
  148. mylogger.info('executing mutation of {}'.format(layer.name))
  149. weights = layer.get_weights()
  150. new_weights = []
  151. for weight in weights:
  152. weight_shape = weight.shape
  153. weight_flat = weight.flatten()
  154. permu_num = math.floor(len(weight_flat) * mutation_ratio)
  155. permutation = np.random.permutation(len(weight_flat))[:permu_num]
  156. STD = math.sqrt(weight_flat.var()) * STD
  157. weight_flat[permutation] += np.random.normal(scale=STD, size=len(permutation))
  158. weight = weight_flat.reshape(weight_shape)
  159. new_weights.append(weight)
  160. layer.set_weights(new_weights)
  161. return GF_model
  162. def WS_mut(model, mutation_ratio, mutated_layer_indices=None):
  163. WS_model = utils.ModelUtils.model_copy(model, 'WS')
  164. layers = WS_model.layers
  165. depth_layer = len(layers)
  166. mutated_layer_indices = np.arange(depth_layer) if mutated_layer_indices is None else mutated_layer_indices
  167. if 0 < mutation_ratio <= 1.0:
  168. _assert_indices(mutated_layer_indices, depth_layer)
  169. np.random.shuffle(mutated_layer_indices)
  170. i = mutated_layer_indices[0]
  171. layer = layers[i]
  172. weights = layer.get_weights()
  173. layer_name = type(layer).__name__
  174. if layer_name == "Conv2D" and len(weights) != 0:
  175. layer.set_weights(_shuffle_conv2d(weights, mutation_ratio))
  176. elif layer_name == "Dense" and len(weights) != 0:
  177. layer.set_weights(_shuffle_dense(weights, mutation_ratio))
  178. else:
  179. pass
  180. else:
  181. mylogger.error("mutation_ratio or index are wrong")
  182. raise Exception("mutation_ratio or index are wrong")
  183. return WS_model
  184. def NEB_mut(model, mutation_ratio, mutated_layer_indices=None):
  185. NEB_model = utils.ModelUtils.model_copy(model, 'NEB')
  186. layers = NEB_model.layers
  187. mutated_layer_indices = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  188. if 0 < mutation_ratio <= 1.0:
  189. _assert_indices(mutated_layer_indices, len(layers))
  190. layer_utils = LayerUtils()
  191. np.random.shuffle(mutated_layer_indices)
  192. for i in mutated_layer_indices:
  193. layer = layers[i]
  194. # skip if layer is not in white list
  195. if not layer_utils.is_layer_in_weight_change_white_list(layer):
  196. continue
  197. weights = layer.get_weights()
  198. if len(weights) > 0:
  199. if isinstance(weights, list):
  200. # assert len(weights) == 2
  201. if len(weights) != 2:
  202. continue
  203. else:
  204. weights_w, weights_b = weights
  205. weights_w = weights_w.transpose()
  206. permutation = utils.ModelUtils.generate_permutation(weights_w.shape[0], mutation_ratio)
  207. weights_w[permutation] = np.zeros(weights_w[0].shape)
  208. weights_w = weights_w.transpose()
  209. weights_b[permutation] = 0
  210. weights = weights_w, weights_b
  211. layer.set_weights(weights)
  212. else:
  213. assert isinstance(weights, np.ndarray)
  214. weights_w = weights
  215. weights_w = weights_w.transpose()
  216. permutation = utils.ModelUtils.generate_permutation(weights_w.shape[0], mutation_ratio)
  217. weights_w[permutation] = np.zeros(weights_w[0].shape)
  218. weights_w = weights_w.transpose()
  219. weights = [weights_w]
  220. layer.set_weights(weights)
  221. break
  222. return NEB_model
  223. else:
  224. mylogger.error("mutation_ratio or index are wrong")
  225. raise Exception("mutation_ratio or index are wrong")
  226. def NAI_mut(model, mutation_ratio, mutated_layer_indices=None):
  227. NAI_model = utils.ModelUtils.model_copy(model, 'NAI')
  228. layers = NAI_model.layers
  229. mutated_layer_indices = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  230. if 0 < mutation_ratio <= 1.0:
  231. _assert_indices(mutated_layer_indices, len(layers))
  232. np.random.shuffle(mutated_layer_indices)
  233. layer_utils = LayerUtils()
  234. for i in mutated_layer_indices:
  235. layer = layers[i]
  236. if not layer_utils.is_layer_in_weight_change_white_list(layer):
  237. continue
  238. weights = layer.get_weights()
  239. if len(weights) > 0:
  240. if isinstance(weights, list):
  241. if len(weights) != 2:
  242. continue
  243. else:
  244. weights_w, weights_b = weights
  245. weights_w = weights_w.transpose()
  246. permutation = utils.ModelUtils.generate_permutation(weights_w.shape[0], mutation_ratio)
  247. # print(permutation)
  248. weights_w[permutation] *= -1
  249. weights_w = weights_w.transpose()
  250. weights_b[permutation] *= -1
  251. weights = weights_w, weights_b
  252. layer.set_weights(weights)
  253. else:
  254. weights_w = weights[0]
  255. weights_w = weights_w.transpose()
  256. permutation = utils.ModelUtils.generate_permutation(weights_w.shape[0], mutation_ratio)
  257. # print(permutation)
  258. weights_w[permutation] *= -1
  259. weights_w = weights_w.transpose()
  260. weights = [weights_w]
  261. layer.set_weights(weights)
  262. break
  263. else:
  264. mylogger.error("mutation_ratio or index are wrong")
  265. raise Exception("mutation_ratio or index are wrong")
  266. return NAI_model
  267. def NS_mut(model, mutated_layer_indices=None):
  268. NS_model = utils.ModelUtils.model_copy(model, 'NS')
  269. layers = NS_model.layers
  270. mutated_layer_indices = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  271. _assert_indices(mutated_layer_indices, len(layers))
  272. layer_utils = LayerUtils()
  273. for i in mutated_layer_indices:
  274. layer = layers[i]
  275. if not layer_utils.is_layer_in_weight_change_white_list(layer):
  276. continue
  277. weights = layer.get_weights()
  278. if len(weights) > 0:
  279. if isinstance(weights, list):
  280. if len(weights) != 2:
  281. continue
  282. weights_w, weights_b = weights
  283. weights_w = weights_w.transpose()
  284. if weights_w.shape[0] >= 2:
  285. permutation = np.random.permutation(weights_w.shape[0])[:2]
  286. weights_w[permutation[0]], weights_w[permutation[1]] = \
  287. weights_w[permutation[1]].copy(), weights_w[permutation[0]].copy()
  288. weights_w = weights_w.transpose()
  289. weights_b[permutation[0]], weights_b[permutation[1]] = \
  290. weights_b[permutation[1]].copy(), weights_b[permutation[0]].copy()
  291. weights = weights_w, weights_b
  292. layer.set_weights(weights)
  293. else:
  294. mylogger.warning("NS not used! One neuron can't be shuffle!")
  295. else:
  296. assert isinstance(weights, np.ndarray)
  297. weights_w = weights
  298. weights_w = weights_w.transpose()
  299. if weights_w.shape[0] >= 2:
  300. permutation = np.random.permutation(weights_w.shape[0])[:2]
  301. weights_w[permutation[0]], weights_w[permutation[1]] = \
  302. weights_w[permutation[1]].copy(), weights_w[permutation[0]].copy()
  303. weights_w = weights_w.transpose()
  304. weights = [weights_w]
  305. layer.set_weights(weights)
  306. else:
  307. mylogger.warning("NS not used! One neuron can't be shuffle!")
  308. break
  309. return NS_model
  310. def ARem_mut(model, mutated_layer_indices=None):
  311. ARem_model = utils.ModelUtils.model_copy(model, 'ARem')
  312. layers = ARem_model.layers
  313. # the activation of last layer should not be removed
  314. mutated_layer_indices = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  315. np.random.shuffle(mutated_layer_indices)
  316. _assert_indices(mutated_layer_indices, len(layers))
  317. for i in mutated_layer_indices:
  318. layer = layers[i]
  319. if hasattr(layer, 'activation') and 'softmax' not in layer.activation.__name__.lower():
  320. layer.activation = ActivationUtils.no_activation
  321. break
  322. return ARem_model
  323. def ARep_mut(model, new_activations=None, mutated_layer_indices=None):
  324. activation_utils = ActivationUtils()
  325. ARep_model = utils.ModelUtils.model_copy(model, 'ARep')
  326. layers = ARep_model.layers
  327. # the activation of last layer should not be replaced
  328. mutated_layer_indices = np.arange(len(layers) - 1) if mutated_layer_indices is None else mutated_layer_indices
  329. np.random.shuffle(mutated_layer_indices)
  330. _assert_indices(mutated_layer_indices, len(layers))
  331. for i in mutated_layer_indices:
  332. layer = layers[i]
  333. if hasattr(layer, 'activation') and 'softmax' not in layer.activation.__name__.lower():
  334. layer.activation = activation_utils.pick_activation_randomly(new_activations)
  335. break
  336. return ARep_model
  337. def LA_mut(model, new_layers=None, mutated_layer_indices=None):
  338. layer_utils = LayerUtils()
  339. if new_layers is not None:
  340. for layer in new_layers:
  341. if layer not in layer_utils.available_model_level_layers.keys():
  342. mylogger.error('Layer {} is not supported.'.format(layer))
  343. raise Exception('Layer {} is not supported.'.format(layer))
  344. LA_model = utils.ModelUtils.model_copy(model, 'LA')
  345. insertion_points = _LA_model_scan(LA_model, new_layers, mutated_layer_indices)
  346. if len(insertion_points.keys()) == 0:
  347. mylogger.warning('no appropriate layer to insert')
  348. return None
  349. for key in insertion_points.keys():
  350. mylogger.info('{} can be added after layer {} ({})'
  351. .format(insertion_points[key], key, type(model.layers[key])))
  352. layers_index_avaliable = list(insertion_points.keys())
  353. layer_index_to_insert = layers_index_avaliable[np.random.randint(0, len(layers_index_avaliable))]
  354. available_new_layers = insertion_points[layer_index_to_insert]
  355. layer_name_to_insert = available_new_layers[np.random.randint(0, len(available_new_layers))]
  356. mylogger.info('insert {} after {}'.format(layer_name_to_insert, LA_model.layers[layer_index_to_insert].name))
  357. # insert new layer
  358. if model.__class__.__name__ == 'Sequential':
  359. import keras
  360. new_model = keras.models.Sequential()
  361. for i, layer in enumerate(LA_model.layers):
  362. new_layer = LayerUtils.clone(layer)
  363. new_model.add(new_layer)
  364. if i == layer_index_to_insert:
  365. output_shape = layer.output_shape
  366. new_model.add(layer_utils.available_model_level_layers[layer_name_to_insert](output_shape))
  367. else:
  368. def layer_addition(x, layer):
  369. x = layer(x)
  370. output_shape = layer.output_shape
  371. new_layer = layer_utils.available_model_level_layers[layer_name_to_insert](output_shape)
  372. x = new_layer(x)
  373. return x
  374. new_model = utils.ModelUtils.functional_model_operation(LA_model, operation={LA_model.layers[layer_index_to_insert].name: layer_addition})
  375. assert len(new_model.layers) == len(model.layers) + 1
  376. tuples = []
  377. import time
  378. old_model_layers = {}
  379. for layer in model.layers:
  380. old_model_layers[layer.name] = layer
  381. new_model_layers = {}
  382. for layer in new_model.layers:
  383. layer_name = layer.name
  384. if layer_name.endswith('_copy_LA'):
  385. key = layer_name[:-8]
  386. else:
  387. key = layer_name
  388. new_model_layers[key] = layer
  389. for layer_name in old_model_layers.keys():
  390. layer_weights = old_model_layers[layer_name].get_weights()
  391. for sw, w in zip(new_model_layers[layer_name].weights, layer_weights):
  392. shape_sw = np.shape(sw)
  393. shape_w = np.shape(w)
  394. assert len(shape_sw) == len(shape_w)
  395. for i in range(len(shape_sw)):
  396. assert shape_sw[i] == shape_w[i], '{}'.format(layer_name)
  397. tuples.append((sw, w))
  398. import keras.backend as K
  399. K.batch_set_value(tuples)
  400. return new_model
  401. def MLA_mut(model, new_layers = None, mutated_layer_indices=None):
  402. # mutiple layers addition
  403. layer_matching = LayerMatching()
  404. if new_layers is not None:
  405. for layer in new_layers:
  406. if layer not in layer_matching.layer_concats.keys():
  407. raise Exception('Layer {} is not supported.'.format(layer))
  408. MLA_model = utils.ModelUtils.model_copy(model, 'MLA')
  409. insertion_points = _MLA_model_scan(model, new_layers, mutated_layer_indices)
  410. mylogger.info(insertion_points)
  411. if len(insertion_points.keys()) == 0:
  412. mylogger.warning('no appropriate layer to insert')
  413. return None
  414. for key in insertion_points.keys():
  415. mylogger.info('{} can be added after layer {} ({})'
  416. .format(insertion_points[key], key, type(model.layers[key])))
  417. # use logic: randomly select a new layer available to insert into the layer which can be inserted
  418. layers_index_avaliable = list(insertion_points.keys())
  419. # layer_index_to_insert = np.max([i for i in insertion_points.keys()])
  420. layer_index_to_insert = layers_index_avaliable[np.random.randint(0, len(layers_index_avaliable))]
  421. available_new_layers = insertion_points[layer_index_to_insert]
  422. layer_name_to_insert = available_new_layers[np.random.randint(0, len(available_new_layers))]
  423. mylogger.info('choose to insert {} after {}'.format(layer_name_to_insert, MLA_model.layers[layer_index_to_insert].name))
  424. # insert new layers
  425. if model.__class__.__name__ == 'Sequential':
  426. import keras
  427. new_model = keras.models.Sequential()
  428. for i, layer in enumerate(MLA_model.layers):
  429. new_layer = LayerUtils.clone(layer)
  430. # new_layer.name += "_copy"
  431. new_model.add(new_layer)
  432. if i == layer_index_to_insert:
  433. output_shape = layer.output.shape.as_list()
  434. layers_to_insert = layer_matching.layer_concats[layer_name_to_insert](output_shape)
  435. for layer_to_insert in layers_to_insert:
  436. layer_to_insert.name += "_insert"
  437. mylogger.info(layer_to_insert)
  438. new_model.add(layer_to_insert)
  439. new_model.build(MLA_model.input_shape)
  440. else:
  441. def layer_addition(x, layer):
  442. x = layer(x)
  443. output_shape = layer.output.shape.as_list()
  444. new_layers = layer_matching.layer_concats[layer_name_to_insert](output_shape)
  445. for l in new_layers:
  446. l.name += "_insert"
  447. mylogger.info('insert layer {}'.format(str(l)))
  448. x = l(x)
  449. return x
  450. new_model = utils.ModelUtils.functional_model_operation(MLA_model, operation={MLA_model.layers[layer_index_to_insert].name: layer_addition})
  451. tuples = []
  452. import time
  453. start_time = time.time()
  454. old_model_layers = {}
  455. for layer in model.layers:
  456. old_model_layers[layer.name] = layer
  457. new_model_layers = {}
  458. for layer in new_model.layers:
  459. layer_name = layer.name
  460. if layer_name.endswith('_copy_MLA'):
  461. key = layer_name[:-9]
  462. else:
  463. key = layer_name
  464. new_model_layers[key] = layer
  465. for layer_name in old_model_layers.keys():
  466. layer_weights = old_model_layers[layer_name].get_weights()
  467. for sw, w in zip(new_model_layers[layer_name].weights, layer_weights):
  468. shape_sw = np.shape(sw)
  469. shape_w = np.shape(w)
  470. assert len(shape_sw) == len(shape_w)
  471. assert shape_sw[0] == shape_w[0]
  472. tuples.append((sw, w))
  473. import keras.backend as K
  474. K.batch_set_value(tuples)
  475. end_time = time.time()
  476. print('set weight cost {}'.format(end_time - start_time))
  477. return new_model
  478. def LC_mut(model, mutated_layer_indices=None):
  479. LC_model = utils.ModelUtils.model_copy(model, 'LC')
  480. available_layer_indices = _LC_and_LR_scan(LC_model, mutated_layer_indices)
  481. if len(available_layer_indices) == 0:
  482. mylogger.warning('no appropriate layer to copy (input and output shape should be same)')
  483. return None
  484. # use logic: copy the last available layer
  485. copy_layer_index = available_layer_indices[-1]
  486. copy_layer_name = LC_model.layers[copy_layer_index].name + '_repeat'
  487. mylogger.info('choose to copy layer {}'.format(LC_model.layers[copy_layer_index].name))
  488. if model.__class__.__name__ == 'Sequential':
  489. import keras
  490. new_model = keras.models.Sequential()
  491. for i, layer in enumerate(LC_model.layers):
  492. new_model.add(LayerUtils.clone(layer))
  493. if i == copy_layer_index:
  494. copy_layer = LayerUtils.clone(layer)
  495. copy_layer.name += '_repeat'
  496. new_model.add(copy_layer)
  497. else:
  498. def layer_repeat(x, layer):
  499. x = layer(x)
  500. copy_layer = LayerUtils.clone(layer)
  501. copy_layer.name += '_repeat'
  502. x = copy_layer(x)
  503. return x
  504. new_model = utils.ModelUtils.functional_model_operation(LC_model, operation={LC_model.layers[copy_layer_index].name: layer_repeat})
  505. # update weights
  506. assert len(new_model.layers) == len(model.layers) + 1
  507. tuples = []
  508. old_model_layers = {}
  509. for layer in model.layers:
  510. old_model_layers[layer.name] = layer
  511. new_model_layers = {}
  512. for layer in new_model.layers:
  513. layer_name = layer.name
  514. if layer_name.endswith('_copy_LC'):
  515. key = layer_name[:-8]
  516. else:
  517. key = layer_name
  518. new_model_layers[key] = layer
  519. for layer_name in old_model_layers.keys():
  520. layer_weights = old_model_layers[layer_name].get_weights()
  521. if layer_name + '_copy_LC_repeat' == copy_layer_name:
  522. for sw, w in zip(new_model_layers[copy_layer_name].weights, layer_weights):
  523. shape_sw = np.shape(sw)
  524. shape_w = np.shape(w)
  525. assert len(shape_sw) == len(shape_w)
  526. assert shape_sw[0] == shape_w[0]
  527. tuples.append((sw, w))
  528. for sw, w in zip(new_model_layers[layer_name].weights, layer_weights):
  529. shape_sw = np.shape(sw)
  530. shape_w = np.shape(w)
  531. assert len(shape_sw) == len(shape_w)
  532. assert shape_sw[0] == shape_w[0]
  533. tuples.append((sw, w))
  534. import keras.backend as K
  535. K.batch_set_value(tuples)
  536. return new_model
  537. def LR_mut(model, mutated_layer_indices=None):
  538. LR_model = utils.ModelUtils.model_copy(model, 'LR')
  539. available_layer_indices = _LC_and_LR_scan(LR_model, mutated_layer_indices)
  540. if len(available_layer_indices) == 0:
  541. mylogger.warning('no appropriate layer to remove (input and output shape should be same)')
  542. return None
  543. # use logic: remove the last available layer
  544. remove_layer_index = available_layer_indices[-1]
  545. mylogger.info('choose to remove layer {}'.format(LR_model.layers[remove_layer_index].name))
  546. if model.__class__.__name__ == 'Sequential':
  547. import keras
  548. new_model = keras.models.Sequential()
  549. for i, layer in enumerate(LR_model.layers):
  550. if i != remove_layer_index:
  551. new_layer = LayerUtils.clone(layer)
  552. # new_layer.name += '_copy'
  553. new_model.add(new_layer)
  554. else:
  555. new_model = utils.ModelUtils.functional_model_operation(LR_model, operation={LR_model.layers[remove_layer_index].name: lambda x, layer: x})
  556. # update weights
  557. assert len(new_model.layers) == len(model.layers) - 1
  558. tuples = []
  559. old_model_layers = {}
  560. for layer in model.layers:
  561. old_model_layers[layer.name] = layer
  562. new_model_layers = {}
  563. for layer in new_model.layers:
  564. layer_name = layer.name
  565. if layer_name.endswith('_copy_LR'):
  566. key = layer_name[:-8]
  567. else:
  568. key = layer_name
  569. new_model_layers[key] = layer
  570. for layer_name in new_model_layers.keys():
  571. layer_weights = old_model_layers[layer_name].get_weights()
  572. for sw, w in zip(new_model_layers[layer_name].weights, layer_weights):
  573. shape_sw = np.shape(sw)
  574. shape_w = np.shape(w)
  575. assert len(shape_sw) == len(shape_w)
  576. assert shape_sw[0] == shape_w[0]
  577. tuples.append((sw, w))
  578. import keras.backend as K
  579. K.batch_set_value(tuples)
  580. return new_model
  581. def LS_mut(model):
  582. LS_model = utils.ModelUtils.model_copy(model,"LS")
  583. shape_dict = _LS_scan(LS_model)
  584. layers = LS_model.layers
  585. swap_list = []
  586. for v in shape_dict.values():
  587. if len(v) > 1:
  588. swap_list.append(v)
  589. if len(swap_list) == 0:
  590. mylogger.warning("No layers to swap!")
  591. return None
  592. swap_list = swap_list[random.randint(0, len(swap_list)-1)]
  593. choose_index = random.sample(swap_list, 2)
  594. mylogger.info('choose to swap {} ({} - {}) and {} ({} - {})'.format(layers[choose_index[0]].name,
  595. layers[choose_index[0]].input.shape,
  596. layers[choose_index[0]].output.shape,
  597. layers[choose_index[1]].name,
  598. layers[choose_index[1]].input.shape,
  599. layers[choose_index[1]].output.shape))
  600. if model.__class__.__name__ == 'Sequential':
  601. import keras
  602. new_model = keras.Sequential()
  603. for i, layer in enumerate(layers):
  604. if i == choose_index[0]:
  605. new_model.add(LayerUtils.clone(layers[choose_index[1]]))
  606. elif i == choose_index[1]:
  607. new_model.add(LayerUtils.clone(layers[choose_index[0]]))
  608. else:
  609. new_model.add(LayerUtils.clone(layer))
  610. else:
  611. layer_1 = layers[choose_index[0]]
  612. layer_2 = layers[choose_index[1]]
  613. new_model = utils.ModelUtils.functional_model_operation(LS_model, {layer_1.name: lambda x, layer: LayerUtils.clone(layer_2)(x),
  614. layer_2.name: lambda x, layer: LayerUtils.clone(layer_1)(x)})
  615. # update weights
  616. assert len(new_model.layers) == len(model.layers)
  617. tuples = []
  618. old_model_layers = {}
  619. for layer in model.layers:
  620. old_model_layers[layer.name] = layer
  621. new_model_layers = {}
  622. for layer in new_model.layers:
  623. layer_name = layer.name
  624. if layer_name.endswith('_copy_LS'):
  625. key = layer_name[:-8]
  626. else:
  627. key = layer_name
  628. new_model_layers[key] = layer
  629. for layer_name in old_model_layers.keys():
  630. layer_weights = old_model_layers[layer_name].get_weights()
  631. for sw, w in zip(new_model_layers[layer_name].weights, layer_weights):
  632. shape_sw = np.shape(sw)
  633. shape_w = np.shape(w)
  634. assert len(shape_sw) == len(shape_w)
  635. assert shape_sw[0] == shape_w[0]
  636. tuples.append((sw, w))
  637. import keras.backend as K
  638. K.batch_set_value(tuples)
  639. return new_model
  640. if __name__ == '__main__':
  641. pass