Ускорение Математических вычислений в Java

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

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

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

11
задан Zaid 22 May 2010 в 11:47
поделиться

4 ответа

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

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

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

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


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

21
ответ дан 3 December 2019 в 03:34
поделиться

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

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

1
ответ дан 3 December 2019 в 03:34
поделиться

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

0
ответ дан 3 December 2019 в 03:34
поделиться

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

5
ответ дан 3 December 2019 в 03:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: