Как обращаться с log (0) при использовании кросс-энтропии - PullRequest
0 голосов
/ 25 апреля 2018

Чтобы сделать случай простым и интуитивно понятным, я буду использовать двоичную (0 и 1) классификацию для иллюстрации.

Функция потери

loss = np.multiply(np.log(predY), Y) + np.multiply((1 - Y), np.log(1 - predY)) #cross entropy
cost = -np.sum(loss)/m #num of examples in batch is m

Вероятность Y

predY вычисляется с использованием сигмоида, и logits может рассматриваться как результат от нейронной сети до достижения этапа классификации

predY = sigmoid(logits) #binary case

def sigmoid(X):
    return 1/(1 + np.exp(-X))

Задача

Предположим, у нас есть прямая сеть.

Входные данные: [3, 5]: 3 - это число примеров, а 5 - размер объекта (изготовленные данные)

Количество скрытых юнитов: 100 (только 1 скрытый слой)

итераций: 10000

Такое расположение подходит для снаряжения. Когда это подходит, мы можем точно предсказать вероятность для обучающих примеров; другими словами, сигмоид выводит 1 или 0, точное число, потому что экспонента взорвана. Если это так, у нас будет np.log(0) undefined . Как вы обычно решаете эту проблему?

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Один из распространенных способов справиться с log (x) и y / x, где x всегда неотрицателен, но может стать 0, - добавить небольшую константу (как написано Jakub).

Вы также можете обрезать значение (например, tf.clip_by_value или np.clip).

0 голосов
/ 25 апреля 2018

Если вы не против зависимости от scipy, вы можете использовать scipy.special.xlogy. Вы бы заменили выражение

np.multiply(np.log(predY), Y) + np.multiply((1 - Y), np.log(1 - predY))

с

xlogy(Y, predY) + xlogy(1 - Y, 1 - predY)

Если вы ожидаете, что predY будет содержать очень малые значения, вы можете получить лучшие числовые результаты, используя scipy.special.xlog1py во втором члене:

xlogy(Y, predY) + xlog1py(1 - Y, -predY)

В качестве альтернативы, зная, что значения в Y равны 0 или 1, вы можете вычислить стоимость совершенно другим способом:

Yis1 = Y == 1
cost = -(np.log(predY[Yis1]).sum() + np.log(1 - predY[~Yis1]).sum())/m
0 голосов
/ 25 апреля 2018

Как вы обычно решаете эту проблему?

Добавьте небольшое число (что-то вроде 1e-15) к predY - это число не делает много предсказаний, и оно решает проблему log (0).

Кстати, если ваш алгоритм выводит нули и единицы, может быть полезно проверить гистограмму возвращаемых вероятностей - когда алгоритм настолько уверен, что что-то происходит, это может быть признаком переобучения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...