使用load_model时,keras内核初始化程序被错误地调用 [英] keras kernel initializers are called incorrectly when using load_model
问题描述
Keras 2.2.4版, tensorflow 1.13.1版, 我正在使用colab笔记本
Keras version 2.2.4, tensorflow version 1.13.1, I'm using colab notebooks
我试图制作一个自定义的初始化程序,并使用model.save()保存模型,但是当我再次加载模型时,出现以下错误:
I'm trying to make a custom initializer and save the model using model.save() but when I load the model again I get the following error:
TypeError:myInit()缺少1个必需的位置参数:"input_shape"
TypeError: myInit() missing 1 required positional argument: 'input_shape'
我有以下代码:
import numpy as np
import tensorflow as tf
import keras
from google.colab import drive
from keras.models import Sequential, load_model
from keras.layers import Dense, Dropout, Flatten, Lambda, Reshape, Activation
from keras.layers.convolutional import Conv2D, MaxPooling2D
from keras import backend as K
K.set_image_data_format('channels_first')
K.backend()
# the output should be 'tensorflow'
'tensorflow'
'tensorflow'
def myInit( input_shape, dtype=None):
weights = np.full( input_shape, 2019 )
return K.variable( weights, dtype=dtype )
此初始值设定项被赋予input_shape并返回keras张量,如文档中所示: https://keras.io/初始化程序/
This initializer is given an input_shape and returns a keras tensor like in the docs: https://keras.io/initializers/
model = Sequential()
model.add(
Dense( 40, input_shape=(784,) )
)
model.add(
Dense( 30, kernel_initializer=myInit )
)
model.add(
Dense( 5 )
)
model.build()
权重正确初始化,因为当我调用model.layers[1].get_weights()
时,得到的数组充满了2019.
我使用model.save保存模型:
The weights are initialized correctly because when I call model.layers[1].get_weights()
I get an array full of 2019.
I save the model using model.save:
model.save(somepath)
然后在另一个笔记本中致电
In a different notebook I then call
model = load_model(somepath,
custom_objects={
'tf' : tf,
'myInit' : myInit
}
)
在此笔记本myInit
中,还定义了所有导入.
当我呼叫load_model
时,出现以下错误:
In this notebook myInit
and all the imports are defined as well.
When I call load_model
I get the following error:
TypeError:myInit()缺少1个必需的位置参数:"input_shape"
TypeError: myInit() missing 1 required positional argument: 'input_shape'
因此,似乎在加载模型时,input_shape没有传递给myInit.有人知道吗?
So it seems when the model is loaded, the input_shape is not passed to myInit. Does anyone have any idea?
完整跟踪:
TypeError Traceback (most recent call last)
<ipython-input-25-544d137de03f> in <module>()
2 custom_objects={
3 'tf' : tf,
----> 4 'myInit' : myInit
5 }
6 )
/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py in load_model(filepath, custom_objects, compile)
417 f = h5dict(filepath, 'r')
418 try:
--> 419 model = _deserialize_model(f, custom_objects, compile)
420 finally:
421 if opened_new_file:
/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py in _deserialize_model(f, custom_objects, compile)
223 raise ValueError('No model found in config.')
224 model_config = json.loads(model_config.decode('utf-8'))
--> 225 model = model_from_config(model_config, custom_objects=custom_objects)
226 model_weights_group = f['model_weights']
227
/usr/local/lib/python3.6/dist-packages/keras/engine/saving.py in model_from_config(config, custom_objects)
456 '`Sequential.from_config(config)`?')
457 from ..layers import deserialize
--> 458 return deserialize(config, custom_objects=custom_objects)
459
460
/usr/local/lib/python3.6/dist-packages/keras/layers/__init__.py in deserialize(config, custom_objects)
53 module_objects=globs,
54 custom_objects=custom_objects,
---> 55 printable_module_name='layer')
/usr/local/lib/python3.6/dist-packages/keras/utils/generic_utils.py in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
143 config['config'],
144 custom_objects=dict(list(_GLOBAL_CUSTOM_OBJECTS.items()) +
--> 145 list(custom_objects.items())))
146 with CustomObjectScope(custom_objects):
147 return cls.from_config(config['config'])
/usr/local/lib/python3.6/dist-packages/keras/engine/sequential.py in from_config(cls, config, custom_objects)
298 for conf in layer_configs:
299 layer = layer_module.deserialize(conf,
--> 300 custom_objects=custom_objects)
301 model.add(layer)
302 if not model.inputs and build_input_shape:
/usr/local/lib/python3.6/dist-packages/keras/layers/__init__.py in deserialize(config, custom_objects)
53 module_objects=globs,
54 custom_objects=custom_objects,
---> 55 printable_module_name='layer')
/usr/local/lib/python3.6/dist-packages/keras/utils/generic_utils.py in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
145 list(custom_objects.items())))
146 with CustomObjectScope(custom_objects):
--> 147 return cls.from_config(config['config'])
148 else:
149 # Then `cls` may be a function returning a class.
/usr/local/lib/python3.6/dist-packages/keras/engine/base_layer.py in from_config(cls, config)
1107 A layer instance.
1108 """
-> 1109 return cls(**config)
1110
1111 def count_params(self):
/usr/local/lib/python3.6/dist-packages/keras/legacy/interfaces.py in wrapper(*args, **kwargs)
89 warnings.warn('Update your `' + object_name + '` call to the ' +
90 'Keras 2 API: ' + signature, stacklevel=2)
---> 91 return func(*args, **kwargs)
92 wrapper._original_function = func
93 return wrapper
/usr/local/lib/python3.6/dist-packages/keras/layers/core.py in __init__(self, units, activation, use_bias, kernel_initializer, bias_initializer, kernel_regularizer, bias_regularizer, activity_regularizer, kernel_constraint, bias_constraint, **kwargs)
846 self.activation = activations.get(activation)
847 self.use_bias = use_bias
--> 848 self.kernel_initializer = initializers.get(kernel_initializer)
849 self.bias_initializer = initializers.get(bias_initializer)
850 self.kernel_regularizer = regularizers.get(kernel_regularizer)
/usr/local/lib/python3.6/dist-packages/keras/initializers.py in get(identifier)
509 elif isinstance(identifier, six.string_types):
510 config = {'class_name': str(identifier), 'config': {}}
--> 511 return deserialize(config)
512 elif callable(identifier):
513 return identifier
/usr/local/lib/python3.6/dist-packages/keras/initializers.py in deserialize(config, custom_objects)
501 module_objects=globals(),
502 custom_objects=custom_objects,
--> 503 printable_module_name='initializer')
504
505
/usr/local/lib/python3.6/dist-packages/keras/utils/generic_utils.py in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
152 custom_objects = custom_objects or {}
153 with CustomObjectScope(custom_objects):
--> 154 return cls(**config['config'])
155 elif isinstance(identifier, six.string_types):
156 function_name = identifier
TypeError: myInit() missing 1 required positional argument: 'input_shape'
请注意,我也将此内容发布在> https://github.com/keras-team /keras/issues/12452 ,但我认为这是个更好的选择.
Note I also posted this on https://github.com/keras-team/keras/issues/12452 but I figured this would be a better place for this.
推荐答案
查看源代码后,我得到了以下工作代码,这应该是定义初始化程序的正确方法(尤其是在使用load_model加载模型时):
After viewing the source code I got the following working code, which should be the proper way to define an initializer (especially when loading a model with load_model):
import numpy as np
import tensorflow as tf
import keras
from google.colab import drive
from keras.models import Sequential, load_model
from keras.layers import Dense
from keras import backend as K
from keras.initializers import Initializer
K.backend()
# the output should be 'tensorflow'
class myInit( Initializer ):
def __init__(self, myParameter):
self.myParameter = myParameter
def __call__(self, shape, dtype=None):
# array filled entirely with 'myParameter'
weights = np.full( shape, self.myParameter )
return K.variable( weights, dtype=dtype )
def get_config(self):
return {
'myParameter' : self.myParameter
}
建立模型:
model = Sequential()
model.add(
Dense( 2, input_shape=(784,) )
)
model.add(
Dense( 3, kernel_initializer=myInit( 2019 ) )
)
model.add(
Dense( 5 )
)
model.compile(optimizer='rmsprop',
loss='binary_crossentropy',
metrics=['accuracy'])
保存模型:
model.save( somepath )
现在,我们可以将模型加载到其他笔记本中.从其他笔记本导入的内容也应在此处导入,并且myInit
也应在此笔记本中定义.
Now we can load the model in a different notebook. The imports from the other notebook should be imported here as well and myInit
should also be defined in this notebook.
model = load_model( somepath,
custom_objects={
'tf' : tf,
'myInit' : myInit
}
)
这篇关于使用load_model时,keras内核初始化程序被错误地调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!