mplementação de uma função de ativação softmax para redes neura

Estou usando um Softmax função de ativação na última camada de uma rede neural. Mas tenho problemas com uma implementação segura dessa função.

Uma implementação ingênua seria esta:

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();

Isso não funciona muito bem para> 100 nós ocultos porque y seráNaN em muitos casos (se y (f)> 709, exp (y (f)) retornará inf). Eu vim com esta versão:

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();

OndesafeExp é definido com

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);
}

Esta função limita a entrada de exp. Na maioria dos casos, isso funciona, mas não em todos os casos, e eu realmente não consegui descobrir em quais casos ele não funciona. Quando tenho 800 neurônios ocultos na camada anterior, ele não funcion

No entanto, mesmo que isso funcionasse, de alguma forma "distorci" o resultado da RNA. Você consegue pensar em outra maneira de calcular a solução correta? Existem bibliotecas ou truques em C ++ que eu possa usar para calcular a saída exata dessa RN

editar A solução fornecida por 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();

E é realmente matematicamente o mesmo. Na prática, no entanto, alguns valores pequenos tornam-se 0 por causa da precisão do ponto flutuante. Eu me pergunto por que ninguém nunca escreve esses detalhes de implementação nos livros didático

questionAnswers(4)

yourAnswerToTheQuestion