【问题标题】:Why is my loss function increasing with each epoch?为什么我的损失函数随着每个时期的增加而增加?
【发布时间】:2021-12-13 17:34:01
【问题描述】:

我是 ML 的新手,所以如果这是一个任何人都能想到的愚蠢问题,我很抱歉。我在这里使用 TensorFlow 和 Keras。

这是我的代码:

import tensorflow as tf
import numpy as np
from tensorflow import keras
model = keras.Sequential([
    keras.layers.Dense(units=1, input_shape=[1])
])
model.compile(optimizer="sgd", loss="mean_squared_error")
xs = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0], dtype=float)
ys = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0], dtype=float)
model.fit(xs, ys, epochs=500)
print(model.predict([25.0]))

我将此作为输出 [我没有显示全部 500 行,仅显示 20 个 epoch:

Epoch 1/500
1/1 [==============================] - 0s 210ms/step - loss: 450.9794
Epoch 2/500
1/1 [==============================] - 0s 4ms/step - loss: 1603.0852
Epoch 3/500
1/1 [==============================] - 0s 10ms/step - loss: 5698.4731
Epoch 4/500
1/1 [==============================] - 0s 7ms/step - loss: 20256.3398
Epoch 5/500
1/1 [==============================] - 0s 10ms/step - loss: 72005.1719
Epoch 6/500
1/1 [==============================] - 0s 4ms/step - loss: 255956.5938
Epoch 7/500
1/1 [==============================] - 0s 3ms/step - loss: 909848.5000
Epoch 8/500
1/1 [==============================] - 0s 5ms/step - loss: 3234236.0000
Epoch 9/500
1/1 [==============================] - 0s 3ms/step - loss: 11496730.0000
Epoch 10/500
1/1 [==============================] - 0s 3ms/step - loss: 40867392.0000
Epoch 11/500
1/1 [==============================] - 0s 3ms/step - loss: 145271264.0000
Epoch 12/500
1/1 [==============================] - 0s 3ms/step - loss: 516395584.0000
Epoch 13/500
1/1 [==============================] - 0s 4ms/step - loss: 1835629312.0000
Epoch 14/500
1/1 [==============================] - 0s 3ms/step - loss: 6525110272.0000
Epoch 15/500
1/1 [==============================] - 0s 3ms/step - loss: 23194802176.0000
Epoch 16/500
1/1 [==============================] - 0s 3ms/step - loss: 82450513920.0000
Epoch 17/500
1/1 [==============================] - 0s 3ms/step - loss: 293086593024.0000
Epoch 18/500
1/1 [==============================] - 0s 5ms/step - loss: 1041834835968.0000
Epoch 19/500
1/1 [==============================] - 0s 3ms/step - loss: 3703408164864.0000
Epoch 20/500
1/1 [==============================] - 0s 3ms/step - loss: 13164500484096.0000

如您所见,它呈指数级增长。很快(在第 64 个纪元),这些数字变为inf。然后,从无穷大开始,它做了一些事情,变成了NaN(不是数字)。我认为模型会随着时间的推移更好地找出模式,这是怎么回事?

我注意到一件事,如果我将 xsys 的长度从 20 减少到 10,损失会减少并变为 7.9193e-05。在我将两个 numpy 数组的长度增加到 18 之后,它开始不受控制地增加,否则没关系。我给出了 20 个值,因为我认为如果我给出更多数据,模型会更好,这就是我给出 20 个值的原因。

【问题讨论】:

    标签: python tensorflow keras artificial-intelligence loss-function


    【解决方案1】:

    你的 alpha/学习率似乎太大了。

    尝试使用较低的学习率,如下所示:

    import tensorflow as tf
    import numpy as np
    from tensorflow import keras
    model = keras.Sequential([
        keras.layers.Dense(units=1, input_shape=[1])
    ])
    # manually set the optimizer, default learning_rate=0.01
    opt = keras.optimizers.SGD(learning_rate=0.0001)
    
    model.compile(optimizer=opt, loss="mean_squared_error")
    xs = np.array([1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0], dtype=float)
    ys = np.array([0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0], dtype=float)
    model.fit(xs, ys, epochs=500)
    print(model.predict([25.0]))
    

    ...这将收敛。

    ADAM 工作得更好的原因之一可能是因为它自适应地估计学习率 - 我认为 ADAM 中的 A 代表 Adaptive ;))。

    编辑:确实如此!

    来自https://arxiv.org/pdf/1412.6980.pdf

    该方法计算个体自适应学习率 与梯度的第一和第二矩估计不同的参数; 亚当这个名字 源自自适应矩估计

    Epoch 1/500
    1/1 [==============================] - 0s 129ms/step - loss: 1.2133
    Epoch 2/500
    1/1 [==============================] - 0s 990us/step - loss: 1.1442
    Epoch 3/500
    1/1 [==============================] - 0s 0s/step - loss: 1.0792
    Epoch 4/500
    1/1 [==============================] - 0s 1ms/step - loss: 1.0178
    Epoch 5/500
    1/1 [==============================] - 0s 1ms/step - loss: 0.9599
    Epoch 6/500
    1/1 [==============================] - 0s 1ms/step - loss: 0.9053
    Epoch 7/500
    1/1 [==============================] - 0s 0s/step - loss: 0.8538
    Epoch 8/500
    1/1 [==============================] - 0s 1ms/step - loss: 0.8053
    Epoch 9/500
    1/1 [==============================] - 0s 999us/step - loss: 0.7595
    Epoch 10/500
    1/1 [==============================] - 0s 1ms/step - loss: 0.7163
    ...
    Epoch 499/500
    1/1 [==============================] - 0s 1ms/step - loss: 9.9431e-06
    Epoch 500/500
    1/1 [==============================] - 0s 999us/step - loss: 9.9420e-06
    

    EDIT2:

    使用 true/"vanilla" 梯度下降,您应该在每一步都看到收敛。如果你开始发散,通常是因为 alpha/learning-rate/step-size 太大。这意味着搜索在一个、多个或所有维度上“过冲”。

    考虑一个损失函数,它的偏导数/梯度在一维或多维上有一个非常窄的谷。 “小步太远”可能意味着突然出现大错误。

    【讨论】:

    • 你能解释一下“自适应学习率”是什么意思吗?
    • 阅读en.wikipedia.org/wiki/Gradient_descent 上的文章(搜索“步长”)并了解什么是 alpha/learning-rate。然后,您将了解 alpha 如何是一种“步长”,以及如果太大/太小可能会出现问题,因此需要自适应 alpha(用于 ADAM 等更智能的算法)。有很多关于这方面的文献和谷歌上的很多文章,可以比我更好地解释它
    • 所以,如果您可以接受很多 epoch,那么较小的学习率比较大的学习率要好,对吗?
    • 是的,听起来你明白了 :) 使用天真/简单/愚蠢的梯度下降(甚至是 SGD),确定学习率可能是一门艺术。这在很大程度上取决于模型/数据。问题随着尺寸而增长,另见the curse of dimensionality
    • 感谢@mortonjensen 也对我的回答提供了一些见解。我最初认为这可能是学习率,但我不明白为什么 adam 会工作而 sgd 不会。自适应部分很有意义。
    【解决方案2】:

    似乎优化器 SGD 在您的数据集上表现不佳。 如果您将优化器替换为“adam”,您应该会得到预期的结果。

    model.compile(optimizer="adam", loss="mean_squared_error")
    

    那么预测应该是你所期望的

    print(model.predict([25.0]))
    # [[12.487587]]
    

    我不是 100% 了解 SGD 优化器为何如此糟糕。

    编辑:

    @MortenJensen(下)很好地解释了为什么亚当优化器做得更好。 总结:sgd做不好的原因是它需要更小的学习率。然而,Adam 具有自适应学习率。

    【讨论】:

      猜你喜欢
      • 2017-11-02
      • 2012-06-20
      • 2021-11-22
      • 2018-09-21
      • 2022-09-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多