¿Cómo cargar un modelo desde un archivo HDF5 en Keras?

94

¿Cómo cargar un modelo desde un archivo HDF5 en Keras?

Lo que probé:

model = Sequential()

model.add(Dense(64, input_dim=14, init='uniform'))
model.add(LeakyReLU(alpha=0.3))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Dropout(0.5))

model.add(Dense(64, init='uniform'))
model.add(LeakyReLU(alpha=0.3))
model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
model.add(Dropout(0.5))

model.add(Dense(2, init='uniform'))
model.add(Activation('softmax'))


sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
model.compile(loss='binary_crossentropy', optimizer=sgd)

checkpointer = ModelCheckpoint(filepath="/weights.hdf5", verbose=1, save_best_only=True)
model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose = 2, callbacks=[checkpointer])

El código anterior guarda con éxito el mejor modelo en un archivo llamado weights.hdf5. Lo que quiero hacer es cargar ese modelo. El siguiente código muestra cómo intenté hacerlo:

model2 = Sequential()
model2.load_weights("/Users/Desktop/SquareSpace/weights.hdf5")

Este es el error que obtengo:

IndexError                                Traceback (most recent call last)
<ipython-input-101-ec968f9e95c5> in <module>()
      1 model2 = Sequential()
----> 2 model2.load_weights("/Users/Desktop/SquareSpace/weights.hdf5")

/Applications/anaconda/lib/python2.7/site-packages/keras/models.pyc in load_weights(self, filepath)
    582             g = f['layer_{}'.format(k)]
    583             weights = [g['param_{}'.format(p)] for p in range(g.attrs['nb_params'])]
--> 584             self.layers[k].set_weights(weights)
    585         f.close()
    586 

IndexError: list index out of range
pr338
fuente

Respuestas:

84

load_weightssolo establece los pesos de su red. Aún necesita definir su arquitectura antes de llamar load_weights:

def create_model():
   model = Sequential()
   model.add(Dense(64, input_dim=14, init='uniform'))
   model.add(LeakyReLU(alpha=0.3))
   model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
   model.add(Dropout(0.5)) 
   model.add(Dense(64, init='uniform'))
   model.add(LeakyReLU(alpha=0.3))
   model.add(BatchNormalization(epsilon=1e-06, mode=0, momentum=0.9, weights=None))
   model.add(Dropout(0.5))
   model.add(Dense(2, init='uniform'))
   model.add(Activation('softmax'))
   return model

def train():
   model = create_model()
   sgd = SGD(lr=0.1, decay=1e-6, momentum=0.9, nesterov=True)
   model.compile(loss='binary_crossentropy', optimizer=sgd)

   checkpointer = ModelCheckpoint(filepath="/tmp/weights.hdf5", verbose=1, save_best_only=True)
   model.fit(X_train, y_train, nb_epoch=20, batch_size=16, show_accuracy=True, validation_split=0.2, verbose=2, callbacks=[checkpointer])

def load_trained_model(weights_path):
   model = create_model()
   model.load_weights(weights_path)
Mikael Rousson
fuente
37
Si desea cargar el modelo COMPLETO, no solo los pesos: from keras.models import load_modelentoncesmodel = load_model('model.h5')
cgnorthcutt
1
@mikael, ¿puedes darme un consejo con esta publicación SO? stackoverflow.com/questions/55050339/…
HenryHub
207

Si almacenó el modelo completo, no solo los pesos, en el archivo HDF5, entonces es tan simple como

from keras.models import load_model
model = load_model('model.h5')
Martín Thoma
fuente
¿Un modelo incluye los datos de entrenamiento reales también al calcular la huella de memoria del modelo? ¿Cómo podría cargar un modelo que es más grande que su memoria disponible?
user798719
Un modelo NO incluye (explícitamente) los datos de entrenamiento. No puede cargar un modelo que sea más grande que su memoria disponible (bueno, está bien, es posible, pero esto será bastante difícil y tendrá que revisarlo usted mismo ... pero si su modelo es demasiado grande para cargarlo debería (a) obtener más memoria o (b) entrenar un modelo más pequeño)
Martin Thoma
@MartinThoma Estoy usando el método sugerido por ti. Estoy tratando de sacar una capa del modelo cargado y tratando de ver sus pesos por: encoder = autoencoder.layers[0] encoder.get_weights() Pero FailedPreconditionError: Attempting to use uninitialized value lstm_1/kernel
obtengo
1
Agradezco el cumplido :-) Para aclarar la respuesta aceptada: podría imaginar que almacenar solo los pesos es más robusto. Si keras cambia, los pesos aún podrían importarse mientras que el elemento completo no se puede importar. Por otro lado, se puede instalar una versión antigua, volcar los pesos y hacer lo mismo que antes.
Martin Thoma
@ pr338 Considere actualizar su respuesta aceptada.
Kris
28

Vea el siguiente código de muestra sobre cómo construir un modelo básico de red neuronal de Keras, guardar el modelo (JSON) y los pesos (HDF5) y cargarlos:

# create model
model = Sequential()
model.add(Dense(X.shape[1], input_dim=X.shape[1], activation='relu')) #Input Layer
model.add(Dense(X.shape[1], activation='relu')) #Hidden Layer
model.add(Dense(output_dim, activation='softmax')) #Output Layer

# Compile & Fit model
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
model.fit(X,Y,nb_epoch=5,batch_size=100,verbose=1)    

# serialize model to JSON
model_json = model.to_json()
with open("Data/model.json", "w") as json_file:
    json_file.write(simplejson.dumps(simplejson.loads(model_json), indent=4))

# serialize weights to HDF5
model.save_weights("Data/model.h5")
print("Saved model to disk")

# load json and create model
json_file = open('Data/model.json', 'r')
loaded_model_json = json_file.read()
json_file.close()
loaded_model = model_from_json(loaded_model_json)

# load weights into new model
loaded_model.load_weights("Data/model.h5")
print("Loaded model from disk")

# evaluate loaded model on test data 
# Define X_test & Y_test data first
loaded_model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])
score = loaded_model.evaluate(X_test, Y_test, verbose=0)
print ("%s: %.2f%%" % (loaded_model.metrics_names[1], score[1]*100))
Geek heredado
fuente
1
Esto funcionó para mí al cargar un modelo desde json y h5. Asegúrese de que si usa el ejemplo de @ InheritedGeek, recuerda el model.compile (). Es necesario antes de poder llamar a model.evaluate. ¡Gran ejemplo, gracias!
CodeGuyRoss
6

Según la documentación oficial https://keras.io/getting-started/faq/#how-can-i-install-hdf5-or-h5py-to-save-my-models-in-keras

tu puedes hacer :

Primero pruebe si tiene h5py instalado ejecutando el

import h5py

Si no tiene errores al importar h5py, puede guardar:

from keras.models import load_model

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')

Si necesita instalar h5py http://docs.h5py.org/en/latest/build.html

Richardd
fuente
3
Esto no parece funcionar en Keras 2.2.4 con h5py 2.9.0. Recibo el siguiente error: Anaconda3 \ envs \ Synthetic \ lib \ site-packages \ keras \ utils \ io_utils.py ", línea 302, en getitem raise ValueError ('No se puede crear un grupo en modo de solo lectura')
csteel
0

Lo hice de esta manera

from keras.models import Sequential
from keras_contrib.losses import import crf_loss
from keras_contrib.metrics import crf_viterbi_accuracy

# To save model
model.save('my_model_01.hdf5')

# To load the model
custom_objects={'CRF': CRF,'crf_loss': crf_loss,'crf_viterbi_accuracy':crf_viterbi_accuracy}

# To load a persisted model that uses the CRF layer 
model1 = load_model("/home/abc/my_model_01.hdf5", custom_objects = custom_objects)
TRINADH NAGUBADI
fuente
no hay model.save (). Solo existe model.model.save (). Y volver a cargar este modelo y usarlo en la forma original del modelo creado conduce a errores. El objeto cargado es <keras.engine.sequential.Sequential, mientras que el que creamos es keras.wrappers.scikit_learn.KerasRegressor. ¿Cómo puedo cambiarlo?
arena
Resolví
TRINADH NAGUBADI
Tengo un 404 en ese enlace
arena
@TRINADH NAGUBADI, actualice el enlace por favor, la página ya no existe.
Catalina Chircu