我知道Java Double.NaN
是什么。我有一些生成NaN
的Java代码。
// calculate errors
delta = m1 + m2 - M;
eta = f1 + f2 - F;
for (int i = 0; i < numChildren; i++) {
epsilon[i] = p[i]*m1+(1-p[i])*m2+q[i]*f1+(1-q[i])*f2-C[i];
}
// use errors in gradient descent
// set aside differences for the p's and q's
float mDiff = m1 - m2;
float fDiff = f1 - f2;
// first update m's and f's
m1 -= rate*delta;
m2 -= rate*delta;
f1 -= rate*eta;
f2 -= rate*eta;
for (int i = 0; i < numChildren; i++) {
m1 -= rate*epsilon[i]*p[i];
m2 -= rate*epsilon[i]*(1-p[i]);
f1 -= rate*epsilon[i]*q[i];
f2 -= rate*epsilon[i]*(1-q[i]);
}
// now update the p's and q's
for (int i = 0; i < numChildren; i++) {
p[i] -= rate*epsilon[i]*mDiff;
q[i] -= rate*epsilon[i]*fDiff;
}
在什么情况下Java会产生NaN值?
答案 0 :(得分:35)
NaN
由以下事件触发:
很抱歉这么一般的答案,但我希望有所帮助。
答案 1 :(得分:4)
根据维基百科:
有三种操作返回
NaN
:
- 使用
NaN
作为至少一个操作数的操作- 不确定表格
- 划分0/0,∞/∞,∞/-∞,-∞/∞和-∞/-∞
- 乘法0×∞和0×-∞
- 权力1 ∞
- 加法∞+( - ∞),( - ∞)+∞和等效减法。
- 结果复杂的实际操作:
- 负数的平方根
- 负数的对数
- 90度(或π/ 2弧度)的奇数倍的切线
- 小于-1或大于+1的数字的反正弦或余弦。
这个Java片段说明了上述所有内容,除了切线之外(我怀疑是因为double
的精度有限):
import java.util.*;
import static java.lang.Double.NaN;
import static java.lang.Double.POSITIVE_INFINITY;
import static java.lang.Double.NEGATIVE_INFINITY;
public class NaN {
public static void main(String args[]) {
double[] allNaNs = {
0D/0D,
POSITIVE_INFINITY / POSITIVE_INFINITY,
POSITIVE_INFINITY / NEGATIVE_INFINITY,
NEGATIVE_INFINITY / POSITIVE_INFINITY,
NEGATIVE_INFINITY / NEGATIVE_INFINITY,
0 * POSITIVE_INFINITY,
0 * NEGATIVE_INFINITY,
Math.pow(1, POSITIVE_INFINITY),
POSITIVE_INFINITY + NEGATIVE_INFINITY,
NEGATIVE_INFINITY + POSITIVE_INFINITY,
POSITIVE_INFINITY - POSITIVE_INFINITY,
NEGATIVE_INFINITY - NEGATIVE_INFINITY,
Math.sqrt(-1),
Math.log(-1),
Math.asin(-2),
Math.acos(+2),
};
System.out.println(Arrays.toString(allNaNs));
// prints "[NaN, NaN...]"
System.out.println(NaN == NaN); // prints "false"
System.out.println(Double.isNaN(NaN)); // prints "true"
}
}
如果任一操作数为
NaN
,则==
的结果为false
,但!=
的结果为true
。实际上,当且仅当x!=x
的值为true
时,测试x
为NaN
。 (方法Float.isNaN
和Double.isNaN
也可用于测试值是否为NaN
。)
答案 2 :(得分:3)
鉴于我对梯度下降的了解,你很可能会跳到无穷大,因为你没有自适应rate
(即你的rate
太大了。)
答案 3 :(得分:0)
您是否尝试使用System.out.println
语句填充代码以确定确切 NaN何时开始发生?