[手抄] Keras官方教程 - 模型保存

2018-07-05 keras, learn

官方教程,记录以便查阅!

以下代码运行环境为 —— keras[2.2.4], tensorflow[1.11.0]

How can I save a Keras model?

Saving/loading whole models (architecture + weights + optimizer state)

It is not recommended to use pickle or cPickle to save a Keras model.

You can use model.save(filepath) to save a Keras model into a single HDF5 file which will contain:

the architecture of the model, allowing to re-create the model the weights of the model the training configuration (loss, optimizer) the state of the optimizer, allowing to resume training exactly where you left off. You can then use keras.models.load_model(filepath) to reinstantiate your model. load_model will also take care of compiling the model using the saved training configuration (unless the model was never compiled in the first place).

Example:

In [ ]:
from keras.models import load_model
from keras.models import Model
from keras.layers import Input, Embedding, Dense

x_input = Input(shape=(100,), dtype='int32', name='model_input0')
x = Embedding(output_dim=512, input_dim=1000, input_length=100)(x_input)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
x = Dense(64, activation='relu')(x)
y = Dense(1, activation='sigmoid')(x)

model = Model(inputs=x_input, outputs=y)

model.save('my_model.h5')  # creates a HDF5 file 'my_model.h5'
del model  # deletes the existing model

# returns a compiled model
# identical to the previous one
model = load_model('my_model.h5')

Saving/loading only a model's architecture

If you only need to save the architecture of a model, and not its weights or its training configuration, you can do:

In [ ]:
# save as JSON
json_string = model.to_json()

# save as YAML
yaml_string = model.to_yaml()

Saving/loading only a model's weights

If you need to save the weights of a model, you can do so in HDF5 with the code below:

In [ ]:
model.save_weights('my_model_weights.h5')
In [ ]:
model.load_weights('my_model_weights.h5')

If you need to load the weights into a different architecture (with some layers in common), for instance for fine-tuning or transfer-learning, you can load them by layer name:

In [ ]:
model.load_weights('my_model_weights.h5', by_name=True)
In [ ]:
"""
Assuming the original model looks like this:
    model = Sequential()
    model.add(Dense(2, input_dim=3, name='dense_1'))
    model.add(Dense(3, name='dense_2'))
    ...
    model.save_weights(fname)
"""

from keras.models import Sequential
fname  = 'my_model_weights.h5'

# new model
model = Sequential()
model.add(Dense(2, input_dim=3, name='dense_1'))  # will be loaded
model.add(Dense(10, name='new_dense'))  # will not be loaded

# load weights from first model; will only affect the first layer, dense_1.
model.load_weights(fname, by_name=True)

Handling custom layers (or other custom objects) in saved models

If the model you want to load includes custom layers or other custom classes or functions, you can pass them to the loading mechanism via the custom_objects argument:

In [ ]:
from keras.models import load_model
# Assuming your model includes instance of an "AttentionLayer" class
model = load_model('my_model.h5', custom_objects={'AttentionLayer': AttentionLayer})

Alternatively, you can use a custom object scope:

In [ ]:
from keras.utils import CustomObjectScope

with CustomObjectScope({'AttentionLayer': AttentionLayer}):
    model = load_model('my_model.h5')

Custom objects handling works the same way for load_model, model_from_json, model_from_yaml:

In [ ]:
from keras.models import model_from_json
model = model_from_json(json_string, custom_objects={'AttentionLayer': AttentionLayer})

How can I obtain the output of an intermediate layer?

One simple way is to create a new Model that will output the layers that you are interested in:

In [ ]:
from keras.models import Model

model = ...  # create the original model

layer_name = 'my_layer'
intermediate_layer_model = Model(inputs=model.input,
                                 outputs=model.get_layer(layer_name).output)
intermediate_output = intermediate_layer_model.predict(data)

Alternatively, you can build a Keras function that will return the output of a certain layer given a certain input, for example:

In [ ]:
from keras import backend as K

# with a Sequential model
get_3rd_layer_output = K.function([model.layers[0].input],
                                  [model.layers[3].output])
layer_output = get_3rd_layer_output([x])[0]

model checkpoints

In [ ]:
import keras
In [1]:
from keras.callbacks import ModelCheckpoint, TensorBoard
from keras.layers import Dense, Activation
from keras.models import Sequential
import numpy as np
import tensorflow as tf
import keras
x_train = np.random.random((1000, 784))
y_train = np.random.randint(10, size=1000)
y_train = keras.utils.to_categorical(y_train, num_classes=10)
X_test = np.random.random((100, 784))
Y_test = np.random.randint(10, size=100)
Y_test = keras.utils.to_categorical(Y_test, num_classes=10)

model = Sequential()
model.add(Dense(10, input_dim=784, kernel_initializer='uniform'))
model.add(Activation('softmax'))
model.compile(loss='categorical_crossentropy', optimizer='rmsprop')

'''
saves the model weights after each epoch if the validation loss decreased
'''
checkpointer = ModelCheckpoint(filepath='/tmp/weights.hdf5', verbose=1, save_best_only=True)
# boarder = TensorBoard(log_dir='./logs')
boarder = tf.keras.callbacks.TensorBoard(log_dir='./logs')
model.fit(x_train, y_train, batch_size=128, epochs=20, verbose=0, validation_data=(X_test, Y_test), callbacks=[checkpointer, boarder])
Using TensorFlow backend.
Epoch 00001: val_loss improved from inf to 2.31371, saving model to /tmp/weights.hdf5

Epoch 00002: val_loss improved from 2.31371 to 2.29954, saving model to /tmp/weights.hdf5

Epoch 00003: val_loss did not improve from 2.29954

Epoch 00004: val_loss improved from 2.29954 to 2.27591, saving model to /tmp/weights.hdf5

Epoch 00005: val_loss improved from 2.27591 to 2.26748, saving model to /tmp/weights.hdf5

Epoch 00006: val_loss did not improve from 2.26748

Epoch 00007: val_loss did not improve from 2.26748

Epoch 00008: val_loss did not improve from 2.26748

Epoch 00009: val_loss did not improve from 2.26748

Epoch 00010: val_loss did not improve from 2.26748

Epoch 00011: val_loss did not improve from 2.26748

Epoch 00012: val_loss did not improve from 2.26748

Epoch 00013: val_loss did not improve from 2.26748

Epoch 00014: val_loss did not improve from 2.26748

Epoch 00015: val_loss did not improve from 2.26748

Epoch 00016: val_loss did not improve from 2.26748

Epoch 00017: val_loss did not improve from 2.26748

Epoch 00018: val_loss did not improve from 2.26748

Epoch 00019: val_loss did not improve from 2.26748

Epoch 00020: val_loss did not improve from 2.26748
Out[1]:
<keras.callbacks.History at 0xb2b61e630>
In [2]:
tf.keras.__version__
Out[2]:
'2.1.6-tf'
In [3]:
import keras
keras.__version__
Out[3]:
'2.2.4'
In [ ]: