I got RecursionError while load_model with a custom_objects in keras〔RecursionError: maximum recursion depth exceeded in __instancecheck__〕
Question:
- I tried to train a model with a customized activation function, and saved a model for each epoch.
- I made a loop of 3500 iterations(each iteration should be an epoch), in each iteration the model which saved in the previous iteration is loaded (using
keras
‘s load_model()
).
- The model keeps training and saving until 90 iterations, then encounters
RecursionError
Here is the code:
#define custom activation
class Double_Tanh(Activation):
def __init__(self, activation, **kwargs):
super(Double_Tanh, self).__init__(activation, **kwargs)
self.__name__ = 'double_tanh'
def double_tanh(x):
return (K.tanh(x) * 2)
get_custom_objects().update({'double_tanh':Double_Tanh(double_tanh)})
# Model Generation
model = Sequential()
#check https://machinelearningmastery.com/use-weight-regularization-lstm-networks-time-series-forecasting/
model.add(LSTM(25, input_shape=(20,1), dropout=0.0, kernel_regularizer=l1_l2(0.00,0.00), bias_regularizer=l1_l2(0.00,0.00)))
model.add(Dense(1))
model.add(Activation(double_tanh))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mse', 'mae'])
model.summary()
epoch_num=1
max_epoch = 3500
for _ in range(max_epoch):
# train the model
dir_ = './lstm_only_models/LSTM_only/'
file_list = os.listdir(dir_)
if len(file_list) != 0 :
epoch_num = len(file_list) + 1
recent_model_name = 'epoch'+str(epoch_num-1)+'.h5'
filepath = './lstm_only_models/LSTM_only/' + recent_model_name
custom_objects = {"Double_Tanh": Double_Tanh}
with keras.utils.custom_object_scope(custom_objects):
model = load_model(filepath)
filepath = './lstm_only_models/LSTM_only/epoch'+str(epoch_num)+'.h5'
checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=False, mode='min')
callbacks_list = [checkpoint]
if len(callbacks_list) == 0:
model.fit(_train_X, _train_Y, epochs=1, batch_size=500, shuffle=True)
else:
model.fit(_train_X, _train_Y, epochs=1, batch_size=500, shuffle=True, callbacks=callbacks_list)
# test the model
score_train = model.evaluate(_train_X, _train_Y)
score_dev = model.evaluate(_dev_X, _dev_Y)
score_test1 = model.evaluate(_test1_X, _test1_Y)
score_test2 = model.evaluate(_test2_X, _test2_Y)
Error message:
Traceback (most recent call last):
File "LSTM_only.py", line 110, in <module>
model = load_model(filepath, custom_objects=custom_objects)
File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "LSTM_only.py", line 65, in __init__
super(Double_Tanh, self).__init__(activation, **kwargs)
File "LSTM_only.py", line 65, in __init__
super(Double_Tanh, self).__init__(activation, **kwargs)
File "LSTM_only.py", line 65, in __init__
super(Double_Tanh, self).__init__(activation, **kwargs)
[Previous line repeated 86 more times]
RecursionError: maximum recursion depth exceeded in __instancecheck__
I am not sure why does this happen, so my questions are:
- How should I adjust my code?
- What’s the reason of this error?
Answers:
According to the documents: https://keras.io/guides/serialization_and_saving/#savedmodel-format
- Using
model.save("my_model")
enables Keras to restore both built-in layers as well as custom objects.
So don’t need to create the class and register custom_objects.
All we need to do is change the save-format.
Here is the correct codes:
def double_tanh(x):
return (K.tanh(x) * 2)
# Model Generation
model = Sequential()
#check https://machinelearningmastery.com/use-weight-regularization-lstm-networks-time-series-forecasting/
model.add(LSTM(25, input_shape=(20,1), dropout=0.0, kernel_regularizer=l1_l2(0.00,0.00), bias_regularizer=l1_l2(0.00,0.00)))
model.add(Dense(1, activation=double_tanh))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mse', 'mae'])
epoch_num=1
max_epoch = 3500
for _ in range(max_epoch):
# train the model
dir_ = './lstm_only_models/LSTM_only/'
file_list = os.listdir(dir_)
if len(file_list) != 0 :
epoch_num = len(file_list) + 1
recent_model_name = 'epoch'+str(epoch_num-1)
filepath = './lstm_only_models/LSTM_only/' + recent_model_name
model = load_model(filepath)
filepath = './lstm_only_models/LSTM_only/epoch'+str(epoch_num)
model.fit(_train_X, _train_Y, epochs=1, batch_size=500, shuffle=True)
model.save(filepath)
# test the model
score_train = model.evaluate(_train_X, _train_Y)
score_dev = model.evaluate(_dev_X, _dev_Y)
score_test1 = model.evaluate(_test1_X, _test1_Y)
score_test2 = model.evaluate(_test2_X, _test2_Y)
- I tried to train a model with a customized activation function, and saved a model for each epoch.
- I made a loop of 3500 iterations(each iteration should be an epoch), in each iteration the model which saved in the previous iteration is loaded (using
keras
‘sload_model()
). - The model keeps training and saving until 90 iterations, then encounters
RecursionError
Here is the code:
#define custom activation
class Double_Tanh(Activation):
def __init__(self, activation, **kwargs):
super(Double_Tanh, self).__init__(activation, **kwargs)
self.__name__ = 'double_tanh'
def double_tanh(x):
return (K.tanh(x) * 2)
get_custom_objects().update({'double_tanh':Double_Tanh(double_tanh)})
# Model Generation
model = Sequential()
#check https://machinelearningmastery.com/use-weight-regularization-lstm-networks-time-series-forecasting/
model.add(LSTM(25, input_shape=(20,1), dropout=0.0, kernel_regularizer=l1_l2(0.00,0.00), bias_regularizer=l1_l2(0.00,0.00)))
model.add(Dense(1))
model.add(Activation(double_tanh))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mse', 'mae'])
model.summary()
epoch_num=1
max_epoch = 3500
for _ in range(max_epoch):
# train the model
dir_ = './lstm_only_models/LSTM_only/'
file_list = os.listdir(dir_)
if len(file_list) != 0 :
epoch_num = len(file_list) + 1
recent_model_name = 'epoch'+str(epoch_num-1)+'.h5'
filepath = './lstm_only_models/LSTM_only/' + recent_model_name
custom_objects = {"Double_Tanh": Double_Tanh}
with keras.utils.custom_object_scope(custom_objects):
model = load_model(filepath)
filepath = './lstm_only_models/LSTM_only/epoch'+str(epoch_num)+'.h5'
checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=False, mode='min')
callbacks_list = [checkpoint]
if len(callbacks_list) == 0:
model.fit(_train_X, _train_Y, epochs=1, batch_size=500, shuffle=True)
else:
model.fit(_train_X, _train_Y, epochs=1, batch_size=500, shuffle=True, callbacks=callbacks_list)
# test the model
score_train = model.evaluate(_train_X, _train_Y)
score_dev = model.evaluate(_dev_X, _dev_Y)
score_test1 = model.evaluate(_test1_X, _test1_Y)
score_test2 = model.evaluate(_test2_X, _test2_Y)
Error message:
Traceback (most recent call last):
File "LSTM_only.py", line 110, in <module>
model = load_model(filepath, custom_objects=custom_objects)
File "/usr/local/lib/python3.8/dist-packages/keras/utils/traceback_utils.py", line 67, in error_handler
raise e.with_traceback(filtered_tb) from None
File "LSTM_only.py", line 65, in __init__
super(Double_Tanh, self).__init__(activation, **kwargs)
File "LSTM_only.py", line 65, in __init__
super(Double_Tanh, self).__init__(activation, **kwargs)
File "LSTM_only.py", line 65, in __init__
super(Double_Tanh, self).__init__(activation, **kwargs)
[Previous line repeated 86 more times]
RecursionError: maximum recursion depth exceeded in __instancecheck__
I am not sure why does this happen, so my questions are:
- How should I adjust my code?
- What’s the reason of this error?
According to the documents: https://keras.io/guides/serialization_and_saving/#savedmodel-format
- Using
model.save("my_model")
enables Keras to restore both built-in layers as well as custom objects.
So don’t need to create the class and register custom_objects.
All we need to do is change the save-format.
Here is the correct codes:
def double_tanh(x):
return (K.tanh(x) * 2)
# Model Generation
model = Sequential()
#check https://machinelearningmastery.com/use-weight-regularization-lstm-networks-time-series-forecasting/
model.add(LSTM(25, input_shape=(20,1), dropout=0.0, kernel_regularizer=l1_l2(0.00,0.00), bias_regularizer=l1_l2(0.00,0.00)))
model.add(Dense(1, activation=double_tanh))
model.compile(loss='mean_squared_error', optimizer='adam', metrics=['mse', 'mae'])
epoch_num=1
max_epoch = 3500
for _ in range(max_epoch):
# train the model
dir_ = './lstm_only_models/LSTM_only/'
file_list = os.listdir(dir_)
if len(file_list) != 0 :
epoch_num = len(file_list) + 1
recent_model_name = 'epoch'+str(epoch_num-1)
filepath = './lstm_only_models/LSTM_only/' + recent_model_name
model = load_model(filepath)
filepath = './lstm_only_models/LSTM_only/epoch'+str(epoch_num)
model.fit(_train_X, _train_Y, epochs=1, batch_size=500, shuffle=True)
model.save(filepath)
# test the model
score_train = model.evaluate(_train_X, _train_Y)
score_dev = model.evaluate(_dev_X, _dev_Y)
score_test1 = model.evaluate(_test1_X, _test1_Y)
score_test2 = model.evaluate(_test2_X, _test2_Y)