Jak wczytać model z pliku HDF5 w Keras?

94

Jak wczytać model z pliku HDF5 w Keras?

Co próbowałem:

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

Powyższy kod pomyślnie zapisuje najlepszy model do pliku o nazwie weights.hdf5. Chcę wtedy załadować ten model. Poniższy kod pokazuje, jak próbowałem to zrobić:

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

Oto błąd, który otrzymuję:

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
źródło

Odpowiedzi:

84

load_weightsustala tylko wagi Twojej sieci. Nadal musisz zdefiniować jego architekturę przed wywołaniem 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
źródło
37
Jeśli chcesz załadować PEŁNY model, a nie tylko wagi: from keras.models import load_modeltomodel = load_model('model.h5')
cgnorthcutt
1
@mikael, czy możesz dać mi wskazówkę dotyczącą tego wpisu SO? stackoverflow.com/questions/55050339/…
HenryHub
211

Jeśli zapisałeś kompletny model, a nie tylko ciężary, w pliku HDF5, jest to tak proste, jak

from keras.models import load_model
model = load_model('model.h5')
Martin Thoma
źródło
czy model obejmuje również rzeczywiste dane szkoleniowe podczas obliczania zużycia pamięci przez model? Jak możesz załadować model, który jest większy niż dostępna pamięć?
user798719
Model NIE zawiera (jawnie) danych uczących. Nie możesz załadować modelu, który jest większy niż twoja dostępna pamięć (no dobra, jest to możliwe, ale będzie to dość trudne i będziesz musiał to zrobić samodzielnie ... ale jeśli twój model jest zbyt duży, aby cię wczytać) powinien (a) uzyskać więcej pamięci lub (b) wytrenować mniejszy model)
Martin Thoma
@MartinThoma Korzystam z zaproponowanej przez Ciebie metody. Próbuję wyciągnąć jedną warstwę z załadowanego modelu i próbuję zobaczyć jego wagi przez: encoder = autoencoder.layers[0] encoder.get_weights() Ale otrzymuję: FailedPreconditionError: Attempting to use uninitialized value lstm_1/kernel
shubhamsingh
1
Doceniam komplement :-) Aby zwrócić uwagę na zaakceptowaną odpowiedź: Mogę sobie wyobrazić, że przechowywanie samych ciężarków jest bardziej wytrzymałe. Jeśli keras się zmieni, wagi mogą być nadal importowane, podczas gdy całość nie może być importowana. Z drugiej strony można zainstalować starą wersję, zrzucić wagi i zrobić to samo, co wcześniej.
Martin Thoma
@ pr338 Proszę rozważyć zaktualizowanie zaakceptowanej odpowiedzi.
Kris,
28

Zobacz poniższy przykładowy kod, aby dowiedzieć się, jak zbudować podstawowy model sieci neuronowej Keras, zapisać model (JSON) i wagi (HDF5) i załadować je:

# 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))
Odziedziczony Geek
źródło
1
To zadziałało dla mnie podczas ładowania modelu z json i h5. Upewnij się, że jeśli używasz przykładu @ InheritedGeek, pamiętasz model.compile (). Jest to wymagane przed wywołaniem model.evaluate. Świetny przykład, dzięki!
CodeGuyRoss
6

Zgodnie z oficjalną dokumentacją https://keras.io/getting-started/faq/#how-can-i-install-hdf5-or-h5py-to-save-my-models-in-keras

możesz to zrobić :

pierwszy test, jeśli masz zainstalowany h5py, uruchamiając

import h5py

jeśli nie masz błędów podczas importowania h5py, możesz zapisać:

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

Jeśli musisz zainstalować h5py http://docs.h5py.org/en/latest/build.html

Richardd
źródło
3
Wydaje się, że nie działa to w Keras 2.2.4 z h5py 2.9.0. Otrzymuję następujący błąd: Anaconda3 \ envs \ syntetyczne \ lib \ site-packages \ keras \ utils \ io_utils.py ", wiersz 302, w getitem podnieś wartość ValueError ('Nie można utworzyć grupy w trybie tylko do odczytu.')
csteel
0

Zrobiłem w ten sposób

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
źródło
nie ma modelu.save (). Jest tylko model.model.save (). Wczytanie tego modelu z powrotem i użycie go w oryginalnie utworzony sposób prowadzi do błędów. Załadowany obiekt to <keras.engine.sequential.Sequential Podczas gdy ten, który tworzymy, to keras.wrappers.scikit_learn.KerasRegressor. Jak mogę to zmienić?
piasek
Rozwiązałem mój problem na poniższej stronie [ github.com/keras-team/keras-contrib/blob/master/keras_contrib/…
TRINADH NAGUBADI
Mam 404 na tym łączu
piasek
@TRINADH NAGUBADI, Zaktualizuj łącze, strona już nie istnieje.
Catalina Chircu