我目前有兩個 Torch Tensorp和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 個 for 回圈?我正在嘗試盡可能多地矢量化此操作。我可以發誓我們之前可以使用 LaTeX 來計算方程,做了什么改變還是另一個網站?
uj5u.com熱心網友回復:
雖然不是一個好的做法,但您可以直接在張量上使用公式如下(有效,因為這些是元素明智的操作):
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 計算為loss,因此它會在您的公式前面加上一個負號。該屬性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
請隨時要求進一步說明。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/368454.html
