Sto utilizzando una funzione di attivazione Softmax nell'ultimo livello di una rete neurale. Ma ho problemi con un'implementazione sicura di questa funzione.Implementazione di una funzione di attivazione softmax per reti neurali
Un'implementazione ingenuo sarebbe questo:
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();
Questo non funziona molto bene per> 100 nodi nascosti perché la y sarà NaN
in molti casi (se y (f)> 709, exp (y (f)) restituirà inf). Sono venuto con questa versione:
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();
dove safeExp
è definito come
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);
}
Questa funzione limita l'ingresso di exp. Nella maggior parte dei casi questo funziona, ma non in tutti i casi e non sono riuscito a scoprire in quali casi non funziona. Quando ho 800 neuroni nascosti nel livello precedente non funziona affatto.
Tuttavia, anche se questo ha funzionato ho in qualche modo "distorto" il risultato della ANN. Riesci a pensare a un altro modo per calcolare la soluzione corretta? Ci sono alcune librerie o trucchi C++ che posso usare per calcolare l'output esatto di questa ANN?
edit: La soluzione fornita da 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();
Ed è proprio matematicamente lo stesso. In pratica, tuttavia, alcuni valori piccoli diventano 0 a causa della precisione in virgola mobile. Mi chiedo perché nessuno scriva mai questi dettagli di implementazione nei libri di testo.
"Mi chiedo perché nessuno scriva mai questi dettagli di implementazione nei libri di testo." Mi sono sempre chiesto la stessa cosa! – pjreddie
"È matematicamente lo stesso" - leggendo ulteriormente, qualcuno dice che il metodo è preferito a causa della stabilità numerica: https://stackoverflow.com/questions/34968722/softmax-function-python – gremwell