RuntimeWarning: недопустимое значение, встречающееся в большем

Я попытался реализовать soft-max со следующим кодом (out_vec является вектором float numpy):

numerator = np.exp(out_vec)
denominator = np.sum(np.exp(out_vec))
out_vec = numerator/denominator

Однако, я получил ошибку переполнения из-за np.exp(out_vec). Поэтому я проверил (вручную), каков верхний предел np.exp(), и обнаружил, что np.exp(709) является числом, но np.exp(710) считается np.inf. Таким образом, чтобы избежать ошибки переполнения, я изменил свой код следующим образом:

out_vec[out_vec > 709] = 709 #prevent np.exp overflow
numerator = np.exp(out_vec)
denominator = np.sum(np.exp(out_vec))
out_vec = numerator/denominator

Теперь я получаю другую ошибку:

RuntimeWarning: invalid value encountered in greater out_vec[out_vec > 709] = 709

Что случилось с линией, которую я добавил? Я просмотрел эту конкретную ошибку, и все, что я нашел, это советы людей о том, как игнорировать ошибку. Просто игнорирование ошибки не поможет мне, потому что каждый раз, когда мой код сталкивается с этой ошибкой, он не дает обычных результатов.

Ответ 1

Ваша проблема вызвана элементами NaN или Inf в вашем массиве out_vec. Вы можете использовать следующий код, чтобы избежать этой проблемы:

if np.isnan(np.sum(out_vec)):
    out_vec = out_vec[~numpy.isnan(out_vec)] # just remove nan elements from vector
out_vec[out_vec > 709] = 709
...

или вы можете использовать следующий код, чтобы оставить значения NaN в своем массиве:

out_vec[ np.array([e > 709 if ~np.isnan(e) else False for e in out_vec], dtype=bool) ] = 709

Ответ 2

IMO, лучшим способом было бы использовать более численно стабильную реализацию суммы экспонент.

from scipy.misc import logsumexp
out_vec = np.exp(out_vec - logsumexp(out_vec))

Ответ 3

В моем случае предупреждение не отображалось при вызове этого перед сравнением (у меня были сопоставлены значения NaN)

np.warnings.filterwarnings('ignore')