【问题标题】:Adding a constant to Loss function in Tensorflow在 Tensorflow 中向损失函数添加一个常数
【发布时间】:2020-08-28 03:24:12
【问题描述】:

我问了一个类似的问题,但没有回应。所以我再试一次,

我正在阅读一篇论文,该论文建议将一些在 Tensorflow 之外计算的值添加到 Tensorflow 中神经网络模型的损失函数中。我给你看这里的报价(我已经模糊了不重要的部分):

在 Tensorflow 中拟合序列模型时,如何向损失函数添加预先计算的值? 使用的损失函数是 BinaryCrossentropy,你可以在论文引用的公式 (4) 中看到它。附加值显示在报价中,但对于我认为的问题并不重要。

我的模型看起来如何并不重要,我只是想在拟合我的模型时在 tensorflow 中为我的损失函数添加一个常数值。

非常感谢!!

【问题讨论】:

    标签: python tensorflow neural-network loss-function


    【解决方案1】:

    您似乎希望能够定义自己的损失。另外,我不确定您使用的是实际的 Tensorflow 还是 Keras。这是 Keras 的解决方案:

    import tensorflow.keras.backend as K
    
    def my_custom_loss(precomputed_value):
        def loss(y_true, y_pred):
            return K.binary_crossentropy(y_true, y_pred) + precomputed_value
        return loss
    
    my_model = Sequential()
    my_model.add(...)
    # Add any layer there
    
    my_model.compile(loss=my_custom_loss(42))
    

    灵感来自https://towardsdatascience.com/advanced-keras-constructing-complex-custom-losses-and-metrics-c07ca130a618

    编辑:答案只是添加一个常数项,但我意识到论文中建议的术语不是常数。

    我没有读过论文,但我认为从交叉熵定义来看,sigma 是基本事实,p 是预测值。如果没有其他依赖,解决方案甚至可以更简单:

    def my_custom_loss(y_pred, y_true):
        norm_term = K.square( K.mean(y_true) - K.mean(y_pred) )
        return K.binary_crossentropy(y_true, y_pred) + norm_term
    
    # ...
    
    my_model.compile(loss=my_custom_loss)
    

    在这里,我假设仅对每批计算期望值。告诉我这是否是你想要的。否则,如果您想以不同的规模计算统计数据,例如在每个 epoch 之后的整个数据集上,您可能需要使用回调。 在这种情况下,请更准确地说明您的问题,例如为y_predy_true 添加一个小示例,以及预期的损失。

    【讨论】:

    • 感谢您的回答。像这样,“precomputed_value”只是在编译数据时添加的,怎么可能为每个 epoch 或实际上为每个 mini_batch 执行此操作?
    • 在这里我编辑了答案,为仅取决于批处理统计信息的非常数项添加了一些精度。是你想要的吗?
    • 感谢您再次回复。是的,你是对的,sigma 是“基本事实”,但是论文的背景要复杂得多,我试图绕过对我的问题进行解释。如果我多解释一点,也许会有所帮助。 E() 不是您所写的期望值或“平均值”。它是能量。能量可以通过更困难的算法来计算。我不确定如何以后端的方式实现这一点。
    • 而且 p 也稍微复杂一些。是的,它是预测,但需要在另一个步骤中进行处理以计算此处的能量。预测是 0 和 1 之间的浮点数,实际上是表示为 0 或 1 的概率。所以最终它是一个二进制数。把它想象成薛定谔猫,它也是一篇物理论文......任何提示我如何实现这个?或者这篇论文的引用是什么意思?
    • 您从一开始就提供的信息越多,就越容易帮助您。你写过代码来计算那个能量项吗?你可以通过编辑你的问题来分享它吗?您还可以分享您提到的论文的链接。
    【解决方案2】:

    如您所见,在上面的等式中,结果可能非常低,即可能会出现梯度消失的问题。

    为了缓解这种情况,他们要求为损失添加一个常数值。

    现在,您可以使用简单的常数,例如 1、10 或其他任何值,或者与他们所说的成正比。

    您可以很容易地根据基本事实计算出某一部分的期望值。另一部分是棘手的,因为在你训练之前你不会有值,并且动态计算它们是不明智的。

    该术语表示基本事实和预测之间会有多大差异。

    所以,如果你要实现这篇论文,那么,给你的损失添加一个常数值 1,这样它就不会消失。

    【讨论】:

    • 感谢您的回答,但仍有一些不清楚的地方。将常数值 1 添加到损失函数时,这如何影响梯度?从这个意义上说,梯度、损失的推导和添加一个常数不会以这种方式改变事情吗?
    • 它不会改变渐变,它只是为了保护你的渐变不消失。
    • 这不是矛盾吗?在损失中添加一个常数如何防止梯度消失?梯度是损失函数的推导,而常数的推导为零。
    • 是的,梯度是权重变化率的推导,但是如果结果为零会发生什么,那么反向传播的将是那个零,它将开始减少权重整个网络。学习将因此停止。所以,你在损失中添加一些东西来保持它,因为也许这个批次或时代已经变坏了,但是下次当数据流过它时,权重可能会恢复。它为您的网络提供了一个反弹的机会。
    • 我想你理解错了。任何反向传播算法都在考虑损失函数的推导,而不是“权重变化率”的推导。最后一个是拉普拉斯算子。据我了解:如果您的损失值为 100 万或 1,则反向传播算法并不重要。重要的是步骤之间损失函数之间的差异。需要推导出损失函数才能使反向传播算法起作用,并且常数的推导为零。因此,添加任何常量都无济于事。
    猜你喜欢
    • 2016-08-02
    • 1970-01-01
    • 1970-01-01
    • 2018-03-03
    • 2020-02-11
    • 2019-01-20
    • 1970-01-01
    • 2019-02-03
    • 1970-01-01
    相关资源
    最近更新 更多