我正在尝试运行一个接受sample_weights的自定义函数。我正在关注本文档https://www.tensorflow.org/api_docs/python/tf/keras/losses/Loss。
但是,当我尝试使用以下成本函数时:
class deltaE(Loss):
def __call__(self, y_true, y_pred, sample_weight):
errors = tf_get_deltaE2000(y_true * tf_Xtrain_labels_max, y_pred * tf_Xtrain_labels_max)
errors *= sample_weight
return tf.math.reduce_mean(errors, axis=-1)
loss_deltaE = deltaE()
我在Model.fit
方法上收到此错误。
TypeError: in user code:
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:571 train_function *
outputs = self.distribute_strategy.run(
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:951 run **
return self._extended.call_for_each_replica(fn, args=args, kwargs=kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2290 call_for_each_replica
return self._call_for_each_replica(fn, args, kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/distribute/distribute_lib.py:2649 _call_for_each_replica
return fn(*args, **kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/training.py:543 train_step **
self.compiled_metrics.update_state(y, y_pred, sample_weight)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/engine/compile_utils.py:411 update_state
metric_obj.update_state(y_t, y_p)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/utils/metrics_utils.py:90 decorated
update_op = update_state_fn(*args, **kwargs)
/usr/local/lib/python3.6/dist-packages/tensorflow/python/keras/metrics.py:603 update_state
matches = self._fn(y_true, y_pred, **self._fn_kwargs)
TypeError: __call__() missing 1 required positional argument: 'sample_weight'
我正在使用一个生成器,该生成器可以根据需要生成长度为3的元组。我已经检查过了。一切正常。
cost函数也可以正常工作。当我使用下面的代码时,模型可以毫无问题地训练。
def loss_deltaE(y_true, y_pred):
errors = tf_get_deltaE2000(y_true * tf_Xtrain_labels_max, y_pred * tf_Xtrain_labels_max)
return tf.math.reduce_mean(errors, axis=-1)
如果有人有任何线索。我会很感激的。预先感谢!
答案 0 :(得分:1)
这是一种将其他参数传递给自定义损失函数的解决方法。诀窍在于使用伪造的输入,以正确的方式来建立和使用损失
我在回归问题中提供了一个虚拟的例子
def mse(y_true, y_pred, sample_weight):
error = y_true-y_pred
return K.mean(K.sqrt(error)*sample_weight)
X = np.random.uniform(0,1, (1000,10))
y = np.random.uniform(0,1, 1000)
W = np.random.uniform(1,2, 1000)
inp = Input((10))
true = Input((1))
sample_weight = Input((1))
x = Dense(32, activation='relu')(inp)
out = Dense(1)(x)
m = Model([inp,true, sample_weight], out)
m.add_loss( mse( true, out, sample_weight ) )
m.compile(loss=None, optimizer='adam')
history = m.fit([X, y, W], y, epochs=10)
# final fitted model to compute predictions
final_m = Model(inp, out)