Rizwan
Rizwan

Reputation: 1270

"AttributeError: 'str' object has no attribute 'decode' " while Loading a Keras Saved Model

After Training, I saved Both Keras whole Model and Only Weights using

model.save_weights(MODEL_WEIGHTS) and model.save(MODEL_NAME)

Models and Weights were saved successfully and there was no error. I can successfully load the weights simply using model.load_weights and they are good to go, but when i try to load the save model via load_model, i am getting an error.

File "C:/Users/Rizwan/model_testing/model_performance.py", line 46, in <module>
Model2 = load_model('nasnet_RS2.h5',custom_objects={'euc_dist_keras': euc_dist_keras})
File "C:\Users\Rizwan\AppData\Roaming\Python\Python36\site-packages\keras\engine\saving.py", line 419, in load_model
model = _deserialize_model(f, custom_objects, compile)
File "C:\Users\Rizwan\AppData\Roaming\Python\Python36\site-packages\keras\engine\saving.py", line 321, in _deserialize_model
optimizer_weights_group['weight_names']]
File "C:\Users\Rizwan\AppData\Roaming\Python\Python36\site-packages\keras\engine\saving.py", line 320, in <listcomp>
n.decode('utf8') for n in
AttributeError: 'str' object has no attribute 'decode'

I never received this error and i used to load any models successfully. I am using Keras 2.2.4 with tensorflow backend. Python 3.6. My Code for training is :

from keras_preprocessing.image import ImageDataGenerator
from keras import backend as K
from keras.models import load_model
from keras.callbacks import ReduceLROnPlateau, TensorBoard, 
ModelCheckpoint,EarlyStopping
import pandas as pd

MODEL_NAME = "nasnet_RS2.h5"
MODEL_WEIGHTS = "nasnet_RS2_weights.h5"
def euc_dist_keras(y_true, y_pred):
return K.sqrt(K.sum(K.square(y_true - y_pred), axis=-1, keepdims=True))
def main():

# Here, we initialize the "NASNetMobile" model type and customize the final 
#feature regressor layer.
# NASNet is a neural network architecture developed by Google.
# This architecture is specialized for transfer learning, and was discovered via Neural Architecture Search.
# NASNetMobile is a smaller version of NASNet.
model = NASNetMobile()
model = Model(model.input, Dense(1, activation='linear', kernel_initializer='normal')(model.layers[-2].output))

#    model = load_model('current_best.hdf5', custom_objects={'euc_dist_keras': euc_dist_keras})

# This model will use the "Adam" optimizer.
model.compile("adam", euc_dist_keras)
lr_callback = ReduceLROnPlateau(monitor='val_loss', factor=0.2, patience=5, min_lr=0.003)
# This callback will log model stats to Tensorboard.
tb_callback = TensorBoard()
# This callback will checkpoint the best model at every epoch.
mc_callback = ModelCheckpoint(filepath='current_best_mem3.h5', verbose=1, save_best_only=True)
es_callback=EarlyStopping(monitor='val_loss', min_delta=0, patience=4, verbose=0, mode='auto', baseline=None, restore_best_weights=True)

# This is the train DataSequence.
# These are the callbacks.
#callbacks = [lr_callback, tb_callback,mc_callback]
callbacks = [lr_callback, tb_callback,es_callback]

train_pd = pd.read_csv("./train3.txt", delimiter=" ", names=["id", "label"], index_col=None)
test_pd = pd.read_csv("./val3.txt", delimiter=" ", names=["id", "label"], index_col=None)

 #    train_pd = pd.read_csv("./train2.txt",delimiter=" ",header=None,index_col=None)
 #    test_pd = pd.read_csv("./val2.txt",delimiter=" ",header=None,index_col=None)
#model.summary()
batch_size=32
datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = datagen.flow_from_dataframe(dataframe=train_pd, 
directory="./images", x_col="id", y_col="label",
                                              has_ext=True, 
class_mode="other", target_size=(224, 224),
                                              batch_size=batch_size)
valid_generator = datagen.flow_from_dataframe(dataframe=test_pd, directory="./images", x_col="id", y_col="label",
                                              has_ext=True, class_mode="other", target_size=(224, 224),
                                              batch_size=batch_size)

STEP_SIZE_TRAIN = train_generator.n // train_generator.batch_size
STEP_SIZE_VALID = valid_generator.n // valid_generator.batch_size
model.fit_generator(generator=train_generator,
                    steps_per_epoch=STEP_SIZE_TRAIN,
                    validation_data=valid_generator,
                    validation_steps=STEP_SIZE_VALID,
                    callbacks=callbacks,
                    epochs=20)

# we save the model.
model.save_weights(MODEL_WEIGHTS)
model.save(MODEL_NAME)
if __name__ == '__main__':
   # freeze_support() here if program needs to be frozen
    main()

Upvotes: 104

Views: 119659

Answers (10)

Akhilesh
Akhilesh

Reputation: 524

Downgrading python, tensorflow, keras and h5py resolved the issue.

python -> 3.6.2

pip install tensorflow==1.3.0
pip install keras==2.1.2
pip install 'h5py==2.10.0' --force-reinstall

Upvotes: 0

Codemaker2015
Codemaker2015

Reputation: 1

Downgrade h5py package with the following command to resolve the issue,

pip install h5py==2.10.0 --force-reinstall

Upvotes: 13

pcampana
pcampana

Reputation: 2683

The solution than works for me was:

pip3 uninstall keras
pip3 uninstall tensorflow
pip3 install --upgrade pip3
pip3 install tensorflow
pip3 install keras

Upvotes: 2

Azaria Gebremichael
Azaria Gebremichael

Reputation: 762

I still kept having this error after having tensorflow==2.4.1, h5py==2.1.0, and python 3.8 in my environment. what fixed it was downgrading the python version to 3.6.9

Upvotes: 1

I downgraded my h5py package with the following command,

pip install 'h5py==2.10.0' --force-reinstall

Restarted my ipython kernel and it worked.

Upvotes: 127

saved using TF format file and not h5py: save_format='tf'. In my case:

model.save_weights("NMT_model_weight.tf",save_format='tf')

Upvotes: 6

Ibra
Ibra

Reputation: 499

For me it was the version of h5py that was superior to my previous build.
Fixed it by setting to 2.10.0.

Upvotes: 23

Michela Ruperti
Michela Ruperti

Reputation: 75

I had the same problem, solved putting compile=False in load_model:

model_ = load_model('path to your model.h5',custom_objects={'Scale': Scale()}, compile=False)
sgd = SGD(lr=1e-3, decay=1e-6, momentum=0.9, nesterov=True)
model_.compile(loss='categorical_crossentropy',optimizer='sgd',metrics=['accuracy'])

Upvotes: 5

arno_v
arno_v

Reputation: 20257

For me the solution was downgrading the h5py package (in my case to 2.10.0), apparently putting back only Keras and Tensorflow to the correct versions was not enough.

Upvotes: 191

Eric Fournie
Eric Fournie

Reputation: 1372

This is probably due to a model saved from a different version of keras. I got the same problem when loading a model generated by tensorflow.keras (which is similar to keras 2.1.6 for tf 1.12 I think) from keras 2.2.6.

You can load the weights with model.load_weights and resave the complete model from the keras version you want to use.

Upvotes: 3

Related Questions