【发布时间】:2021-12-15 15:07:57
【问题描述】:
我是 Tensorflow 和 Keras 的新手。我想在自定义损失函数中使用样本权重。
如果我理解正确,这篇文章 (Custom loss function with weights in Keras) 建议将权重作为网络的输入。 还有这个: Custom weighted loss function in Keras for weighing each element
我想知道我是否遗漏了什么(我也不想将权重定义为全局变量)。我也有点惊讶没有直接使用它的方法,因为 Loss 类 _ _ call _ _ 方法接受 sample_weight 作为参数,但如果我理解正确,损失函数必须只有参数 y_true 和 y_pred。
然而,从文档 (https://keras.io/api/losses/#creating-custom-losses):
创建自定义损失 任何带有签名 loss_fn(y_true, y_pred) 且返回损失数组(输入批次中的样本之一)的可调用函数都可以作为损失传递给 compile()。请注意,任何此类损失都会自动支持样本加权。
听起来应该可以通过 model.fit(..., sample_weight=sample_weight) 方法使用样本加权。
在这篇文章中(Should the custom loss function in Keras return a single loss value for the batch or an arrary of losses for every sample in the training batch? ) 关于损失函数的输出大小有一个冗长的讨论。
最后还提到,当创建自定义损失函数时,应该返回一组损失(单个样本损失)。它们的减少由框架处理。
在我看来,如果 custom_loss(y_true, y_pred) 返回一个大小为 (batch_size, ) 的张量,那么应该能够在 fit 方法中使用 sample_weight。我错过了什么?
非常感谢您的帮助!
代码sn-ps:
class NegLogLikMixedGaussian(Loss):
"""
Negative Log-Likelihood of Mixed Gaussian with:
num_components: number of components
mu: means of the Gaussian components
sg: standard deviations of the Gaussian components
"""
def __init__(self, num_params=NUM_PARAMS_MG,
num_components=2, name='neg_log_lik_mixed_gaussian'):
super(NegLogLikMixedGaussian, self).__init__(name=name)
self.num_params = num_params
self.num_components = num_components
def call(self, y_true, p_predict):
"""
Rem: for MDN the output of the networks are _parameters_ of the
predicted distribution, _not_ point-estimates
Parameters
----------
y_true: (batch_size, 1)
Observed value of the random variable
p_predict: (batch_size, num_components)
Output parameters of the network given some input
Returns
-------
Negative log likelihood of the batch (batch_size, 1)
"""
alpha, mu, sg = tf.split(p_predict,
num_or_size_splits=self.num_params, axis=1)
gm = tfd.MixtureSameFamily(
mixture_distribution=tfd.Categorical(probs=alpha),
components_distribution=tfd.Normal(loc=mu, scale=sg))
log_likelihood = tf.transpose(gm.log_prob(tf.transpose(y_true)))
return -tf.reduce_mean(log_likelihood, axis=-1)
我希望那时能够使用:
model.compile(optimizer=Adam(learning_rate=0.005),
loss=NegLogLikMixedGaussian(
num_components=2, num_params=3))
还有:
# For testing purposes
sample_weight = np.ones(len(y_train)) / len(dh.y_train_scaled) # this should give same results as un-weighted
# Some non-trivial weights
sample_weights = np.zeros(len(y_train))
sample_weights[:5] = 1
# This will give me same results as above
model.fit(x_train, y_train, sample_weight=sample_weight,
batch_size=128, epochs=10)
【问题讨论】:
标签: python tensorflow loss-function