Избегайте бесконечности в этом расчете numpy logsumexp

Следуя ошибка значения: истинное значение неоднозначно, я редактирую функцию logsumexp отсюда: https://github.com/scipy/scipy/blob/v0.14.0/scipy/misc/common.py#L18

Причина в том, что: 1. Я хочу сам выбрать максимальное значение, это не всегда только максимум массива 2. Я хочу поставить условие, чтобы разница после вычитания максимума из каждого элемента не опускалась ниже определенный порог.

Это мой последний код. В этом нет ничего плохого, за исключением того, что иногда он все еще возвращает бесконечность!

def mylogsumexp(self, a, is_class, maxaj=None, axis=None, b=None):
        threshold = -sys.float_info.max         
        a = asarray(a)
        if axis is None:
            a = a.ravel()
        else:
            a = rollaxis(a, axis)

        if is_class == 1:
            a_max = a.max(axis=0)
        else:
            a_max = maxaj  
        if b is not None:
            b = asarray(b)
            if axis is None:
                b = b.ravel()
            else:
                b = rollaxis(b, axis)
            #out = log(sum(b * exp(threshold if a - a_max < threshold else a - a_max), axis=0))
            out = np.log(np.sum(b * np.exp( np.minimum(a - a_max, threshold)), axis=0))

        else:
            out = np.log(np.sum(np.exp( np.minimum(a - a_max, threshold)), axis=0))
        out += a_max

person user961627    schedule 04.09.2014    source источник


Ответы (1)


Вы можете использовать np.clip для ограничения максимального и минимального значений массива:

>>> arr = np.arange(10)
>>> np.clip(arr, 3, 7)
array([3, 3, 3, 3, 4, 5, 6, 7, 7, 7])

В этом примере значения больше 7 ограничиваются 7; значения меньше 3 устанавливаются равными 3.

Если я правильно интерпретировал ваш код, вы можете заменить

out = np.log(np.sum(b * np.exp( np.minimum(a - a_max, threshold)), axis=0))

с

out = np.log(np.sum(b * np.exp( np.clip(a - a_max, threshold, maximum)), axis=0))

где maximum — желаемое максимальное значение.

person Alex Riley    schedule 04.09.2014
comment
вы имеете в виду вместо np.minimum()? - person user961627; 04.09.2014
comment
@ user961627 да - я отредактировал свой ответ, включив в него возможное решение. - person Alex Riley; 04.09.2014
comment
Я установил threshold и maxthreshold на -sys.float_info.max, а sys.float_info.max получил эту ошибку: out = np.log(np.sum(b * np.exp( np.clip(a - a_max, threshold, maxthreshold)), axis=0)) TypeError: unsupported operand type(s) for -: 'float' and 'NoneType' - person user961627; 04.09.2014
comment
Похоже, что некоторые элементы массива a могут быть None. Вы можете отфильтровать эти элементы из массива? - person Alex Riley; 04.09.2014