加快 Java 中的数学计算速度

我有一个用Java编写的神经网络,它使用定义如下的sigmoid传递函数:

private static double sigmoid(double x)
{
    return 1 / (1 + Math.exp(-x));
}

这在使用网络的训练和计算过程中被多次调用。有什么办法可以加快速度吗?这并不是说它很慢,只是它被大量使用,所以在这里进行一个小的优化将是一个很大的整体收益。


答案 1

对于神经网络,您不需要 sigmoid 函数的确切值。因此,您可以预先计算 100 个值并重用最接近输入的值,或者更好的(如注释所述)从相邻值进行插值。

如何做到这一点在本文中进行了描述(从s-lott的答案中窃取的链接)。

这是 sigmoid 函数:Sigmoid function graph

如您所见,只有 -10 < x < 10 的值才有趣。而且,正如另一条评论所述,该函数是对称的。您只需要存储一半的值。


编辑:很抱歉,我在这里显示了错误的图表。我已经纠正了它。


答案 2

如果您有很多节点,其中x的值位于-10..+10框之外,则可以省略以计算这些值,例如,例如..

if( x < -10 )
    y = 0;
else if( x > 10 )
    y = 1;
else
    y = 1 / (1 + Math.exp(-x));
return y;

当然,这会产生每次计算的条件检查开销,因此只有在您有很多饱和节点时才值得。

另一件值得一提的事情是,如果你正在使用反向传播,并且你必须处理函数的斜率,那么最好是分段计算它,而不是“写”。

我现在不记得斜坡了,但这就是我所说的使用双极乙状结肠作为例子。而不是以这种方式计算

y = (1 - exp(-x)) / (1 + exp(-x));

命中 exp() 两次,您可以将昂贵的计算缓存在临时变量中,就像这样

temp = exp(-x);
y = (1 - temp) / (1 + temp);

有很多地方可以把这种东西用在BP网中。


推荐