- 1.软件环境
- 2.问题描述
- 3.解决方法
- 4.结果预览
2.问题描述Windows10 教育版64位
Python 3.6.3
Tensorflow-GPU 2.3.0
Keras 2.4.3
CUDA 10.1
最近需要用到自定义的focal_loss来处理样本不平衡的问题:
def focal_loss(y_true, y_pred):
gamma = 2.0
alpha = 0.25
pt_1 = tf.where(tf.equal(y_true, 1), y_pred, tf.ones_like(y_pred))
pt_0 = tf.where(tf.equal(y_true, 0), y_pred, tf.zeros_like(y_pred))
return -K.sum(alpha * K.pow(1. - pt_1, gamma) * K.log(pt_1)) - K.sum(
(1 - alpha) * K.pow(pt_0, gamma) * K.log(1. - pt_0))
训练的时候没有问题,但当使用load_model加载训练好的模型进行预测时:
model = load_model(model_path)
出现报错:ValueError: Unknown loss function: focal_loss,即:
Traceback (most recent call last): File "", line 1, inFile "C:Program FilesJetBrainsPyCharm 2020.1pluginspythonhelperspydev_pydev_bundlepydev_umd.py", line 197, in runfile pydev_imports.execfile(filename, global_vars, local_vars) # execute the script File "C:Program FilesJetBrainsPyCharm 2020.1pluginspythonhelperspydev_pydev_imps_pydev_execfile.py", line 18, in execfile exec(compile(contents+"n", file, 'exec'), glob, loc) File "E:/Code/Python/tensorflow2.5.0/Classification model evaluation/model_evaluation.py", line 70, in model = load_model(model_path) File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerassavingsave.py", line 182, in load_model return hdf5_format.load_model_from_hdf5(filepath, custom_objects, compile) File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerassavinghdf5_format.py", line 194, in load_model_from_hdf5 training_config, custom_objects)) File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerassavingsaving_utils.py", line 217, in compile_args_from_training_config loss = _deserialize_nested_config(losses.deserialize, loss_config) File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerassavingsaving_utils.py", line 265, in _deserialize_nested_config return [_deserialize_nested_config(deserialize_fn, obj) for obj in config] File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerassavingsaving_utils.py", line 265, in return [_deserialize_nested_config(deserialize_fn, obj) for obj in config] File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerassavingsaving_utils.py", line 258, in _deserialize_nested_config return deserialize_fn(config) File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkeraslosses.py", line 1854, in deserialize printable_module_name='loss function') File "C:UsersAdminAnaconda3envstf2.3libsite-packagestensorflowpythonkerasutilsgeneric_utils.py", line 378, in deserialize_keras_object 'Unknown ' + printable_module_name + ': ' + object_name) ValueError: Unknown loss function: focal_loss
这个报错很明显了,Keras找不到我们自定义的focal_loss,故而引发报错,那这个时候又该怎么办呢?
这是因为Keras在保存模型时,会保存训练时候的一切东西,包括优化器状态、权重、损失函数等,但由于这个损失函数函数是我们自定义的,并不在系统自带的损失函数函数中,我们下次重新加载的时候,自然就找不到这个损失函数,故引发了ValueError: Unknown loss function: focal_loss。
Keras早就想到了这点,因此可以在load_model中通过custom_objects参数传入自定义的类或者函数:
def load_model(filepath, custom_objects=None, compile=True, options=None): # pylint: disable=redefined-builtin
"""Loads a model saved via `model.save()`.
Usage:
>>> model = tf.keras.Sequential([
... tf.keras.layers.Dense(5, input_shape=(3,)),
... tf.keras.layers.Softmax()])
>>> model.save('/tmp/model')
>>> loaded_model = tf.keras.models.load_model('/tmp/model')
>>> x = tf.random.uniform((10, 3))
>>> assert np.allclose(model.predict(x), loaded_model.predict(x))
Note that the model weights may have different scoped names after being
loaded. Scoped names include the model/layer names, such as
`"dense_1/kernel:0"`. It is recommended that you use the layer properties to
access specific variables, e.g. `model.get_layer("dense_1").kernel`.
Arguments:
filepath: One of the following:
- String or `pathlib.Path` object, path to the saved model
- `h5py.File` object from which to load the model
custom_objects: Optional dictionary mapping names
(strings) to custom classes or functions to be
considered during deserialization.
compile: Boolean, whether to compile the model
after loading.
options: Optional `tf.saved_model.LoadOptions` object that specifies
options for loading from SavedModel.
Returns:
A Keras model instance. If the original model was compiled, and saved with
the optimizer, then the returned model will be compiled. Otherwise, the
model will be left uncompiled. In the case that an uncompiled model is
returned, a warning is displayed if the `compile` argument is set to
`True`.
Raises:
ImportError: if loading from an hdf5 file and h5py is not available.
IOError: In case of an invalid savefile.
"""
因此,我们只需要将focal_loss通过custom_objects传入即可:
model = load_model(model_path, custom_objects={'focal_loss': focal_loss})
4.结果预览
可以看到模型成功被正确加载:
都看到这里了,还不赶紧点赞,评论,收藏走一波?



