Pytorch:二元分类的损失函数

数据挖掘 损失函数 火炬
2022-03-07 22:43:07

Pytorch 和神经网络世界的新手。下面是使用简单的 3 层网络完成的二进制分类的代码片段:

n_input_dim = X_train.shape[1]
n_hidden = 100  # Number of hidden nodes
n_output = 1   # Number of output nodes = for binary classifier
# Build the network
model = nn.Sequential(
    nn.Linear(n_input_dim, n_hidden),
    nn.ELU(),
    nn.Linear(n_hidden, n_output),
    nn.Sigmoid())

x_tensor =  torch.from_numpy(X_train.values).float()
tensor([[ -1.0000,  -1.0000,  -1.0000,  ..., -99.0000, -99.0000, -99.0000],
       [ -1.0000,  -1.0000,  -1.0000,  ...,   0.1538,   5.0000,   0.1538],
       [ -1.0000,  -1.0000,  -1.0000,  ..., -99.0000,   6.0000,   0.2381],
       ...,
       [ -1.0000,  -1.0000,  -1.0000,  ..., -99.0000, -99.0000, -99.0000],
       [ -1.0000,  -1.0000,  -1.0000,  ..., -99.0000, -99.0000, -99.0000],
       [ -1.0000,  -1.0000,  -1.0000,  ..., -99.0000, -99.0000, -99.0000]])
y_tensor =  torch.from_numpy(Y_train).float()
tensor([0., 0., 1.,  ..., 0., 0., 0.])
#Loss Computation
loss_func = nn.BCELoss()
#Optimizer
learning_rate = 0.0001
optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)

train_loss = []
iters = 500
for i in range(iters):
    y_pred = model(x_tensor)
    loss = loss_func(y_pred, y_tensor)
    print " Loss in iteration :"
    print (i, loss.item())

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    train_loss.append(loss.item())

在上述情况下,我不确定损失是在 y_pred 上计算的,它是一组概率,是从使用 y_tensor(二进制 0/1)的训练数据上的模型计算得出的。在pytorch的分类问题中,这种损失计算方式好吗?不应该在理想的两个概率之间计算损失吗?如果这没问题,那么这里的损失函数 BCELoss 会以某种方式缩放输入吗?

对此的任何见解将不胜感激

2个回答

关于交叉熵是在 2 个分布之间计算的事实,您是对的,但是,在 y_tensor 值的情况下,我们确定该示例实际上应该属于哪个类,哪个是基本事实。因此,您可以将二进制值视为可能类的概率分布,在这种情况下,损失函数是绝对正确的,也是解决问题的方法。希望有帮助。

除了@Sajid Ahmed 给出的答案之外,您还可以从PyTorch 文档中看到它确实可以正常工作。他们提供的例子是:

import torch
import torch.nn as nn
m = nn.Sigmoid()
loss = nn.BCELoss()
input = torch.randn(3, requires_grad=True)
target = torch.empty(3).random_(2)
output = loss(m(input), target)
output.backward()

为此

print("input: \t\t{}".format(input))
print("m(input): \t{}".format(m(input)))
print("target: \t{}".format(target))
print("output: \t{}".format(output))

给出以下输出:

input:      tensor([ 1.3313,  1.2612,  0.3466])
m(input):   tensor([ 0.7911,  0.7792,  0.5858])
target:     tensor([ 0.,  1.,  1.])
output:     0.7833071351051331

如您所见,它可以按需要工作。