【问题标题】:Custom loss function with regularization cost added in TensorFlow在 TensorFlow 中添加了正则化成本的自定义损失函数
【发布时间】:2021-06-09 22:03:05
【问题描述】:

我编写了一个自定义损失函数,将正则化损失添加到总损失中,我只将 L2 正则化器添加到内核,但是当我调用 model.fit() 时出现警告,指出这些偏差不存在梯度,并且偏差不会更新,如果我从其中一层的内核中删除正则化器,该内核的梯度也不存在。

我尝试向每一层添加偏差正则化器,一切正常,但我不想对偏差进行正则化,我该怎么办?

这是我的损失函数:

 def _loss_function(y_true, y_pred):
    # convert tensors to numpy arrays
    y_true_n = y_true.numpy()
    y_pred_n = y_pred.numpy()
    # modify probablities for Knowledge Distillation loss
    # we do this for old tasks only
    old_y_true = np.float_power(y_true_n[:, :-1], 0.5)
    old_y_true = old_y_true / np.sum(old_y_true)
    old_y_pred = np.float_power(y_pred_n[:, :-1], 0.5)
    old_y_pred = old_y_pred / np.sum(old_y_pred)
    # Define the loss that we will used for new and old tasks
    bce = tf.keras.losses.BinaryCrossentropy()
    # compute the loss on old tasks
    old_loss = bce(old_y_true, old_y_pred)
    # compute the loss on new task
    new_loss = bce(y_true_n[:, -1], y_pred_n[:, -1])
    # compute the regularization loss
    reg_loss = tf.compat.v1.losses.get_regularization_loss()
    assert reg_loss is not None
    # convert all tensors to float64
    old_loss = tf.cast(old_loss, dtype=tf.float64)
    new_loss = tf.cast(new_loss, dtype=tf.float64)
    reg_loss = tf.cast(reg_loss, dtype=tf.float64)
    return old_loss + new_loss + reg_loss

【问题讨论】:

    标签: tensorflow deep-learning loss-function


    【解决方案1】:

    在 keras 中,损失函数应该返回没有正则化损失的损失值。正则化损失将通过在每个 keras 层中设置 kernel_regularizer 或 bias_regularizer 自动添加。

    换句话说,当您编写自定义损失函数时,您不必关心正则化损失。

    编辑:您收到梯度不存在的警告消息的原因是因为在您的损失函数中使用了numpy()。 numpy() 将停止任何梯度传播。

    在向层添加正则化器后,警告消息消失了不暗示随后正确计算了梯度。它只包括来自正则化器的梯度,而不包括来自数据的梯度。应该在损失函数中删除numpy(),以获得正确的梯度。

    其中一个解决方案是将所有内容保存在张量中并使用 tf.math 库。例如使用tf.pow 替换np.float_power 和tf.reduce_sum 替换np.sum

    【讨论】:

    • 我照你说的做了,但还是会出现同样的警告
    • 您能否为您的答案提供参考?
    • 哦,我错过了你调用numpy()的损失函数有错误。你不能调用 numpy() 来停止渐变。我将补充我的答案。
    • 关于“损失函数应该在没有正则化损失的情况下返回损失值”的参考,我认为tensorflow没有非常清楚地记录这一点,这就是我回答的原因。我知道通过阅读 tensorflow 的源代码并通过查看 model.fit 的日志记录来观察损失值的行为。
    • 如果要验证,可以做一个这样的实验,通过 tf.keras.losses.BinaryCrossentropy(name='total_loss') 和 tf.keras.metrics.BinaryCrossentropy(name='bce ') (请注意,一个是指标,另一个是损失)到 model.compile() 并为您的模型添加正则化。然后,在model.fit()的日志中,你会发现总损失大于bce。
    猜你喜欢
    • 1970-01-01
    • 2018-06-11
    • 2018-10-28
    • 2017-12-29
    • 2016-09-27
    • 2017-01-20
    • 2022-11-07
    • 2019-12-16
    • 2020-07-29
    相关资源
    最近更新 更多