2

我正在用 Java 编写一个基本的神经网络,并且正在编写激活函数(目前我刚刚编写了 sigmoid 函数)。我正在尝试使用doubles (与 sBigDecimal相对),希望培训实际上需要合理的时间。但是,我注意到该函数不适用于较大的输入。目前我的功能是:

public static double sigmoid(double t){

    return (1 / (1 + Math.pow(Math.E, -t)));

}

这个函数返回非常精确的值,一直到 when t = -100,但是当t >= 37函数返回时1.0在一个典型的神经网络中,当输入被归一化时这很好吗?神经元会得到总和超过 37 的输入吗?如果输入到激活函数中的输入总和的大小从 NN 到 NN 不同,有哪些因素会影响它?另外,有什么方法可以使这个函数更精确吗?是否有更精确和/或更快的替代方案?

4

2 回答 2

2

令人惊讶的答案是 double 实际上比您需要的更精确。 Pete Warden 的这篇博客文章声称即使是 8 位也足够精确。而不仅仅是一个学术理念:NVidia 的新 Pascal 芯片强调其单精度性能高于一切,因为这对深度学习训练很重要。

你应该标准化你的输入神经元值。如果仍然出现极值,则可以将它们设置为 -1 或 +1。事实上,这个答案明确地表明了这一点。(关于这个问题的其他答案也很有趣——建议只预先计算 100 个左右的值,而不使用Math.exp()或根本不使用Math.pow()!)

于 2016-09-26T08:10:17.313 回答
2

是的,在标准化网络中使用 double 是可以的。但这取决于您的输入,如果您的输入层更大,您的输入总和当然会更大。

我在使用 C++ 时遇到了同样的问题,在 t 变大之后,编译器/rte 甚至不考虑 E^-t 并返回纯 1,因为它只计算 1/1 部分。我试图将已经标准化的输入除以 1000-1000000,它有时会起作用,但有时它不起作用,因为我在第一个时期使用随机输入,而我的输入层是一个 784x784 的矩阵。不过,如果您的输入层很小,并且您的输入已标准化,这将对您有所帮助

于 2016-09-27T11:00:18.650 回答