【发布时间】:2012-04-11 23:08:21
【问题描述】:
我在神经网络的最后一层使用Softmax 激活函数。但是我在安全实现这个函数时遇到了问题。
一个幼稚的实现是这样的:
Vector y = mlp(x); // output of the neural network without softmax activation function
for(int f = 0; f < y.rows(); f++)
y(f) = exp(y(f));
y /= y.sum();
这不适用于> 100个隐藏节点,因为在许多情况下y将是NaN(如果y(f)> 709,exp(y(f))将返回inf)。我想出了这个版本:
Vector y = mlp(x); // output of the neural network without softmax activation function
for(int f = 0; f < y.rows(); f++)
y(f) = safeExp(y(f), y.rows());
y /= y.sum();
safeExp 定义为
double safeExp(double x, int div)
{
static const double maxX = std::log(std::numeric_limits<double>::max());
const double max = maxX / (double) div;
if(x > max)
x = max;
return std::exp(x);
}
这个函数限制了exp的输入。在大多数情况下,这有效,但并非在所有情况下都有效,我并没有真正设法找出在哪些情况下无效。当我在前一层有 800 个隐藏神经元时,它根本不起作用。
但是,即使这有效,我还是以某种方式“扭曲”了 ANN 的结果。你能想到任何其他方法来计算正确的解决方案吗?是否有任何 C++ 库或技巧可用于计算此 ANN 的准确输出?
编辑: Itamar Katz 提供的解决方案是:
Vector y = mlp(x); // output of the neural network without softmax activation function
double ymax = maximal component of y
for(int f = 0; f < y.rows(); f++)
y(f) = exp(y(f) - ymax);
y /= y.sum();
在数学上确实是一样的。然而,在实践中,由于浮点精度,一些小值变为 0。我想知道为什么没有人在教科书中写下这些实现细节。
【问题讨论】:
-
“我想知道为什么没有人在教科书中写下这些实现细节。”我一直想知道同样的事情!
-
“它在数学上确实是一样的”——进一步阅读,有人说由于数值稳定性,您的方法更受欢迎。:stackoverflow.com/questions/34968722/softmax-function-python
标签: c++ math neural-network softmax