Ускорение математических вычислений в Java - PullRequest
11 голосов
/ 22 мая 2010

У меня есть нейронная сеть, написанная на Java, которая использует сигмоидальную передаточную функцию, определенную следующим образом:

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

, и это называется много раз во время обучения и вычислений с использованием сети.Есть ли способ ускорить это?Дело не в том, что он медленный, а в том, что он часто используется, поэтому небольшая оптимизация принесла бы большой общий выигрыш.

Ответы [ 4 ]

21 голосов
/ 22 мая 2010

Для нейронных сетей вам не нужно точное значение сигмоидальной функции.Таким образом, вы можете предварительно рассчитать 100 значений и повторно использовать значение, наиболее близкое к вашему входу, или даже лучше (как указано в комментарии) выполнить интерполяцию из соседних значений.

Как вы можете это сделать, описано в этой статье (ссылка, украденная из ответа s-lott ).

Это сигмоидфункция: Sigmoid function graph

Как видите, интересны только значения -10


Редактировать: Извините, что я показал неправильный график здесь.Я исправил это.

5 голосов
/ 22 мая 2010

Если у вас много узлов, где значение 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.

1 голос
/ 22 мая 2010

Это довольно плавная функция, поэтому схема поиска и интерполяции, вероятно, будет более чем достаточной.

Когда я строю график функции в диапазоне -10 <= x <= 10, я получаю пятизначную точность в крайних значениях,Это достаточно хорошо для вашего приложения?

0 голосов
/ 22 мая 2010

С математической точки зрения я не вижу возможности оптимизировать его.

...