Tensorflow 如何仅为正则化损失编写自定义度量?

Tensorflow 如何仅为正则化损失编写自定义度量?,tensorflow,keras,tensorflow2.0,tf.keras,Tensorflow,Keras,Tensorflow2.0,Tf.keras,某些层具有正则化损失。我希望有一个“指标”,只记录正规化损失,这样我就可以在进度条中单独(从总损失中)看到正规化损失在训练期间的演变。此外,鉴于度量保存在历史对象中(由fit返回),我可以在培训结束时轻松地绘制并保存(到文件中)正则化损失 如何仅为正则化损失编写自定义度量 我知道我可以有一个回调来迭代模型的层,并对正则化损失求和(例如,请参见),但我希望有一个度量(而不是回调),因为度量将保存在历史对象中 最后,我希望正则化损失出现在历史对象中,并显示在进度栏中(与总损失分开),即使不实现自定义

某些层具有正则化损失。我希望有一个“指标”,只记录正规化损失,这样我就可以在进度条中单独(从总损失中)看到正规化损失在训练期间的演变。此外,鉴于度量保存在历史对象中(由
fit
返回),我可以在培训结束时轻松地绘制并保存(到文件中)正则化损失

如何仅为正则化损失编写自定义度量

我知道我可以有一个回调来迭代模型的层,并对正则化损失求和(例如,请参见),但我希望有一个度量(而不是回调),因为度量将保存在历史对象中


最后,我希望正则化损失出现在历史对象中,并显示在进度栏中(与总损失分开),即使不实现自定义度量,但我不知道
tf.keras
中是否有这样的选项。另外,如果我能有两个选择,那就太好了:1。参见所有层和2的所有正则化损失的总和。请分别查看每层的正则化损失。

我想我找到了解决方案。您可以在回调中修改参数
logs
,以添加所需的信息。然后,历史对象将自动包含此新信息

def get_cb(model):
    def on_epoch_end(epoch, logs):
        # Iterate the layers of your model to get the regularisation losses
        reg_losses = get_your_regularisation_losses(model)
        logs["reg_losses"] = reg_losses

    return tf.keras.callbacks.LambdaCallback(on_epoch_end=on_epoch_end)

...
history = model.fit(..., callbacks=[get_cb(model)])
do_something(history) # history contains "reg_losses"

(请随时提供使用自定义指标的替代解决方案!)

要在进度栏中显示,您可以执行以下操作:


这会将所有正则化损失项的总和作为度量添加到模型中。这种方法的缺点是,如果希望进度条显示各个层的损失项,则必须为每个正则化层定义一个唯一命名的函数。

如何在模型中添加正则化?使用层的
kernel\u regularizer
参数,或在自定义层/模型中使用
add\u loss
方法?@今天在我的具体案例中,我使用的是TFP的
DenseFlipout
。他们用
add_loss
将损失添加到字段
loss
,但我认为这没有任何区别。我明白了。这是您不使用回调的唯一原因:“因为度量将保存在历史对象中。”?换句话说,如果它存储在历史对象中,那么不管它是度量还是回调,您都可以使用它,对吗?@今天,是的,能够访问历史对象的正则化损失是很好的。现在,我正在尝试这样做:,但是如果我可以将规则添加到历史中,我的代码将更加统一(因为我已经在训练结束时通过访问历史对象绘制了其他损失的演变图)。
def get_reg_loss(reg_layers):
    def reg_loss_term(y_true, y_pred):
        return tf.add_n([r.losses[0] for r in reg_layers])

    return reg_loss_term

model.compile(..., metrics=[..., get_reg_loss(reg_layers)])