在研究涉及神经网络的C项目时,我受到NaN结果的阻碍.经过大量的追踪(试图找到NaN的起源)后,我意识到它的来源是我的sigmoid派生函数,如下所示.
double sigDer(double n){
return 2*exp(-n) / pow(1 + exp(-n), 2);
}
虽然它具有所有实数的域,但是诸如-1008.3的值导致NaN的结果.根据mathematica,正确的结果应该非常接近零 – 2.522 * 10 ^ -438.我以下列方式避免了这个问题:
double sigDer(double n){
double res = 2*exp(-n) / pow(1 + exp(-n), 2);
if( isnan(res) ){
return 0;
} else{
return res;
}
}
通过这个简单的假设,我的代码按预期运行;但是,我仍然不明白为什么sigDer(< #with large magnitude>)不会返回〜0.有人可以告诉我有关C(Xcode IDE)中NaN的原因除了除以零并取消负的均匀根吗?
提前致谢!我还想知道为什么签名者(-1008.3)返回NaN以及如何更好/更有效地追踪NaN值的来源.
解决方法:
在每种情况下,分母都试图达到无穷大(这意味着整个分数试图达到0).但是,这意味着你要用无穷大来定义某个除法(结合有限的双倍范围).
这里的解释在于c++ exp function,如果返回值不能表示为double,则返回-HUGE_VAL.
话虽如此,当你的结果不能包含在一个双变量中时,它将导致除以无穷大,从而得到一个纳米
顺便说一句,如果你想操作大数字,你可以实现一个存储数字的类,例如字符串和重载运算符.