第13章 用序列化保存模型

深度学习的模型有可能需要好几天才能训练好,如果没有SL大法就完蛋了。本章关于如何保存和加载模型。本章将:

  • 使用HDF5格式保存模型
  • 使用JSON格式保存模型
  • 使用YAML格式保存模型

我们开始吧。

13.1 简介

Keras中,模型的结构和权重数据是分开的:权重的文件格式是HDF5,这种格式保存数字矩阵效率很高。模型的结构用JSON或YAML导入导出。

本章包括如何手工修改HDF5文件,使用的模型是第7章的皮马人糖尿病模型。

13.1.1 HDF5文件

分层数据格式,版本5(HDF5)可以高效保存大实数矩阵,例如神经网络的权重。HDF5的包需要安装:

  1. sudo pip install h5py

13.2 使用JSON保存网络结构

JSON的格式很简单,Keras可以用to_json()把模型导出为JSON格式,再用model_from_json()加载回来。

  1. 模型和权重加载后需要编译一次,让Keras正确调用后端。模型的验证方法和之前一致:
  2. 导出:
  3. ```python
  4. # MLP for Pima Indians Dataset serialize to JSON and HDF5
  5. from keras.models import Sequential
  6. from keras.layers import Dense
  7. from keras.models import model_from_json
  8. import numpy
  9. import os
  10. # fix random seed for reproducibility
  11. seed = 7
  12. numpy.random.seed(seed)
  13. # load pima indians dataset
  14. dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
  15. # split into input (X) and output (Y) variables
  16. X = dataset[:,0:8]
  17. Y = dataset[:,8]
  18. # create model
  19. model = Sequential()
  20. model.add(Dense(12, input_dim=8, init='uniform', activation='relu')) model.add(Dense(8, init='uniform', activation='relu'))
  21. model.add(Dense(1, init='uniform', activation='sigmoid'))
  22. # Compile model
  23. model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # Fit the model
  24. model.fit(X, Y, nb_epoch=150, batch_size=10, verbose=0)
  25. # evaluate the model
  26. scores = model.evaluate(X, Y, verbose=0)
  27. print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
  28. # serialize model to JSON
  29. model_json = model.to_json()
  30. with open("model.json", "w") as json_file:
  31. json_file.write(model_json)
  32. # serialize weights to HDF5
  33. model.save_weights("model.h5")
  34. print("Saved model to disk")

导入:

  1. # later...
  2. # load json and create model
  3. # MLP for Pima Indians Dataset serialize to JSON and HDF5
  4. from keras.models import Sequential
  5. from keras.layers import Dense
  6. from keras.models import model_from_json
  7. import numpy
  8. import os
  9. # fix random seed for reproducibility
  10. seed = 7
  11. numpy.random.seed(seed)
  12. # load pima indians dataset
  13. dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
  14. # split into input (X) and output (Y) variables
  15. X = dataset[:,0:8]
  16. Y = dataset[:,8]
  17. # create model
  18. model = Sequential()
  19. model.add(Dense(12, input_dim=8, init='uniform', activation='relu')) model.add(Dense(8, init='uniform', activation='relu'))
  20. model.add(Dense(1, init='uniform', activation='sigmoid'))
  21. # Compile model
  22. model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # Fit the model
  23. model.fit(X, Y, nb_epoch=150, batch_size=10, verbose=0)
  24. # evaluate the model
  25. scores = model.evaluate(X, Y, verbose=0)
  26. print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
  27. # serialize model to JSON
  28. model_json = model.to_json()
  29. with open("model.json", "w") as json_file:
  30. json_file.write(model_json)
  31. # serialize weights to HDF5
  32. model.save_weights("model.h5")
  33. print("Saved model to disk")
  34. # later...
  35. # load json and create model

结果如下。导入的模型和之前导出时一致:

  1. acc: 79.56%
  2. Saved model to disk
  3. Loaded model from disk
  4. acc: 79.56%

JSON文件类似:

  1. {
  2. "class_name": "Sequential",
  3. "config": [{
  4. "class_name": "Dense",
  5. "config": {
  6. "W_constraint": null,
  7. "b_constraint": null,
  8. "name": "dense_1",
  9. "output_dim": 12,
  10. "activity_regularizer": null,
  11. "trainable": true,
  12. "init": "uniform",
  13. "input_dtype": "float32",
  14. "input_dim": 8,
  15. "b_regularizer": null,
  16. "W_regularizer": null,
  17. "activation": "relu",
  18. "batch_input_shape": [
  19. null,
  20. 8
  21. ]
  22. }
  23. },
  24. {
  25. "class_name": "Dense",
  26. "config": {
  27. "W_constraint": null,
  28. "b_constraint": null,
  29. "name": "dense_2",
  30. "activity_regularizer": null,
  31. "trainable": true,
  32. "init": "uniform",
  33. "input_dim": null,
  34. "b_regularizer": null,
  35. "W_regularizer": null,
  36. "activation": "relu",
  37. "output_dim": 8
  38. }
  39. },
  40. {
  41. "class_name": "Dense",
  42. "config": {
  43. "W_constraint": null,
  44. "b_constraint": null,
  45. "name": "dense_3",
  46. "activity_regularizer": null,
  47. "trainable": true,
  48. "init": "uniform",
  49. "input_dim": null,
  50. "b_regularizer": null,
  51. "W_regularizer": null,
  52. "activation": "sigmoid",
  53. "output_dim": 1
  54. }
  55. }
  56. ]
  57. }

13.3 使用YAML保存网络结构

和之前JSON类似,只不过文件格式变成YAML,使用的函数变成了to_yaml()model_from_yaml()

  1. # MLP for Pima Indians Dataset serialize to YAML and HDF5
  2. from keras.models import Sequential
  3. from keras.layers import Dense
  4. from keras.models import model_from_yaml
  5. import numpy
  6. import os
  7. # fix random seed for reproducibility
  8. seed = 7
  9. numpy.random.seed(seed)
  10. # load pima indians dataset
  11. dataset = numpy.loadtxt("pima-indians-diabetes.csv", delimiter=",")
  12. # split into input (X) and output (Y) variables
  13. X = dataset[:,0:8]
  14. Y = dataset[:,8]
  15. # create model
  16. model = Sequential()
  17. model.add(Dense(12, input_dim=8, init='uniform', activation='relu')) model.add(Dense(8, init='uniform', activation='relu'))
  18. model.add(Dense(1, init='uniform', activation='sigmoid'))
  19. # Compile model
  20. model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy']) # Fit the model
  21. model.fit(X, Y, nb_epoch=150, batch_size=10, verbose=0)
  22. # evaluate the model
  23. scores = model.evaluate(X, Y, verbose=0)
  24. print("%s: %.2f%%" % (model.metrics_names[1], scores[1]*100))
  25. # serialize model to YAML
  26. model_yaml = model.to_yaml()
  27. with open("model.yaml", "w") as yaml_file:
  28. yaml_file.write(model_yaml)
  29. # serialize weights to HDF5
  30. model.save_weights("model.h5")
  31. print("Saved model to disk")
  32. # later...
  33. # load YAML and create model
  34. yaml_file = open('model.yaml', 'r') loaded_model_yaml = yaml_file.read() yaml_file.close()
  35. loaded_model = model_from_yaml(loaded_model_yaml) # load weights into new model loaded_model.load_weights("model.h5") print("Loaded model from disk")
  36. # evaluate loaded model on test data
  37. loaded_model.compile(loss='binary_crossentropy', optimizer='rmsprop', metrics=['accuracy']) score = loaded_model.evaluate(X, Y, verbose=0)
  38. print "%s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100)

结果和之前的一样:

  1. acc: 79.56%
  2. Saved model to disk
  3. Loaded model from disk
  4. acc: 79.56%

YAML文件长这样:

  1. class_name: Sequential
  2. config:
  3. - class_name: Dense
  4. config:
  5. W_constraint: null
  6. W_regularizer: null
  7. activation: relu
  8. activity_regularizer: null
  9. b_constraint: null
  10. b_regularizer: null
  11. batch_input_shape: !!python/tuple [null, 8]
  12. init: uniform
  13. input_dim: 8
  14. input_dtype: float32
  15. name: dense_1
  16. output_dim: 12
  17. trainable: true
  18. - class_name: Dense
  19. config: {W_constraint: null, W_regularizer: null, activation: relu, activity_regularizer:
  20. null,
  21. b_constraint: null, b_regularizer: null, init: uniform, input_dim: null, name: dense_2,
  22. output_dim: 8, trainable: true}
  23. - class_name: Dense
  24. config: {W_constraint: null, W_regularizer: null, activation: sigmoid,
  25. activity_regularizer: null,
  26. b_constraint: null, b_regularizer: null, init: uniform, input_dim: null, name: dense_3,
  27. output_dim: 1, trainable: true}

13.4 总结

本章关于导入导出Keras模型。总结一下:

  • 如何用HDF5保存加载权重
  • 如何用JSON保存加载模型
  • 如何用YAML保存加载模型
13.4.1 下一章

模型可以保存了:下一章关于使用保存点。