Реализация функции softmax возвращает nan для высоких входов - PullRequest
0 голосов
/ 26 февраля 2019

enter image description here

Я пытаюсь реализовать softmax в конце cnn. Вывод, который я получил, - это нули и нули.Я даю высокие входные значения для softmax около 10-20k. Я даю массив X=[2345,3456,6543,-6789,-9234]

Моя функция

def softmax (X):
    B=np.exp(X)
    C=np.sum(np.exp(X))
    return B/C

Я получаю ошибку true divide and run time error

C:\Anaconda\envs\deep_learning\lib\site-packages\ipykernel_launcher.py:4: RuntimeWarning: invalid value encountered in true_divide
  after removing the cwd from sys.path.

Ответы [ 3 ]

0 голосов
/ 26 февраля 2019

В случае применения softmax для больших чисел, вы можете попробовать использовать max нормализация :

import numpy as np

def softmax (x):
    B=np.exp(x)
    C=np.sum(np.exp(x))
    return B/C

arr = np.array([1,2,3,4,5])

softmax(arr)
# array([0.01165623, 0.03168492, 0.08612854, 0.23412166, 0.63640865])

softmax(arr - max(arr))
# array([0.01165623, 0.03168492, 0.08612854, 0.23412166, 0.63640865])

Как видите, это не влияет на результат softmax.Применяя это к вашему softmax:

def softmax(x):
    B = np.exp(x - max(x))
    C = np.sum(B)
    return B/C
op_arr = np.array([2345,3456,6543,-6789,-9234])
softmax(op_arr)
# array([0., 0., 1., 0., 0.])
0 голосов
/ 26 февраля 2019

Согласно функции softmax , вам нужно выполнить итерацию всех элементов в массиве и вычислить экспоненту для каждого отдельного элемента, а затем разделить ее на сумму экспонент всех элементов:

import numpy as np

a = [1,3,5]
for i in a:
    print np.exp(i)/np.sum(np.exp(a))

0.015876239976466765
0.11731042782619837
0.8668133321973349

Однако, если числа слишком велики, показатели, вероятно, взорвутся (компьютер не может обработать такие большие числа):

a = [2345,3456,6543]
for i in a:
    print np.exp(i)/np.sum(np.exp(a))

__main__:2: RuntimeWarning: invalid value encountered in double_scalars
nan
nan
nan

Чтобы избежать этого, сначала сдвиньте самое высокое значение в массиве на ноль .Затем вычислите softmax.Например, для вычисления softmax [1, 3, 5] используйте [1-5, 3-5, 5-5], который равен [-4, -2, 0].Также вы можете выбрать его векторизацию (как вы собираетесь делать в вопросе):

def softmax(x):
    f = np.exp(x - np.max(x))  # shift values
    return f / f.sum(axis=0)

softmax([1,3,5])
# prints: array([0.01587624, 0.11731043, 0.86681333])

softmax([2345,3456,6543,-6789,-9234])
# prints: array([0., 0., 1., 0., 0.])

Для получения подробной информации посетите страницу курса cs231n . Практические вопросы: стабильность чисел. заголовок - это именно то, что я пытаюсь объяснить.

0 голосов
/ 26 февраля 2019

Когда я запускаю тот же код, я получаю:

RuntimeWarning: overflow encountered in exp
RuntimeWarning: overflow encountered in exp
RuntimeWarning: invalid value encountered in true_divide

Это не очень удивительно, поскольку e^(6543) составляет около 0.39 * 10^2842, вероятно, вызывая переполнение в следующих операциях.

Для этого: нормализуйте данные перед тем, как передать их в softmax: вы могли бы разделить их на 1000, прежде чем передать их в softmax, чтобы вместо ввода в [-20000,20000] вы имели входные данные как плавающие в [-20, 20].

...