You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

test_model_save_graph.py 20 kB

4 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. import os
  4. import unittest
  5. os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
  6. import numpy as np
  7. import tensorflow as tf
  8. import tensorlayer as tl
  9. from tensorlayer.layers import *
  10. from tensorlayer.models import *
  11. from tests.utils import CustomTestCase
  12. def RemoveDateInConfig(config):
  13. config["version_info"]["save_date"] = None
  14. return config
  15. def basic_static_model():
  16. ni = Input((None, 24, 24, 3))
  17. nn = Conv2d(16, (5, 5), (1, 1), padding='SAME', act=tf.nn.relu, name="conv1")(ni)
  18. nn = MaxPool2d((3, 3), (2, 2), padding='SAME', name='pool1')(nn)
  19. nn = Conv2d(16, (5, 5), (1, 1), padding='SAME', act=tf.nn.relu, name="conv2")(nn)
  20. nn = MaxPool2d((3, 3), (2, 2), padding='SAME', name='pool2')(nn)
  21. nn = Flatten(name='flatten')(nn)
  22. nn = Dense(100, act=None, name="dense1")(nn)
  23. M = Model(inputs=ni, outputs=nn)
  24. return M
  25. class Model_Save_and_Load_without_weights(CustomTestCase):
  26. @classmethod
  27. def setUpClass(cls):
  28. print("##### begin testing save_graph, load_graph, without weights #####")
  29. def test_save(self):
  30. M1 = basic_static_model()
  31. print("Model config = \n", M1.config)
  32. print("Model = \n", M1)
  33. M1.save(filepath="basic_model_without_weights.hdf5", save_weights=False)
  34. M2 = Model.load(filepath="basic_model_without_weights.hdf5", load_weights=False)
  35. M1_config = RemoveDateInConfig(M1.config)
  36. M2_config = RemoveDateInConfig(M2.config)
  37. self.assertEqual(M1_config, M2_config)
  38. def get_model(inputs_shape):
  39. ni = Input(inputs_shape)
  40. nn = Dropout(keep=0.8)(ni)
  41. nn = Dense(n_units=800, act=tf.nn.relu,
  42. in_channels=784)(nn) # in_channels is optional in this case as it can be inferred by the previous layer
  43. nn = Dropout(keep=0.8)(nn)
  44. nn = Dense(n_units=800, act=tf.nn.relu,
  45. in_channels=800)(nn) # in_channels is optional in this case as it can be inferred by the previous layer
  46. nn = Dropout(keep=0.8)(nn)
  47. nn = Dense(n_units=10, act=tf.nn.relu,
  48. in_channels=800)(nn) # in_channels is optional in this case as it can be inferred by the previous layer
  49. M = Model(inputs=ni, outputs=nn)
  50. return M
  51. class Model_Save_with_weights(CustomTestCase):
  52. @classmethod
  53. def setUpClass(cls):
  54. print("##### begin testing save_graph, after training, with weights #####")
  55. def test_save(self):
  56. tl.logging.set_verbosity(tl.logging.DEBUG)
  57. X_train, y_train, X_val, y_val, X_test, y_test = tl.files.load_mnist_dataset(shape=(-1, 784))
  58. MLP = get_model([None, 784])
  59. print(MLP)
  60. n_epoch = 3
  61. batch_size = 500
  62. train_weights = MLP.trainable_weights
  63. optimizer = tf.optimizers.Adam(lr=0.0001)
  64. for epoch in range(n_epoch): ## iterate the dataset n_epoch times
  65. print("epoch = ", epoch)
  66. for X_batch, y_batch in tl.iterate.minibatches(X_train, y_train, batch_size, shuffle=True):
  67. MLP.train() # enable dropout
  68. with tf.GradientTape() as tape:
  69. ## compute outputs
  70. _logits = MLP(X_batch) # alternatively, you can use MLP(x, is_train=True) and remove MLP.train()
  71. ## compute loss and update model
  72. _loss = tl.cost.cross_entropy(_logits, y_batch, name='train_loss')
  73. grad = tape.gradient(_loss, train_weights)
  74. optimizer.apply_gradients(zip(grad, train_weights))
  75. MLP.eval()
  76. val_loss, val_acc, n_iter = 0, 0, 0
  77. for X_batch, y_batch in tl.iterate.minibatches(X_val, y_val, batch_size, shuffle=False):
  78. _logits = MLP(X_batch) # is_train=False, disable dropout
  79. val_loss += tl.cost.cross_entropy(_logits, y_batch, name='eval_loss')
  80. val_acc += np.mean(np.equal(np.argmax(_logits, 1), y_batch))
  81. n_iter += 1
  82. print(" val loss: {}".format(val_loss / n_iter))
  83. print(" val acc: {}".format(val_acc / n_iter))
  84. MLP.save("MLP.hdf5")
  85. class Model_Load_with_weights_and_train(CustomTestCase):
  86. @classmethod
  87. def setUpClass(cls):
  88. print("##### begin testing load_graph, after training, with weights, and train again #####")
  89. def test_save(self):
  90. MLP = Model.load("MLP.hdf5", )
  91. MLP.eval()
  92. n_epoch = 3
  93. batch_size = 500
  94. train_weights = MLP.trainable_weights
  95. optimizer = tf.optimizers.Adam(lr=0.0001)
  96. X_train, y_train, X_val, y_val, X_test, y_test = tl.files.load_mnist_dataset(shape=(-1, 784))
  97. val_loss, val_acc, n_iter = 0, 0, 0
  98. for X_batch, y_batch in tl.iterate.minibatches(X_val, y_val, batch_size, shuffle=False):
  99. _logits = MLP(X_batch) # is_train=False, disable dropout
  100. val_loss += tl.cost.cross_entropy(_logits, y_batch, name='eval_loss')
  101. val_acc += np.mean(np.equal(np.argmax(_logits, 1), y_batch))
  102. n_iter += 1
  103. print(" val loss: {}".format(val_loss / n_iter))
  104. print(" val acc: {}".format(val_acc / n_iter))
  105. assert val_acc > 0.7
  106. for epoch in range(n_epoch): ## iterate the dataset n_epoch times
  107. print("epoch = ", epoch)
  108. for X_batch, y_batch in tl.iterate.minibatches(X_train, y_train, batch_size, shuffle=True):
  109. MLP.train() # enable dropout
  110. with tf.GradientTape() as tape:
  111. ## compute outputs
  112. _logits = MLP(X_batch) # alternatively, you can use MLP(x, is_train=True) and remove MLP.train()
  113. ## compute loss and update model
  114. _loss = tl.cost.cross_entropy(_logits, y_batch, name='train_loss')
  115. grad = tape.gradient(_loss, train_weights)
  116. optimizer.apply_gradients(zip(grad, train_weights))
  117. MLP.save("MLP.hdf5")
  118. def create_base_network(input_shape):
  119. '''Base network to be shared (eq. to feature extraction).
  120. '''
  121. input = Input(shape=input_shape)
  122. x = Flatten()(input)
  123. x = Dense(128, act=tf.nn.relu)(x)
  124. x = Dropout(0.9)(x)
  125. x = Dense(128, act=tf.nn.relu)(x)
  126. x = Dropout(0.9)(x)
  127. x = Dense(128, act=tf.nn.relu)(x)
  128. return Model(input, x)
  129. def get_siamese_network(input_shape):
  130. """Create siamese network with shared base network as layer
  131. """
  132. base_layer = create_base_network(input_shape).as_layer()
  133. ni_1 = Input(input_shape)
  134. ni_2 = Input(input_shape)
  135. nn_1 = base_layer(ni_1)
  136. nn_2 = base_layer(ni_2)
  137. return Model(inputs=[ni_1, ni_2], outputs=[nn_1, nn_2])
  138. class Reuse_ModelLayer_test(CustomTestCase):
  139. @classmethod
  140. def setUpClass(cls):
  141. print("##### begin testing save_graph, load_graph, including ModelLayer and reuse #####")
  142. def test_save(self):
  143. input_shape = (None, 784)
  144. M1 = get_siamese_network(input_shape)
  145. print("Model config = \n", M1.config)
  146. print("Model = \n", M1)
  147. M1.save(filepath="siamese.hdf5", save_weights=False)
  148. M2 = Model.load(filepath="siamese.hdf5", load_weights=False)
  149. M1_config = RemoveDateInConfig(M1.config)
  150. M2_config = RemoveDateInConfig(M2.config)
  151. self.assertEqual(M1_config, M2_config)
  152. class Vgg_LayerList_test(CustomTestCase):
  153. @classmethod
  154. def setUpClass(cls):
  155. print("##### begin testing save_graph, load_graph, including LayerList #####")
  156. def test_save(self):
  157. M1 = tl.models.vgg16(mode='static')
  158. print("Model config = \n", M1.config)
  159. print("Model = \n", M1)
  160. M1.save(filepath="vgg.hdf5", save_weights=False)
  161. M2 = Model.load(filepath="vgg.hdf5", load_weights=False)
  162. M1_config = RemoveDateInConfig(M1.config)
  163. M2_config = RemoveDateInConfig(M2.config)
  164. self.assertEqual(M1_config, M2_config)
  165. class List_inputs_outputs_test(CustomTestCase):
  166. @classmethod
  167. def setUpClass(cls):
  168. print("##### begin testing model with list inputs and outputs #####")
  169. def test_list_inputs_outputs(self):
  170. ni_1 = Input(shape=[4, 16])
  171. ni_2 = Input(shape=[4, 32])
  172. a_1 = Dense(80)(ni_1)
  173. b_1 = Dense(160)(ni_2)
  174. concat = Concat()([a_1, b_1])
  175. a_2 = Dense(10)(concat)
  176. b_2 = Dense(20)(concat)
  177. M1 = Model(inputs=[ni_1, ni_2], outputs=[a_2, b_2])
  178. print("Model config = \n", M1.config)
  179. print("Model = \n", M1)
  180. M1.save(filepath="list.hdf5", save_weights=False)
  181. M2 = Model.load(filepath="list.hdf5", load_weights=False)
  182. M1_config = RemoveDateInConfig(M1.config)
  183. M2_config = RemoveDateInConfig(M2.config)
  184. self.assertEqual(M1_config, M2_config)
  185. class Lambda_layer_test(CustomTestCase):
  186. @classmethod
  187. def setUpClass(cls):
  188. print("##### begin testing lambda layer #####")
  189. def test_lambda_layer_no_para_no_args(self):
  190. x = tl.layers.Input([8, 3], name='input')
  191. y = tl.layers.Lambda(lambda x: 2 * x, name='lambda')(x)
  192. M1 = tl.models.Model(x, y)
  193. M1.save("lambda_no_para_no_args.hdf5")
  194. M2 = tl.models.Model.load("lambda_no_para_no_args.hdf5")
  195. print(M1)
  196. print(M2)
  197. M1.eval()
  198. M2.eval()
  199. npInput = np.zeros((8, 3)) + 3
  200. output1 = M1(npInput).numpy()
  201. output2 = M1(npInput).numpy()
  202. M1_config = RemoveDateInConfig(M1.config)
  203. M2_config = RemoveDateInConfig(M2.config)
  204. self.assertEqual((output1 == output2).all(), True)
  205. self.assertEqual(M1_config, M2_config)
  206. def test_lambda_layer_no_para_with_args(self):
  207. def customize_func(x, foo=42): # x is the inputs, foo is an argument
  208. return foo * x
  209. x = tl.layers.Input([8, 3], name='input')
  210. y = tl.layers.Lambda(customize_func, fn_args={'foo': 3}, name='lambda')(x)
  211. M1 = tl.models.Model(x, y)
  212. M1.save("lambda_no_para_with_args.hdf5")
  213. M2 = tl.models.Model.load("lambda_no_para_with_args.hdf5")
  214. print(M1)
  215. print(M2)
  216. M1.eval()
  217. M2.eval()
  218. npInput = np.zeros((8, 3)) + 3
  219. output1 = M1(npInput).numpy()
  220. output2 = M2(npInput).numpy()
  221. M1_config = RemoveDateInConfig(M1.config)
  222. M2_config = RemoveDateInConfig(M2.config)
  223. self.assertEqual((output1 == output2).all(), True)
  224. self.assertEqual((output1 == (np.zeros((8, 3)) + 9)).all(), True)
  225. self.assertEqual(M1_config, M2_config)
  226. def test_lambda_layer_keras_model(self):
  227. input_shape = [100, 5]
  228. in_2 = tl.layers.Input(input_shape, name='input')
  229. layers = [
  230. tf.keras.layers.Dense(10, activation=tf.nn.relu),
  231. tf.keras.layers.Dense(5, activation=tf.nn.sigmoid),
  232. tf.keras.layers.Dense(1, activation=tf.nn.relu)
  233. ]
  234. perceptron = tf.keras.Sequential(layers)
  235. # in order to compile keras model and get trainable_variables of the keras model
  236. _ = perceptron(np.random.random(input_shape).astype(np.float32))
  237. plambdalayer = tl.layers.Lambda(perceptron, perceptron.trainable_variables)(in_2)
  238. M2 = tl.models.Model(inputs=in_2, outputs=plambdalayer)
  239. M2.save('M2_keras.hdf5')
  240. M4 = Model.load('M2_keras.hdf5')
  241. M2.eval()
  242. M4.eval()
  243. npInput = np.zeros(input_shape) + 3
  244. output2 = M2(npInput).numpy()
  245. output4 = M4(npInput).numpy()
  246. M2_config = RemoveDateInConfig(M2.config)
  247. M4_config = RemoveDateInConfig(M4.config)
  248. self.assertEqual((output2 == output4).all(), True)
  249. self.assertEqual(M2_config, M4_config)
  250. ori_weights = M4.all_weights
  251. ori_val = ori_weights[1].numpy()
  252. modify_val = np.zeros_like(ori_val) + 10
  253. M4.all_weights[1].assign(modify_val)
  254. M4 = Model.load('M2_keras.hdf5')
  255. self.assertLess(np.max(np.abs(ori_val - M4.all_weights[1].numpy())), 1e-7)
  256. def test_lambda_layer_keras_layer(self):
  257. input_shape = [100, 5]
  258. in_1 = tl.layers.Input(input_shape, name='input')
  259. denselayer = tf.keras.layers.Dense(10, activation=tf.nn.relu)
  260. # in order to compile keras model and get trainable_variables of the keras model
  261. _ = denselayer(np.random.random(input_shape).astype(np.float32))
  262. dlambdalayer = tl.layers.Lambda(denselayer, denselayer.trainable_variables)(in_1)
  263. M1 = tl.models.Model(inputs=in_1, outputs=dlambdalayer)
  264. M1.save('M1_keras.hdf5')
  265. M3 = Model.load('M1_keras.hdf5')
  266. M1.eval()
  267. M3.eval()
  268. npInput = np.zeros(input_shape) + 3
  269. output1 = M1(npInput).numpy()
  270. output3 = M3(npInput).numpy()
  271. M1_config = RemoveDateInConfig(M1.config)
  272. M3_config = RemoveDateInConfig(M3.config)
  273. self.assertEqual((output1 == output3).all(), True)
  274. self.assertEqual(M1_config, M3_config)
  275. ori_weights = M3.all_weights
  276. ori_val = ori_weights[1].numpy()
  277. modify_val = np.zeros_like(ori_val) + 10
  278. M3.all_weights[1].assign(modify_val)
  279. M3 = Model.load('M1_keras.hdf5')
  280. self.assertLess(np.max(np.abs(ori_val - M3.all_weights[1].numpy())), 1e-7)
  281. class ElementWise_lambda_test(CustomTestCase):
  282. @classmethod
  283. def setUpClass(cls):
  284. print("##### begin testing elementwise lambda layer #####")
  285. def test_elementwise_no_para_with_args(self):
  286. # z = mean + noise * tf.exp(std * 0.5) + foo
  287. def func(noise, mean, std, foo=42):
  288. return mean + noise * tf.exp(std * 0.5) + foo
  289. noise = tl.layers.Input([100, 1])
  290. mean = tl.layers.Input([100, 1])
  291. std = tl.layers.Input([100, 1])
  292. out = tl.layers.ElementwiseLambda(fn=func, fn_args={'foo': 84}, name='elementwiselambda')([noise, mean, std])
  293. M1 = Model(inputs=[noise, mean, std], outputs=out)
  294. M1.save("elementwise_npwa.hdf5")
  295. M2 = Model.load("elementwise_npwa.hdf5")
  296. M1.eval()
  297. M2.eval()
  298. ipt = [np.zeros((100, 1)) + 11, np.zeros((100, 1)) + 21, np.zeros((100, 1)) + 31]
  299. output1 = M1(ipt).numpy()
  300. output2 = M2(ipt).numpy()
  301. M1_config = RemoveDateInConfig(M1.config)
  302. M2_config = RemoveDateInConfig(M2.config)
  303. self.assertEqual((output1 == output2).all(), True)
  304. self.assertEqual(M1_config, M2_config)
  305. def test_elementwise_no_para_no_args(self):
  306. # z = mean + noise * tf.exp(std * 0.5) + foo
  307. def func(noise, mean, std, foo=42):
  308. return mean + noise * tf.exp(std * 0.5) + foo
  309. noise = tl.layers.Input([100, 1])
  310. mean = tl.layers.Input([100, 1])
  311. std = tl.layers.Input([100, 1])
  312. out = tl.layers.ElementwiseLambda(fn=func, name='elementwiselambda')([noise, mean, std])
  313. M1 = Model(inputs=[noise, mean, std], outputs=out)
  314. M1.save("elementwise_npna.hdf5")
  315. M2 = Model.load("elementwise_npna.hdf5")
  316. M1.eval()
  317. M2.eval()
  318. ipt = [np.zeros((100, 1)) + 11, np.zeros((100, 1)) + 21, np.zeros((100, 1)) + 31]
  319. output1 = M1(ipt).numpy()
  320. output2 = M2(ipt).numpy()
  321. M1_config = RemoveDateInConfig(M1.config)
  322. M2_config = RemoveDateInConfig(M2.config)
  323. self.assertEqual((output1 == output2).all(), True)
  324. self.assertEqual(M1_config, M2_config)
  325. def test_elementwise_lambda_func(self):
  326. # z = mean + noise * tf.exp(std * 0.5)
  327. noise = tl.layers.Input([100, 1])
  328. mean = tl.layers.Input([100, 1])
  329. std = tl.layers.Input([100, 1])
  330. out = tl.layers.ElementwiseLambda(fn=lambda x, y, z: x + y * tf.exp(z * 0.5),
  331. name='elementwiselambda')([noise, mean, std])
  332. M1 = Model(inputs=[noise, mean, std], outputs=out)
  333. M1.save("elementwise_lambda.hdf5")
  334. M2 = Model.load("elementwise_lambda.hdf5")
  335. M1.eval()
  336. M2.eval()
  337. ipt = [
  338. (np.zeros((100, 1)) + 11).astype(np.float32), (np.zeros((100, 1)) + 21).astype(np.float32),
  339. (np.zeros((100, 1)) + 31).astype(np.float32)
  340. ]
  341. output1 = M1(ipt).numpy()
  342. output2 = M2(ipt).numpy()
  343. M1_config = RemoveDateInConfig(M1.config)
  344. M2_config = RemoveDateInConfig(M2.config)
  345. self.assertEqual((output1 == output2).all(), True)
  346. self.assertEqual(M1_config, M2_config)
  347. # # ElementwiseLambda does not support keras layer/model func yet
  348. # def test_elementwise_keras_model(self):
  349. # kerasinput1 = tf.keras.layers.Input(shape=(100, ))
  350. # kerasinput2 = tf.keras.layers.Input(shape=(100, ))
  351. # kerasconcate = tf.keras.layers.concatenate(inputs=[kerasinput1, kerasinput2])
  352. # kerasmodel = tf.keras.models.Model(inputs=[kerasinput1, kerasinput2], outputs=kerasconcate)
  353. # _ = kerasmodel([np.random.random([100,]).astype(np.float32), np.random.random([100,]).astype(np.float32)])
  354. #
  355. # input1 = tl.layers.Input([100, 1])
  356. # input2 = tl.layers.Input([100, 1])
  357. # out = tl.layers.ElementwiseLambda(fn=kerasmodel, name='elementwiselambda')([input1, input2])
  358. # M1 = Model(inputs=[input1, input2], outputs=out)
  359. # M1.save("elementwise_keras_model.hdf5")
  360. # M2 = Model.load("elementwise_keras_model.hdf5")
  361. #
  362. # M1.eval()
  363. # M2.eval()
  364. # ipt = [np.zeros((100, 1)) + 11, np.zeros((100, 1)) + 21, np.zeros((100, 1)) + 31]
  365. # output1 = M1(ipt).numpy()
  366. # output2 = M2(ipt).numpy()
  367. #
  368. # M1_config = RemoveDateInConfig(M1.config)
  369. # M2_config = RemoveDateInConfig(M2.config)
  370. #
  371. # self.assertEqual((output1 == output2).all(), True)
  372. # self.assertEqual(M1_config, M2_config)
  373. class basic_dynamic_model(Model):
  374. def __init__(self):
  375. super(basic_dynamic_model, self).__init__()
  376. self.conv1 = Conv2d(16, (5, 5), (1, 1), padding='SAME', act=tf.nn.relu, in_channels=3, name="conv1")
  377. self.pool1 = MaxPool2d((3, 3), (2, 2), padding='SAME', name='pool1')
  378. self.conv2 = Conv2d(16, (5, 5), (1, 1), padding='SAME', act=tf.nn.relu, in_channels=16, name="conv2")
  379. self.pool2 = MaxPool2d((3, 3), (2, 2), padding='SAME', name='pool2')
  380. self.flatten = Flatten(name='flatten')
  381. self.dense1 = Dense(100, act=None, in_channels=576, name="dense1")
  382. self.dense2 = Dense(10, act=None, in_channels=100, name="dense2")
  383. def forward(self, x):
  384. x = self.conv1(x)
  385. x = self.pool1(x)
  386. x = self.conv2(x)
  387. x = self.pool2(x)
  388. x = self.flatten(x)
  389. x = self.dense1(x)
  390. x = self.dense2(x)
  391. return x
  392. class Dynamic_config_test(CustomTestCase):
  393. @classmethod
  394. def setUpClass(cls):
  395. print("##### begin testing exception in dynamic mode #####")
  396. def test_dynamic_config(self):
  397. M1 = basic_dynamic_model()
  398. print(M1.config)
  399. for layer in M1.all_layers:
  400. print(layer.config)
  401. class Exception_test(CustomTestCase):
  402. @classmethod
  403. def setUpClass(cls):
  404. print("##### begin testing exception in dynamic mode #####")
  405. def test_exception(self):
  406. M1 = basic_dynamic_model()
  407. try:
  408. M1.save("dynamic.hdf5", save_weights=False)
  409. except Exception as e:
  410. self.assertIsInstance(e, RuntimeError)
  411. print(e)
  412. M2 = basic_static_model()
  413. M2.save("basic_static_mode.hdf5", save_weights=False)
  414. try:
  415. M3 = Model.load("basic_static_mode.hdf5")
  416. except Exception as e:
  417. self.assertIsInstance(e, RuntimeError)
  418. print(e)
  419. if __name__ == '__main__':
  420. tl.logging.set_verbosity(tl.logging.DEBUG)
  421. unittest.main()

TensorLayer3.0 是一款兼容多种深度学习框架为计算后端的深度学习库。计划兼容TensorFlow, Pytorch, MindSpore, Paddle.