在使用tensorflow.keras加载包含多个自定义loss预训练神经网络时,Visual Studio Code蹿红:
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "D:\ProgramFiles\Anaconda3\envs\MatlabEngine\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "D:\ProgramFiles\Anaconda3\envs\MatlabEngine\lib\site-packages\keras\dtensor\utils.py", line 144, in _wrap_function
init_method(instance, *args, **kwargs)
TypeError: __init__() got an unexpected keyword argument 'reduction'
加载模型代码为:
M = tf.keras.models.load_model('D:/MODEL/my_model.h5', {'user_loss1': user_loss1, 'user_loss2': user_loss2})
自定义损失函数如下:
# Define the loss functions
def user_loss1(y_true, y_pred):
loss = tf.keras.backend.mean(tf.keras.backend.std(y_true - y_pred)) / tf.keras.backend.std(tf.keras.backend.square(y_true))
return loss
def user_loss2(y_true, y_pred):
loss = tf.keras.backend.std(y_true - y_pred)
return loss
# 输入:
Python --version
conda list tensorflow
# 输出:
Python 3.9.16
# packages in environment at D:\ProgramFiles\Anaconda3\envs\MatlabEngine:#
# Name Version Build Channel
tensorflow 2.11.1 pypi_0 pypi
tensorflow-estimator 2.11.0 pypi_0 pypi
tensorflow-intel 2.11.1 pypi_0 pypi
tensorflow-io-gcs-filesystem 0.31.0 pypi_0 pypi
测试描述:
单一只使用user_loss1或者user_loss2时,该报错消失,而给出如下报错
M = tf.keras.models.load_model('D:/MODEL/my_model.h5', {'user_loss1': user_loss1})
# 输出
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "D:\ProgramFiles\Anaconda3\envs\MatlabEngine\lib\site-packages\keras\utils\traceback_utils.py", line 70, in error_handler
raise e.with_traceback(filtered_tb) from None
File "D:\ProgramFiles\Anaconda3\envs\MatlabEngine\lib\site-packages\keras\saving\legacy\serialization.py", line 557, in deserialize_keras_object
raise ValueError(
ValueError: Unknown loss function: 'user_loss2'. Please ensure you are using a `keras.utils.custom_object_scope` and that this object is included in the scope. See https://www.tensorflow.org/guide/keras/save_and_serialize#registering_the_custom_object for details.
有遇到过类似错误的小伙伴不?后面是如何解决的呀?
该报错可能是由于在加载模型时没有正确注册自定义损失函数导致的。另一个可能的原因是,使用的 TensorFlow 版本不支持 reduction 参数,但在自定义损失函数中使用了该参数。
在 TensorFlow 2.0 以后的版本中,reduction 参数被添加到了许多损失函数中,用于指定损失函数在计算损失值时如何将不同样本的损失值进行聚合,例如取平均值、求和等。如果您的 TensorFlow 版本过旧,可能不支持该参数。
解决方法是,在自定义损失函数中移除 reduction 参数,或者升级 TensorFlow 版本至 2.0 或以上版本。
问题原因:
该错误是因为在模型加载时使用了自定义损失函数,并且该自定义损失函数中使用了未知的参数'reduction'。这是因为TensorFlow 2.0之后,自定义损失函数中的'reduction'参数已经被废弃,不再使用。
解决思路:
解决方法:
修改自定义损失函数,移除'reduction'参数,即:
def user_loss1(y_true, y_pred):
loss = tf.keras.backend.mean(tf.keras.backend.std(y_true - y_pred)) / tf.keras.backend.std(tf.keras.backend.square(y_true))
return loss
def user_loss2(y_true, y_pred):
loss = tf.keras.backend.std(y_true - y_pred)
return loss
在加载模型时,使用tf.keras.utils.custom_object_scope()将自定义损失函数加入作用域中,即:
with tf.keras.utils.custom_object_scope({'user_loss1': user_loss1, 'user_loss2': user_loss2}):
M = tf.keras.models.load_model('D:/MODEL/my_model.h5')
这样就可以成功加载包含多个自定义损失函数的预训练模型了。
注:在加载模型时,不需要再指定自定义损失函数,因为已经将其加入作用域中,可以直接加载模型。