Есть ли способ оптимизировать вычисление логарифмических вероятностей Бернулли для многих многомерных выборок?

0

Вопрос

В настоящее время у меня есть два тензора факелов, p и x, которые оба имеют форму (batch_size, input_size).

Я хотел бы рассчитать вероятность логарифма Бернулли для заданных данных и вернуть тензор размера (batch_size)

Вот пример того, что я хотел бы сделать: У меня есть формула для логарифмических вероятностей случайных величин Бернулли:

\sum_i^d x_{i} ln(p_i) + (1-x_i) ln (1-p_i)

Скажи, что у меня есть p Тензор: [[0.6 0.4 0], [0.33 0.34 0.33]] И скажи, что у меня есть x тензор для двоичных входных данных, основанный на этих вероятностях:

[[1 1 0], [0 1 1]]

И я хочу рассчитать логарифмическую вероятность для каждой выборки, что приведет к:

[[ln(0.6)+ln(0.4)], [ln(0.67)+ln(0.34)+ln(0.33)]]

Можно ли было бы выполнить это вычисление без использования циклов for? Я знаю, что мог бы использовать torch.sum(axis=1) чтобы выполнить окончательное суммирование между журналами, но возможно ли выполнить вычисление логарифмической вероятности Бернулли без использования циклов for? или используйте не более 1 для цикла? Я пытаюсь максимально векторизовать эту операцию. Я мог бы поклясться, что мы могли бы использовать латекс для уравнений раньше, что-то изменилось или это другой веб-сайт?

log-likelihood math pytorch
2021-11-24 00:17:07
1

Лучший ответ

1

Хотя это не очень хорошая практика, вы можете напрямую использовать формулу для тензоров следующим образом (работает, потому что это операции с элементами).:

import torch
p = torch.tensor([
    [0.6, 0.4, 0],
    [0.33, 0.34, 0.33]
])

x = torch.tensor([
    [1., 1, 0],
    [0, 1, 1]
])

eps = 1e-8
bll1 = (x * torch.log(p+eps) + (1-x) * torch.log(1-p+eps)).sum(axis=1)
print(bll1)
#tensor([-1.4271162748, -2.5879497528])

Обратите внимание, что во избежание log(0) ошибка, я ввел очень маленькую константу eps внутри него.

Лучший способ сделать это-использовать BCELoss внутри nn модуль в pytorch.

import torch.nn as nn
bce = nn.BCELoss(reduction='none')
bll2 = -bce(p, x).sum(axis=1)
print(bll2)
#tensor([-1.4271162748, -2.5879497528])

С pytorch вычисляет BCE как убыток, он добавляет к вашей формуле отрицательный знак. Атрибут reduction='none' говорит, что я никоим образом не хочу, чтобы вычисленные потери были уменьшены (усреднены/суммированы) по всей партии. Это рекомендуется использовать, так как нам не нужно вручную заботиться о числовой стабильности и обработке ошибок (например, добавлять eps выше.)

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

torch.allclose(bll1, bll2)
# True

или тензоры (без суммирования каждой строки):

torch.allclose((x * torch.log(p+eps) + (1-x) * torch.log(1-p+eps)), -bce(p, x))
# True

Не стесняйтесь обращаться за дальнейшими разъяснениями.

2021-11-25 03:42:35

На других языках

Эта страница на других языках

Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................