【问题标题】:Octave -inf and NaN八度 -inf 和 NaN
【发布时间】:2019-01-24 12:02:51
【问题描述】:

我搜索了论坛并找到了这个帖子,但它没有涵盖我的问题 Two ways around -inf

在第 3 周的机器学习课程中,我在使用 log(0) 时得到了 -inf,后来它变成了 NaNNaN 导致求和公式中没有给出答案,因此J 没有标量(成本函数,它是矩阵数学的结果)。

这是我的功能测试

>> sigmoid([-100;0;100])
ans =
3.7201e-44
5.0000e-01
1.0000e+00

这符合预期。但假设需要ans = 1-sigmoid

>> 1-ans
ans =
1.00000
0.50000
0.00000

Log(0) 给出-Inf

>> log(ans)
ans =
0.00000
-0.69315
-Inf

-Inf 行不会添加到成本函数中,但-Inf 会传递到NaN,我没有得到结果。我在-Inf 上找不到任何资料,但我认为我的 sigmoid 函数有问题。

你能提供任何方向吗?

【问题讨论】:

  • -inf 行可能对成本函数有贡献。从技术上讲,sigmoid (100) 只是略小于 1,但对于浮点表示的精度来说,差异可能太小了。 (1 - ans) 因此是一个非常非常小的正数。因此,log(1 - ans) 是一个非常非常负的数。这肯定会影响成本函数。

标签: octave


【解决方案1】:

在这些情况下避免无穷大的典型方法是将eps 添加到操作数:

log(ans + eps)

eps 是一个非常非常小的值,不会影响 ans 的值的输出,除非 ans 为零:

>> z = [-100;0;100];
>> g = 1 ./ (1+exp(-z));
>> log(1-g + eps)
ans =
    0.0000
   -0.6931
  -36.0437

【讨论】:

  • 我的sigmoid函数是g = 1./(1+exp(-z));这和spoonless的g = 1 ./ (1 + e.^-z); 非常相似
  • 我的sigmoid函数是g = 1./(1+exp(-z));这与spoonless 的g = 1 ./ (1 + e.^-z); 非常相似。 e.^-z 和 exp(-z) 返回不同精度的值有什么不同吗?八度或其他地方是否有影响这一点的设置?感谢您的建议。 (对不起,多个帖子 - 这是由于胖手指)
  • @Edwardh:如果您将鼠标悬停在评论上,您可以通过单击出现在末尾的“x”按钮来删除您自己的 cmets。
  • @Edwardh:MATLAB 不知道e,它可能是 Octave 扩展。但是,exp(-z)exp(1).^-z 产生几乎相同的值 (3.7201e-44),但相差 ~4e-58。在任何情况下,1-g 在这两种情况下都与0 相同。
【解决方案2】:

除了这里的答案,我真的希望您能为您的问题提供更多背景信息(特别是what are you actually trying to do

我会冒险去猜测上下文,以防万一这有用。您可能正在进行机器学习,并尝试根据模型的负对数似然度定义成本函数,然后尝试区分它以找到该成本最低的点。

一般而言,对于具有遵循Cromwell's rule 的有用可能性的合理模型,您不应该遇到这些问题,但实际上它会发生。并且大概在尝试计算零概率的负对数似然的过程中,您得到 inf,并且尝试计算两点之间的差异会产生 inf / inf = nan。

在这种情况下,这是一个“边缘情况”,通常在计算机科学中,边缘情况需要被视为例外情况并进行适当处理。现实情况是,您可以合理地预期 inf 不会是您的函数的最小值!因此,无论是从计算中删除它,还是用一个非常大的数字替换它(无论是任意的还是通过机器精度)都没有真正的区别。

因此,在实践中,您可以执行其他人在此处建议的两件事中的任何一件,或者甚至只是检测此类实例并从计算中跳过它们。实际结果应该是一样的。

【讨论】:

    【解决方案3】:

    -inf 表示负无穷大。这是正确的答案,因为 (0) 的对数定义为负无穷大。

    最简单的做法是检查您的中间结果,如果数字低于某个阈值(如 1e-12),则只需将其设置为该阈值即可。答案并不完美,但仍会非常接近。

    使用以下作为 sigmoid 函数:

    function g = sigmoid(z)
    g = 1 ./ (1 + e.^-z);
    end
    

    然后下面的代码运行没有问题。选择“max”语句中的阈值小于测量中的预期噪声,然后你就可以开始了

    >> a = sigmoid([-100, 0, 100])
    a =
    
       3.7201e-44   5.0000e-01   1.0000e+00
    
    >> b = 1-a
    b =
    
       1.00000   0.50000   0.00000
    
    >> c = max(b, 1e-12)
    c =
    
       1.0000e+00   5.0000e-01   1.0000e-12
    
    >> d = log(c)
    d =
    
        0.00000   -0.69315  -27.63102
    

    【讨论】:

      猜你喜欢
      • 2017-11-05
      • 1970-01-01
      • 2021-09-28
      • 2014-05-03
      • 1970-01-01
      • 2012-11-08
      • 1970-01-01
      • 2021-11-29
      • 1970-01-01
      相关资源
      最近更新 更多