。但是我对这个函数的安全实现有问题。神经网络的softmax激活功能的实现我在神经网络的最后一层使用了激活功能<a href="http://en.wikipedia.org/wiki/Softmax_activation_function" rel="nofollow noreferrer">Softmax</a>
一个天真的实施将是这一个:
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个隐藏的神经元时,它根本不起作用。
然而,即使这个工作我不知怎的“扭曲”的人工神经网络的结果。你能想出任何其他方式来计算正确的解决方案吗?是否有任何C++库或技巧可用于计算此ANN的确切输出?
编辑:由伊塔马尔·卡茨提供的解决方案是:
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。我想知道为什么没有人将这些实现细节写在教科书中。
“我想知道为什么没有人将这些实现细节写入教科书。” 我一直想知道同样的事情! – pjreddie 2014-01-28 21:03:34
“它确实在数学上是一样的” - 进一步阅读,有人说你的方法是首选的,因为数值稳定性:https://stackoverflow.com/questions/34968722/softmax-function-python – gremwell 2017-06-19 05:57:02