mutation_utils.py 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. import numpy as np
  2. import os
  3. import warnings
  4. from run.model2json import *
  5. #np.random.seed(20200501)
  6. warnings.filterwarnings("ignore")
  7. warnings.filterwarnings("ignore")
  8. os.environ["TF_CPP_MIN_LOG_LEVEL"] = '2' # 只显示 warning 和 Error
  9. os.environ["CUDA_DEVICE_ORDER"] = "PCI_BUS_ID"
  10. os.environ["CUDA_VISIBLE_DEVICES"] = ""
  11. class ActivationUtils:
  12. def __init__(self):
  13. self.available_activations = ActivationUtils.available_activations()
  14. @staticmethod
  15. def available_activations():
  16. activations = {}
  17. import keras.backend as K
  18. activations['relu'] = K.relu
  19. activations['tanh'] = K.tanh
  20. activations['sigmoid'] = K.sigmoid
  21. activations['no_activation'] = ActivationUtils.no_activation
  22. activations['leakyrelu'] = ActivationUtils.leakyrelu
  23. return activations
  24. def get_activation(self, activation):
  25. if activation not in self.available_activations.keys():
  26. raise Exception('Activation function {} is not supported. Supported functions: {}'
  27. .format(activation, [key for key in self.available_activations.keys()]))
  28. return self.available_activations[activation]
  29. def pick_activation_randomly(self, activations=None):
  30. if activations is None:
  31. availables = [item for item in self.available_activations.keys()]
  32. availables.remove('no_activation')
  33. else:
  34. availables = activations
  35. index = np.random.randint(0, len(availables))
  36. return self.available_activations[availables[index]]
  37. @staticmethod
  38. def no_activation(x):
  39. return x
  40. @staticmethod
  41. def leakyrelu(x):
  42. import keras.backend as K
  43. return K.relu(x, alpha=0.01)
  44. class LayerUtils:
  45. def __init__(self):
  46. # these layers take effect both for training and testing
  47. self.available_model_level_layers = {}
  48. # these layers only take effect for training
  49. self.available_source_level_layers = {}
  50. self.is_input_legal = {}
  51. self.available_model_level_layers['dense'] = LayerUtils.dense#keras
  52. self.is_input_legal['dense'] = LayerUtils.dense_input_legal
  53. self.available_model_level_layers['conv_1d'] = LayerUtils.conv1d
  54. self.is_input_legal['conv_1d'] = LayerUtils.conv1d_input_legal
  55. self.available_model_level_layers['conv_2d'] = LayerUtils.conv2d
  56. self.is_input_legal['conv_2d'] = LayerUtils.conv2d_input_legal
  57. self.available_model_level_layers['separable_conv_1d'] = LayerUtils.separable_conv_1d
  58. self.is_input_legal['separable_conv_1d'] = LayerUtils.separable_conv_1d_input_legal
  59. self.available_model_level_layers['separable_conv_2d'] = LayerUtils.separable_conv_2d
  60. self.is_input_legal['separable_conv_2d'] = LayerUtils.separable_conv_2d_input_legal
  61. self.available_model_level_layers['depthwise_conv_2d'] = LayerUtils.depthwise_conv_2d
  62. self.is_input_legal['depthwise_conv_2d'] = LayerUtils.depthwise_conv_2d_input_legal
  63. self.available_model_level_layers['conv_2d_transpose'] = LayerUtils.conv_2d_transpose
  64. self.is_input_legal['conv_2d_transpose'] = LayerUtils.conv_2d_transpose_input_legal
  65. self.available_model_level_layers['conv_3d'] = LayerUtils.conv_3d
  66. self.is_input_legal['conv_3d'] = LayerUtils.conv_3d_input_legal
  67. self.available_model_level_layers['conv_3d_transpose'] = LayerUtils.conv_3d_transpose
  68. self.is_input_legal['conv_3d_transpose'] = LayerUtils.conv_3d_transpose_input_legal
  69. self.available_model_level_layers['max_pooling_1d'] = LayerUtils.max_pooling_1d
  70. self.is_input_legal['max_pooling_1d'] = LayerUtils.max_pooling_1d_input_legal
  71. self.available_model_level_layers['max_pooling_2d'] = LayerUtils.max_pooling_2d
  72. self.is_input_legal['max_pooling_2d'] = LayerUtils.max_pooling_2d_input_legal
  73. self.available_model_level_layers['max_pooling_3d'] = LayerUtils.max_pooling_3d
  74. self.is_input_legal['max_pooling_3d'] = LayerUtils.max_pooling_3d_input_legal
  75. self.available_model_level_layers['average_pooling_1d'] = LayerUtils.average_pooling_1d
  76. self.is_input_legal['average_pooling_1d'] = LayerUtils.average_pooling_1d_input_legal
  77. self.available_model_level_layers['average_pooling_2d'] = LayerUtils.average_pooling_2d
  78. self.is_input_legal['average_pooling_2d'] = LayerUtils.average_pooling_2d_input_legal
  79. self.available_model_level_layers['average_pooling_3d'] = LayerUtils.average_pooling_3d
  80. self.is_input_legal['average_pooling_3d'] = LayerUtils.average_pooling_3d_input_legal
  81. self.available_model_level_layers['batch_normalization'] = LayerUtils.batch_normalization
  82. self.is_input_legal['batch_normalization'] = LayerUtils.batch_normalization_input_legal
  83. self.available_model_level_layers['leaky_relu_layer'] = LayerUtils.leaky_relu_layer
  84. self.is_input_legal['leaky_relu_layer'] = LayerUtils.leaky_relu_layer_input_legal
  85. self.available_model_level_layers['prelu_layer'] = LayerUtils.prelu_layer
  86. self.is_input_legal['prelu_layer'] = LayerUtils.prelu_layer_input_legal
  87. self.available_model_level_layers['elu_layer'] = LayerUtils.elu_layer
  88. self.is_input_legal['elu_layer'] = LayerUtils.elu_layer_input_legal
  89. self.available_model_level_layers['thresholded_relu_layer'] = LayerUtils.thresholded_relu_layer
  90. self.is_input_legal['thresholded_relu_layer'] = LayerUtils.thresholded_relu_layer_input_legal
  91. self.available_model_level_layers['softmax_layer'] = LayerUtils.softmax_layer
  92. self.is_input_legal['softmax_layer'] = LayerUtils.softmax_layer_input_legal
  93. self.available_model_level_layers['relu_layer'] = LayerUtils.relu_layer
  94. self.is_input_legal['relu_layer'] = LayerUtils.relu_layer_input_legal
  95. self.available_source_level_layers['activity_regularization_l1'] = LayerUtils.activity_regularization_l1
  96. self.is_input_legal['activity_regularization_l1'] = LayerUtils.activity_regularization_input_legal
  97. self.available_source_level_layers['activity_regularization_l2'] = LayerUtils.activity_regularization_l1
  98. self.is_input_legal['activity_regularization_l2'] = LayerUtils.activity_regularization_input_legal
  99. def is_layer_in_weight_change_white_list(self, layer):
  100. import keras
  101. white_list = [keras.layers.Dense, keras.layers.Conv1D, keras.layers.Conv2D, keras.layers.Conv3D,
  102. keras.layers.DepthwiseConv2D,
  103. keras.layers.Conv2DTranspose, keras.layers.Conv3DTranspose,
  104. keras.layers.MaxPooling1D, keras.layers.MaxPooling2D, keras.layers.MaxPooling3D,
  105. keras.layers.AveragePooling1D, keras.layers.AveragePooling2D, keras.layers.AveragePooling3D,
  106. keras.layers.LeakyReLU, keras.layers.ELU, keras.layers.ThresholdedReLU,
  107. keras.layers.Softmax, keras.layers.ReLU
  108. ]
  109. # print(white_list)
  110. for l in white_list:
  111. if isinstance(layer, l):
  112. return True
  113. return False
  114. @staticmethod
  115. def clone(layer):
  116. from scripts.mutation.utils import ModelUtils
  117. custom_objects = ModelUtils.custom_objects()
  118. layer_config = layer.get_config()
  119. if 'activation' in layer_config.keys():
  120. activation = layer_config['activation']
  121. if activation in custom_objects.keys():
  122. layer_config['activation'] = 'relu'
  123. clone_layer = layer.__class__.from_config(layer_config)
  124. clone_layer.activation = custom_objects[activation]
  125. else:
  126. clone_layer = layer.__class__.from_config(layer_config)
  127. else:
  128. clone_layer = layer.__class__.from_config(layer_config)
  129. return clone_layer
  130. # return layer.__class__.from_config(layer.get_config())
  131. @staticmethod
  132. def dense(input_shape):
  133. # input_shape = input_shape.as_list()
  134. import keras
  135. layer = keras.layers.Dense(input_shape[-1], input_shape=(input_shape[1:],))
  136. layer.name += '_insert'
  137. return layer
  138. @staticmethod
  139. def dense_input_legal(input_shape):
  140. input_shape = input_shape.as_list()
  141. return len(input_shape) == 2 and input_shape[0] is None and input_shape[1] is not None
  142. @staticmethod
  143. def conv1d(input_shape):
  144. import keras
  145. layer = keras.layers.Conv1D(input_shape[-1], 3, strides=1, padding='same')
  146. layer.name += '_insert'
  147. return layer
  148. @staticmethod
  149. def conv1d_input_legal(input_shape):
  150. input_shape = input_shape.as_list()
  151. return len(input_shape) == 3 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3
  152. @staticmethod
  153. def conv2d(input_shape):
  154. # input_shape = input_shape.as_list()
  155. import keras
  156. layer = keras.layers.Conv2D(input_shape[-1], 3, strides=(1,1), padding='same')
  157. layer.name += '_insert'
  158. return layer
  159. @staticmethod
  160. def conv2d_input_legal(input_shape):
  161. input_shape = input_shape.as_list()
  162. return len(input_shape) == 4 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3 \
  163. and input_shape[2] is not None and input_shape[2] >= 3
  164. @staticmethod
  165. def separable_conv_1d(input_shape):
  166. import keras
  167. layer = keras.layers.SeparableConv1D(input_shape[-1], 3, strides=1, padding='same')
  168. layer.name += '_insert'
  169. return layer
  170. @staticmethod
  171. def separable_conv_1d_input_legal(input_shape):
  172. input_shape = input_shape.as_list()
  173. return len(input_shape) == 3 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3
  174. @staticmethod
  175. def separable_conv_2d(input_shape):
  176. import keras
  177. layer = keras.layers.SeparableConv2D(input_shape[-1], 3, strides=(1,1), padding='same')
  178. layer.name += '_insert'
  179. return layer
  180. @staticmethod
  181. def separable_conv_2d_input_legal(input_shape):
  182. input_shape = input_shape.as_list()
  183. return len(input_shape) == 4 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3 \
  184. and input_shape[2] is not None and input_shape[2] >= 3
  185. @staticmethod
  186. def depthwise_conv_2d(input_shape):
  187. import keras
  188. layer = keras.layers.DepthwiseConv2D(3, strides=(1,1), padding='same')
  189. layer.name += '_insert'
  190. return layer
  191. @staticmethod
  192. def depthwise_conv_2d_input_legal(input_shape):
  193. input_shape = input_shape.as_list()
  194. return len(input_shape) == 4 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3 \
  195. and input_shape[2] is not None and input_shape[2] >= 3
  196. @staticmethod
  197. def conv_2d_transpose(input_shape):
  198. import keras
  199. layer = keras.layers.Conv2DTranspose(input_shape[-1], 3, strides=(1,1), padding='same')
  200. layer.name += '_insert'
  201. return layer
  202. @staticmethod
  203. def conv_2d_transpose_input_legal(input_shape):
  204. input_shape = input_shape.as_list()
  205. return len(input_shape) == 4 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3 \
  206. and input_shape[2] is not None and input_shape[2] >= 3
  207. @staticmethod
  208. def conv_3d(input_shape):
  209. import keras
  210. layer = keras.layers.Conv3D(input_shape[-1], 3, strides=(1,1,1), padding='same')
  211. layer.name += '_insert'
  212. return layer
  213. @staticmethod
  214. def conv_3d_input_legal(input_shape):
  215. input_shape = input_shape.as_list()
  216. return len(input_shape) == 5 and input_shape[0] is None \
  217. and input_shape[1] is not None and input_shape[1] >= 3 \
  218. and input_shape[2] is not None and input_shape[2] >= 3 \
  219. and input_shape[3] is not None and input_shape[3] >= 3
  220. @staticmethod
  221. def conv_3d_transpose(input_shape):
  222. import keras
  223. layer = keras.layers.Conv3DTranspose(input_shape[-1], 3, strides=(1,1,1), padding='same')
  224. layer.name += '_insert'
  225. return layer
  226. @staticmethod
  227. def conv_3d_transpose_input_legal(input_shape):
  228. input_shape = input_shape.as_list()
  229. return len(input_shape) == 5 and input_shape[0] is None \
  230. and input_shape[1] is not None and input_shape[1] >= 3 \
  231. and input_shape[2] is not None and input_shape[2] >= 3 \
  232. and input_shape[3] is not None and input_shape[3] >= 3
  233. @staticmethod
  234. def max_pooling_1d(input_shape):
  235. import keras
  236. layer = keras.layers.MaxPooling1D(pool_size=3, strides=1, padding='same')
  237. layer.name += '_insert'
  238. return layer
  239. @staticmethod
  240. def max_pooling_1d_input_legal(input_shape):
  241. input_shape = input_shape.as_list()
  242. return len(input_shape) == 3 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3
  243. @staticmethod
  244. def max_pooling_2d(input_shape):
  245. import keras
  246. layer = keras.layers.MaxPooling2D(pool_size=(3, 3), strides=1, padding='same')
  247. layer.name += '_insert'
  248. return layer
  249. @staticmethod
  250. def max_pooling_2d_input_legal(input_shape):
  251. input_shape = input_shape.as_list()
  252. return len(input_shape) == 4 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3 \
  253. and input_shape[2] is not None and input_shape[2] >= 3
  254. @staticmethod
  255. def max_pooling_3d(input_shape):
  256. import keras
  257. layer = keras.layers.MaxPooling3D(pool_size=(3, 3, 3), strides=1, padding='same')
  258. layer.name += '_insert'
  259. return layer
  260. @staticmethod
  261. def max_pooling_3d_input_legal(input_shape):
  262. input_shape = input_shape.as_list()
  263. return len(input_shape) == 5 and input_shape[0] is None \
  264. and input_shape[1] is not None and input_shape[1] >= 3 \
  265. and input_shape[2] is not None and input_shape[2] >= 3 \
  266. and input_shape[3] is not None and input_shape[3] >= 3
  267. @staticmethod
  268. def average_pooling_1d(input_shape):
  269. import keras
  270. layer = keras.layers.AveragePooling1D(pool_size=3, strides=1, padding='same')
  271. layer.name += '_insert'
  272. return layer
  273. @staticmethod
  274. def average_pooling_1d_input_legal(input_shape):
  275. input_shape = input_shape.as_list()
  276. return len(input_shape) == 3 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3
  277. @staticmethod
  278. def average_pooling_2d(input_shape):
  279. import keras
  280. layer = keras.layers.AveragePooling2D(pool_size=(3, 3), strides=1, padding='same')
  281. layer.name += '_insert'
  282. return layer
  283. @staticmethod
  284. def average_pooling_2d_input_legal(input_shape):
  285. input_shape = input_shape.as_list()
  286. return len(input_shape) == 4 and input_shape[0] is None and input_shape[1] is not None and input_shape[1] >= 3 \
  287. and input_shape[2] is not None and input_shape[2] >= 3
  288. @staticmethod
  289. def average_pooling_3d(input_shape):
  290. import keras
  291. layer = keras.layers.AveragePooling3D(pool_size=(3, 3, 3), strides=1, padding='same')
  292. layer.name += '_insert'
  293. return layer
  294. @staticmethod
  295. def average_pooling_3d_input_legal(input_shape):
  296. input_shape = input_shape.as_list()
  297. return len(input_shape) == 5 and input_shape[0] is None \
  298. and input_shape[1] is not None and input_shape[1] >= 3 \
  299. and input_shape[2] is not None and input_shape[2] >= 3 \
  300. and input_shape[3] is not None and input_shape[3] >= 3
  301. @staticmethod
  302. def batch_normalization(input_shape):
  303. import keras
  304. layer = keras.layers.BatchNormalization(input_shape=input_shape[1:])
  305. layer.name += '_insert'
  306. return layer
  307. @staticmethod
  308. def batch_normalization_input_legal(input_shape):
  309. return True
  310. @staticmethod
  311. def leaky_relu_layer(input_shape):
  312. import keras
  313. layer = keras.layers.LeakyReLU(input_shape=input_shape[1:])
  314. layer.name += '_insert'
  315. return layer
  316. @staticmethod
  317. def leaky_relu_layer_input_legal(input_shape):
  318. return True
  319. @staticmethod
  320. def prelu_layer(input_shape):
  321. import keras
  322. layer = keras.layers.PReLU(input_shape=input_shape[1:], alpha_initializer='RandomNormal')
  323. layer.name += '_insert'
  324. return layer
  325. @staticmethod
  326. def prelu_layer_input_legal(input_shape):
  327. return True
  328. @staticmethod
  329. def elu_layer(input_shape):
  330. import keras
  331. layer = keras.layers.ELU(input_shape=input_shape[1:])
  332. layer.name += '_insert'
  333. return layer
  334. @staticmethod
  335. def elu_layer_input_legal(input_shape):
  336. return True
  337. @staticmethod
  338. def thresholded_relu_layer(input_shape):
  339. import keras
  340. layer = keras.layers.ThresholdedReLU(input_shape=input_shape[1:])
  341. layer.name += '_insert'
  342. return layer
  343. @staticmethod
  344. def thresholded_relu_layer_input_legal(input_shape):
  345. return True
  346. @staticmethod
  347. def softmax_layer(input_shape):
  348. import keras
  349. layer = keras.layers.Softmax(input_shape=input_shape[1:])
  350. layer.name += '_insert'
  351. return layer
  352. @staticmethod
  353. def softmax_layer_input_legal(input_shape):
  354. return True
  355. @staticmethod
  356. def relu_layer(input_shape):
  357. import keras
  358. layer = keras.layers.ReLU(max_value=1.0, input_shape=input_shape[1:])
  359. layer.name += '_insert'
  360. return layer
  361. @staticmethod
  362. def relu_layer_input_legal(input_shape):
  363. return True
  364. @staticmethod
  365. def activity_regularization_l1(input_shape):
  366. import keras
  367. layer = keras.layers.ActivityRegularization(l1=0.5, l2=0.0)
  368. layer.name += '_insert'
  369. return layer
  370. @staticmethod
  371. def activity_regularization_l2(input_shape):
  372. import keras
  373. layer = keras.layers.ActivityRegularization(l1=0.0, l2=0.5)
  374. layer.name += '_insert'
  375. return layer
  376. @staticmethod
  377. def activity_regularization_input_legal(input_shape):
  378. return True
  379. if __name__ == '__main__':
  380. activation_utils = ActivationUtils()
  381. result = activation_utils.pick_activation_randomly(['relu', 'leakyrelu'])
  382. print(result)
  383. layerUtils = LayerUtils()
  384. result = layerUtils.is_layer_in_weight_change_white_list(layerUtils.available_model_level_layers['dense']([None, 3]))
  385. print(result)