【问题标题】:Why does Octave round to 1 'earlier' than 0?为什么 Octave 比 0 更早地舍入到 1?
【发布时间】:2019-07-06 12:16:44
【问题描述】:

上下文:

在 Octave 中,我为 Sigmoid 函数编写了代码,该函数返回 0 到 1 之间的值;在理想情况下,-Inf 只会返回 0,+Inf 只会返回 1,但由于浮点不精确,非常接近其中任何一个的值都会被四舍五入。

问题:

我的问题是为什么会发生以下情况:0 和 1 的舍入边界明显不同:

>> sigmoid(-709)
ans =   1.2168e-308
>> sigmoid(-710)
ans = 0
>> sigmoid(36)
ans =  1.00000
>> sigmoid(37)
ans =  1
>> (sigmoid(37)-1)==0
ans = 1
>> (sigmoid(36)-1)==0
ans = 0
>> sigmoid(-710)==0
ans = 1
>> sigmoid(-709)==0
ans = 0

在示例中,可以看到将输出舍入为 1 所需的值比舍入为 0 所需的值要小得多。37 与 -710 相比是一个非常大的差异,因为它们在量级但符号相反...

我的代码:

也许这是我的功能的问题:

function [z] = sigmoid(x)
z = 1.0 ./(1.0+exp(-x));
endfunction

我的尝试:

另一点,我更改了函数以将 1 添加到结果(基本上将图形向上平移 1),并且边界分别变为 2 和 1 的 +/-37 - 这让我认为它真的是尤其是 0 而不仅仅是函数及其下限。

如果和我的电脑有关,那是什么原因造成的呢?

【问题讨论】:

    标签: floating-point octave rounding data-representation


    【解决方案1】:

    首先,查看this brilliant answer by gnovice on floating-point representation

    除此之外,让我们看看您在此处看到的内容:您可以计算一个非常接近于零的值:sigmoid(-709) 大约等于 1.2e-308,但您无法计算出类似接近于零的值一:sigmoid(709)正好等于1,而不是1 - 1.2e-308,甚至sigmoid(36) == 1,而不是一个略小于1的值。

    但是当我们知道浮点数是如何存储在内存中的时候,我们就会意识到1 - 1.2e-308 不能被精确地表示。我们需要 308 个十进制数字来准确表示这个数字。双精度浮点数(Octave 中的默认值)大约有 15 个十进制数字。即1 - 1e-16可以表示,但1 - 1e-17不能。

    eps(1) 的值是2.2204e-16,这是我们可以用双精度浮点数编码的与 1 的最小差异。

    但是接近 0 的值可以更精确地表示:eps(0)4.9407e-324。那是因为1.2e-308这样的值不需要308个十进制数字来表示,而只需要2个,指数中的值为-308。

    在任何情况下,如果您依赖 sigmoid 函数的精确值,距离转换位置如此之远,那么您的代码逻辑就有问题。

    如果你想让这个函数对称,你所能做的就是降低低端的精度。有两种方法可以做到这一点:

    1. 只需将非常小的值设置为零,以便z==0 与另一侧的z==1 在同一点到达:

      function z = sigmoid(x)
        z = 1.0 ./ (1.0+exp(-x));
        z(z < eps(1)) = 0;
      end
      
    2. 始终计算函数的右半部分,然后折回负输入。这使得x=0两边的计算误差对称:

      function z = sigmoid(x)
        z = 1.0 ./ (1.0+exp(-abs(x)));
        I = x < 0;
        z(I) = 0.5 - z(I);
      end
      

    【讨论】:

    • 精彩的解释,很有道理!我实际上并不需要它是对称的,但是非对称行为导致我的代码中出现了我没想到的问题。答案很有趣——我不知道 eps() 量化精度会随着传递给它的值而变化。即使我没有要求他们,如果可以的话,也会为这些解决方案提供额外的 +1 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-23
    • 2012-09-16
    • 1970-01-01
    • 2017-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-07-22
    相关资源
    最近更新 更多