【问题标题】:Speeding up Math calculations in Java加速 Java 中的数学计算
【发布时间】:2011-02-22 16:31:04
【问题描述】:

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

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

这在使用网络进行训练和计算期间被调用很多次。有没有办法加快这个速度?不是慢,只是用的比较多,所以这里稍微优化一下,整体收益会很大。

【问题讨论】:

  • x 的值是否曾经重复,或者每次调用方法时它们总是不同的可能性更大?
  • 另外,结果需要多准确?
  • @Dave - 取决于所需的精度,但它们都是浮点数,非常独特
  • 您是否对程序进行了剖析以知道改进它会显着提高整体性能?
  • @Refactor 加快计算速度实际上是 NN 蛋头们的共同话题,所以我发现 StackOverflowish 的这种反应非常幽默:)

标签: java neural-network mathematical-optimization


【解决方案1】:

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

article 中描述了如何做到这一点(链接从answer of s-lott 被盗)。

这是sigmoid函数:

如您所见,只有 -10


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

【讨论】:

  • 如果您想要更精确一点,可能会超过 100 个。恕我直言,一个包含 5000 个(但可能甚至是 1000 个)值的查找表就足够了。
  • 为了更精确,最好在最接近的两个值之间进行线性插值。
  • 问题是对称的,所以你只需要一半的值。计算对方是微不足道的。
  • 这是一个完全不同的函数图。 erf(x) 很难计算,exp(x) 不是。
  • @Ha:不错的收获。这看起来像双极 sigmoid 函数。 OP 中的 sigmoid 函数具有水平渐近线 0 和 1。
【解决方案2】:

如果您有很多节点 x 的值在 -10..+10 框之外,您可以完全省略计算这些值,例如,像这样..

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

当然,这会导致每次计算的条件检查的开销,所以只有当你有很多饱和节点时才值得。

另一件值得一提的是,如果您使用反向传播,并且您必须处理函数的斜率,那么最好分段计算而不是“按原样”计算。

我现在不记得斜率了,但这里是我所说的,以双极 sigmoid 为例。而不是这样计算

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

点击 exp() 两次,你可以将代价高昂的计算缓存在临时变量中,就像这样

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

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

【讨论】:

    【解决方案3】:

    这是一个非常平滑的函数,因此查找和插值方案可能绰绰有余。

    当我在-10 &lt;= x &lt;= 10 的范围内绘制函数时,我在极端情况下获得了五位精度。这对您的应用程序是否足够好?

    【讨论】:

      【解决方案4】:

      从数学的角度来看,我认为没有任何优化的可能性。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-07-22
        • 1970-01-01
        • 2021-01-19
        • 1970-01-01
        • 1970-01-01
        • 2011-11-07
        相关资源
        最近更新 更多