I build a model in Keras for CNN. I want to save this model and reuse this trained model for transfer learning as a pre-trained model. I do not understand what is the proper way to save the model for reusing it for transfer learning. Again how to load my pre-trained model in Keras so that I can add some layers after load the previous model.
This is my model that I build
model_cnn = Sequential() # initilaizing the Sequential nature for CNN model
# Adding the embedding layer which will take in maximum of 450 words as input and provide a 32 dimensional output of those words which belong in the top_words dictionary
model_cnn.add(Embedding(vocab_size, embedding_size, input_length=max_len))
model_cnn.add(Conv1D(32, 3, padding='same', activation='relu'))
model_cnn.add(Conv1D(64, 3, padding='same', activation='relu'))
model_cnn.add(MaxPooling1D())
model_cnn.add(Flatten())
model_cnn.add(Dense(250, activation='relu'))
model_cnn.add(Dense(2, activation='softmax'))
# optimizer = keras.optimizers.Adam(lr=0.001)
model_cnn.compile(
loss='categorical_crossentropy',
optimizer=sgd,
metrics=['acc',Precision(),Recall(),]
)
history_cnn = model_cnn.fit(
X_train, y_train,
validation_data=(X_val, y_val),
batch_size = 64,
epochs=epochs,
verbose=1
)
The recommended way to save model, is saving with SavedModel format:
dir = "target_directory"
model_cnn.save(dir) # it will save a .pb file with assets and variables folders
Then you can load it:
model_cnn = tf.keras.models.load_model(dir)
Now, you can add some layers and make another model. For example:
input = tf.keras.Input(shape=(128,128,3))
x = model_cnn(input)
x = tf.keras.layers.Dense(1, activation='sigmoid')(x)
new_model = tf.keras.models.Model(inputs=input, outputs=x)
Related
I am doing am image similarity problem and want to save the image embeddings the model creates during training. Is there a way I can capture the embeddings before they are passed into the loss function?
Here is my model
model = tf.keras.Sequential([
tf.keras.layers.Conv2D(filters=128, kernel_size=2, padding='same', activation='relu', input_shape=(32,32,3)),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Conv2D(filters=64, kernel_size=2, padding='same', activation='relu'),
tf.keras.layers.MaxPooling2D(pool_size=2),
tf.keras.layers.Dropout(0.3),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(32, activation=None), # No activation on final dense layer
tf.keras.layers.Lambda(lambda x: tf.math.l2_normalize(x, axis=1)) # L2 normalize embeddings
])
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tfa.losses.TripletSemiHardLoss(),
metrics = ["accuracy"])
history = model.fit(train_dataset, epochs=3, validation_data=test_dataset)
To be clear I do not want the outputs just from the final layer shown here. I want to save the final resulting vector that is output from my model.
You can create a custom callback and at the end of training step of each batch, call your model with input batch and get the output and save it.
class SaveEmbeddingCallback(tf.keras.callbacks.Callback):
def on_train_batch_end(self, batch, logs=None):
embedding = self.model.predict(batch)
# IN THIS STAGE YOU HAVE THE OUTPUT OF THE MODEL
# YOU CAN SAVE IT OR WHATEVER YOU WANT
...
model.compile(
optimizer=tf.keras.optimizers.Adam(0.001),
loss=tfa.losses.TripletSemiHardLoss(),
metrics = ["accuracy"])
history = model.fit(train_dataset,
epochs=3,
validation_data=test_dataset,
callbacks=[SaveEmbeddingCallback()])
For more information on keras custom callbacks read this TensorFlow tutorial
I have seen some examples of transfer learning where one can use pre-trained models from keras.application (Xception, VGG16, VGG19, ResNet50 e.t.c) but what I want is to transfer the learning from the model I saved using model.save('model.h5')
This is my current model:
model = Sequential()
model.add(Embedding(max_words, embedding_dim, input_length=maxlen))
model.add(LSTM(32))
model.add(Dropout(0.6))
model.add(Dense(2, activation='sigmoid'))
model.compile(optimizer='rmsprop', loss='binary_crossentropy',metrics=['acc'])
model.fit(sequences, labels, epochs=10, batch_size=32, validation_split=0.2)
Now, Instead of saying
model_base = keras.applications.vgg16.VGG16(include_top=False, weights='imagenet')
I want to load the saved model probably with load_model('model.h5') and add it as a layer to my current model.
try this
model = Sequential()
model.add(Embedding(max_words, embedding_dim, input_length=maxlen))
model.add(LSTM(32))
model.add(Dropout(0.6))
model.add(Dense(2, activation='sigmoid'))
model.layers[0].set_weights([embedding_matrix])
model.layers[0].trainable = False
model.load_weights('model.h5')
model.compile(optimizer='rmsprop', loss='binary_crossentropy',metrics=['acc'])
model_base = model
Dont forget to remove your classifier
I trained and saved a Bidirectional LSTM model in Keras successfully with:
model = Sequential()
model.add(Bidirectional(LSTM(N_HIDDEN_NEURONS,
return_sequences=True,
activation="tanh",
input_shape=(SEGMENT_TIME_SIZE, N_FEATURES))))
model.add(Bidirectional(LSTM(N_HIDDEN_NEURONS)))
model.add(Dropout(0.5))
model.add(Dense(N_CLASSES, activation='sigmoid'))
model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train,
batch_size=BATCH_SIZE,
epochs=N_EPOCHS,
validation_data=[X_test, y_test])
model.save('model_keras/model.h5')
However, when I want to load it with:
model = load_model('model_keras/model.h5')
I get an error:
ValueError: You are trying to load a weight file containing 3 layers
into a model with 0 layers.
I also tried different methods like saving and loading model architecture and weights separately but none of them worked for me. Also, previously, when I was using normal (unidirectional) LSTMs, loading the model worked fine.
As mentioned by #mpariente and #today, the input_shape is an argument of Bidirectional, not LSTM, see Keras documentation. My solution:
# Model
model = Sequential()
model.add(Bidirectional(LSTM(N_HIDDEN_NEURONS,
return_sequences=True,
activation="tanh"),
input_shape=(SEGMENT_TIME_SIZE, N_FEATURES)))
model.add(Bidirectional(LSTM(N_HIDDEN_NEURONS)))
model.add(Dropout(0.5))
model.add(Dense(N_CLASSES, activation='sigmoid'))
model.compile('adam', 'binary_crossentropy', metrics=['accuracy'])
model.fit(X_train, y_train,
batch_size=BATCH_SIZE,
epochs=N_EPOCHS,
validation_data=[X_test, y_test])
model.save('model_keras/model.h5')
and then, to load, simply do:
model = load_model('model_keras/model.h5')
I implemented an LSTM with Keras and trained it on a corpus. Now I want to take the output of the NN and pass it as input to another NN model and test on a test set. I saved the model of the NN, but I do not know how to extract the output and feed it to the other NN. How can I do it?
This is my code:
model = Sequential()
model.add(Embedding(vocab_size, 50, input_length=seq_length))
model.add(LSTM(100, return_sequences=True))
model.add(LSTM(100))
model.add(Dense(100, activation='relu'))
model.add(Dense(vocab_size, activation='softmax'))
print(model.summary())
# compile model
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=
['accuracy'])
# fit model
model.fit(X, y, batch_size=128, epochs=500)
# save the model to file
model.save('model.h5')
There isn't any need to save a model to extract output . You can simply use the predict()function to get your output.
In your case to get the output from your model pass the test input as shown
prediction = model.predict(X_test)
where X_test is your test input and 'prediction' will contain your output which can then be printed.
For giving this output as input to another model , first create another model like you have one and then pass the prediction variable into the model.fit() function.
To use the output of one model in another model, simply load it and use it:
m0 = tf.keras.models.load_model("path_to_model_here", compile=False)
m0 = m0(some_input)
m1 = concatenate([some_input, m0])
m1 = Dense(DENSE_LAYER_NEURONS, input_shape=(INPUT_SIZE + M0_SIZE,), activation="relu")(m1)
m1 = Dense(DENSE_LAYER_NEURONS, activation="relu")(m1)
...
Can we save any of the created LSTM models themselves? I believe that “pickling” is the standard method to serialize python objects to a file. Ideally, I wanted to create a python module that contained one or more functions that either allowed me to specify an LSTM model to load or used a hard-coded pre-fit model to generate forecasts based on data passed in to initialize the model.
I tried to use it but gave me an error.
Code that I used:
# create and fit the LSTM network
batch_size = 1
model = Sequential()
model.add(LSTM(50, batch_input_shape=(batch_size, look_back, 1), stateful=True, return_sequences=True))
model.add(Dropout(0.3))
model.add(Activation('relu'))
model.add(LSTM(50, batch_input_shape=(batch_size, look_back, 1), stateful=True))
model.add(Dropout(0.3))
model.add(Activation('relu'))
model.add(Dense(1))
model.add(Activation('relu'))
model.compile(loss='mean_squared_error', optimizer='adam', metrics = ['accuracy'])
for i in range(10):
model.fit(trainX, trainY, epochs=1, batch_size=batch_size, verbose=2, shuffle=False)
model.reset_states()
with open ('sequential.pickle','wb') as f:
pickle.dump(model,f)
pickle_in = open ('sequential.pickle','rb')
model = pickle.load(pickle_in)
# make predictions
trainPredict = model.predict(trainX, batch_size=batch_size)
model.reset_states()
testPredict = model.predict(testX, batch_size=batch_size)
From the documentation:
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.
To save your model, you'd need to call model.save:
model.save('model.h5') # creates a HDF5 file 'model.h5'
Similarly, loading the model is done like this:
from keras.models import load_model
model = load_model('model.h5')