Python 如何使用自定义损耗加载模型?
如何使用子类tf.keras.loss.loss的自定义损耗加载模型 我通过将tf.keras.Loss.Loss分为以下子类来定义损失:Python 如何使用自定义损耗加载模型?,python,tensorflow,keras,deep-learning,tensorflow2.0,Python,Tensorflow,Keras,Deep Learning,Tensorflow2.0,如何使用子类tf.keras.loss.loss的自定义损耗加载模型 我通过将tf.keras.Loss.Loss分为以下子类来定义损失: import tensorflow as tf from tensorflow.keras.losses import Loss class ContrastiveLoss(Loss): def __init__(self, alpha, square=True, **kwargs): super(ContrastiveLoss,
import tensorflow as tf
from tensorflow.keras.losses import Loss
class ContrastiveLoss(Loss):
def __init__(self, alpha, square=True, **kwargs):
super(ContrastiveLoss, self).__init__(**kwargs)
self.alpha = alpha
self.square = square
def get_dists(self, x, y, square):
dists = tf.subtract(x, y)
dists = tf.reduce_sum(tf.square(dists), axis=-1)
if not square:
zero_mask = tf.cast(tf.equal(dists, 0.0), tf.float32)
dists = dists + zero_mask * 1e-16
dists = tf.sqrt(dists)
nonzero_mask = 1.0 - zero_mask
dists = dists * nonzero_mask
return dists
def call(self, y_true, y_pred):
# y_true & y_pred shape == (N, #embed), for N mini-batch
# y_true[:, 0] == (N)
if len(y_true.shape) == 2: y_true= y_true[:, 0]
positive_mask = tf.cast(tf.equal( tf.expand_dims(y_true, 0), tf.expand_dims(y_true, 1) ), tf.float32)
negative_mask = tf.subtract(1.0, positive_mask)
all_dists = self.get_dists(tf.expand_dims(y_pred, 1), tf.expand_dims(y_pred, 0), self.square)
positive_loss = tf.multiply( positive_mask, all_dists )
negative_loss = tf.multiply( negative_mask, tf.maximum(tf.subtract(self.alpha, all_dists), 0.) )
contrastive_loss = tf.add( positive_loss, negative_loss )
valid_doublet_mask = tf.cast( tf.greater(contrastive_loss, 1e-16), tf.float32)
num_valid_doublet = tf.reduce_sum(valid_doublet_mask)
contrastive_loss = tf.reduce_sum( contrastive_loss ) / (num_valid_doublet + 1e-16)
return contrastive_loss
def get_config(self):
config = super(ContrastiveLoss, self).get_config()
config.update({'alpha' : self.alpha,
'square' : self.square})
return config
我可以用它训练和保存模型
然而,当我按如下方式加载模型时,会收到错误消息
load_model(model_path, custom_objects={'ContrastiveLoss' : ContrastiveLoss})
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在()
---->1加载\模型(模型\路径,自定义\对象={'ContractLoss':ContractLoss})
/加载\模型中的tensorflow-2.1.0/python3.6/tensorflow\核心/python/keras/saving/save.py(文件路径、自定义\对象、编译)
148如果isinstance(文件路径,六种字符串类型):
149加载程序\u impl.parse\u保存的\u模型(文件路径)
-->150返回保存的\u模型\u load.load(文件路径,编译)
151
152上升IOError(
/加载中的tensorflow-2.1.0/python3.6/tensorflow_核心/python/keras/saving/saving_model/load.py(路径,编译)
97如果培训配置不是无:
98 model.compile(**从\u training\u config保存\u utils.compile\u args\u(
--->99培训(配置)
100#pylint:disable=受保护访问
101
/tensorflow-2.1.0/python3.6/tensorflow\u core/python/keras/saving/saving\u utils.py,从\u training\u config(training\u config,自定义\u对象)编译\u args\u
232损失配置=培训配置['loss']#反序列化损失类。
233如果存在(丢失配置,dict)和丢失配置中的“类名称”:
-->234 loss\u config=loss.get(loss\u config)
235损失=nest.map_结构(
236 lambda obj:custom_objects.get(obj,obj),loss_config)
/get中的tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/loss.py(标识符)
1184返回反序列化(标识符)
1185如果存在(标识符,dict):
->1186返回反序列化(标识符)
1187 elif可调用(标识符):
1188返回标识符
/反序列化中的tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/loss.py(名称、自定义_对象)
1173模块_对象=全局(),
1174自定义_对象=自定义_对象,
->1175可打印\u模块\u name='loss function')
1176
1177
/tensorflow-2.1.0/python3.6/tensorflow\u core/python/keras/utils/generic\u utils.py反序列化\u keras\u对象(标识符、模块\u对象、自定义\u对象、可打印的\u模块\u名称)
290配置=标识符
291(cls,cls_config)=类_和_配置_,用于序列化的_keras_对象(
-->292配置、模块对象、自定义对象、可打印模块名称)
293
294如果hasattr(cls,“来自配置”):
/tensorflow-2.1.0/python3.6/tensorflow\u core/python/keras/utils/generic\u utils.py在类和配置中,用于序列化的\u keras\u对象(配置、模块\u对象、自定义\u对象、可打印的\u模块\u名称)
248 cls=模块对象.get(类名称)
249如果cls为无:
-->250 raise VALUERROR('未知'+可打印模块名称+':'+类名称)
251
252 cls_config=config['config']
ValueError:未知损失函数:默认损失
奇怪的是,如果我使用自定义损耗“函数”,在load_模型(.)
但在这种情况下,使用Loss的“subclass”,就会发生错误
如果javad建议
您是否尝试过使用对象而不是类名,这意味着
load\u model(model\u path,custom\u objects={'contractorloss':contractorloss(…)})
其中..
包含所有用于丢失的参数,如alpha
不起作用,并且您只想进行推断,然后尝试使用:
tf.keras.models.load\u model(“,compile=False)
希望有帮助。您是否尝试过使用对象而不是类名,意思是
load\u model(model\u path,custom\u objects={'contractorloss':contractorloss(…)})
其中..
包含了所有用于丢失的参数,如alpha
,…?@javad,我已经尝试过了,但仍然不起作用。。。
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-5-af42cd2404e1> in <module>()
----> 1 load_model(model_path, custom_objects={'ContrastiveLoss' : ContrastiveLoss})
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/saving/save.py in load_model(filepath, custom_objects, compile)
148 if isinstance(filepath, six.string_types):
149 loader_impl.parse_saved_model(filepath)
--> 150 return saved_model_load.load(filepath, compile)
151
152 raise IOError(
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/saving/saved_model/load.py in load(path, compile)
97 if training_config is not None:
98 model.compile(**saving_utils.compile_args_from_training_config(
---> 99 training_config))
100 # pylint: disable=protected-access
101
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/saving/saving_utils.py in compile_args_from_training_config(training_config, custom_objects)
232 loss_config = training_config['loss'] # Deserialize loss class.
233 if isinstance(loss_config, dict) and 'class_name' in loss_config:
--> 234 loss_config = losses.get(loss_config)
235 loss = nest.map_structure(
236 lambda obj: custom_objects.get(obj, obj), loss_config)
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/losses.py in get(identifier)
1184 return deserialize(identifier)
1185 if isinstance(identifier, dict):
-> 1186 return deserialize(identifier)
1187 elif callable(identifier):
1188 return identifier
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/losses.py in deserialize(name, custom_objects)
1173 module_objects=globals(),
1174 custom_objects=custom_objects,
-> 1175 printable_module_name='loss function')
1176
1177
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/utils/generic_utils.py in deserialize_keras_object(identifier, module_objects, custom_objects, printable_module_name)
290 config = identifier
291 (cls, cls_config) = class_and_config_for_serialized_keras_object(
--> 292 config, module_objects, custom_objects, printable_module_name)
293
294 if hasattr(cls, 'from_config'):
/tensorflow-2.1.0/python3.6/tensorflow_core/python/keras/utils/generic_utils.py in class_and_config_for_serialized_keras_object(config, module_objects, custom_objects, printable_module_name)
248 cls = module_objects.get(class_name)
249 if cls is None:
--> 250 raise ValueError('Unknown ' + printable_module_name + ': ' + class_name)
251
252 cls_config = config['config']
ValueError: Unknown loss function: ContrastiveLoss