Код: Выделить всё
IEnumerable SoftMax(IEnumerable vector)
{
var exps = vector.Select(v => Math.Exp(v));
var sumExps = exps.Sum();
return exps.Select(exp => exp / sumExps);
}
Однако почти во всех случаях возвращается значение, которое немного больше или немного меньше 1. Обычно это что-то вроде 1.0568102998178908 или 0.9758570985704772.
Я слышал, что это не редкость (по сути, это проблема переполнения), и ее можно исправить вычитанием самый большой элемент входных данных значения, передаваемого в Math.Exp(). Итак, я придумал эту реализацию на основе предложений:
Код: Выделить всё
IEnumerable SoftMax(IEnumerable vector)
{
var maxVal = vector.Max();
var exps = vector.Select(v => Math.Exp(v - maxVal));
var sumExps = exps.Sum();
return exps.Select(exp => exp / sumExps);
}
Код: Выделить всё
IEnumerable vector = Enumerable.Range(0, 100).Select(n => new Random().NextDouble());
var softMaxVec = SoftMax(vector);
Console.WriteLine(softMaxVec.Sum());
Подробнее здесь: https://stackoverflow.com/questions/793 ... ementation
Мобильная версия