torch.nn.BCEWithLogitsLoss用法介绍

self.bce = nn.BCEWithLogitsLoss(reduction='none'), None的使用方法可以见官网pytorch代码文档
BCELoss
代码举例

import torch
a = torch.rand((1, 3, 3))
target = torch.tensor([[[1, 0, 0],
                        [0, 1, 0],
                        [0, 0, 0]]])
print(a)
'''
ouput:tensor([[[0.2070, 0.8432, 0.2494],
         [0.5782, 0.4587, 0.1135],
         [0.9794, 0.8516, 0.4418]]])
'''
b = torch.nn.BCEWithLogitsLoss(reduction='none')(a, target.to(a.dtype))
print(b)
'''
output: tensor([[[0.5950, 1.2011, 0.8256],
         [1.0234, 0.4899, 0.7515],
         [1.2982, 1.2070, 0.9383]]])
'''
c = torch.nn.BCEWithLogitsLoss(reduction='mean')(a, target.to(a.dtype))
print(c)
'''
output:tensor(0.9256)
'''
d = torch.nn.BCEWithLogitsLoss(reduction='sum')(a, target.to(a.dtype))
print(d)
'''
output:tensor(8.3301)
'''

举例的代码中target中的计算方法是这样的(resuction='none')

对于target[0][0][0]=1=yn, a[0][0][0]=0.2070=xn, 因此,对于ln

0.5950 = − ( 1 × ln ⁡ σ ( 0.2070 ) + 0 × ln ⁡ ( 1 − σ ( 0.2070 ) ) ) 0.5950 = -\left ( 1 \times \ln{\sigma\left ( 0.2070 \right ) } + 0 \times\ln{ \left ( 1 - \sigma \left ( 0.2070\right ) \right ) } \right ) 0.5950=(1×lnσ(0.2070)+0×ln(1σ(0.2070)))
对于target[0][0][1]=0=yn, a[0][0][1]=0.8432=xn, 因此,对于ln
1.2011 = − ( 0 × ln ⁡ σ ( 0.8432 ) + 1 × ln ⁡ ( 1 − σ ( 0.8432 ) ) ) 1.2011= -\left ( 0 \times \ln{\sigma\left ( 0.8432\right ) } + 1 \times\ln{ \left ( 1 - \sigma \left ( 0.8432\right ) \right ) } \right ) 1.2011=(0×lnσ(0.8432)+1×ln(1σ(0.8432)))

其中 σ \sigma σ是Sigmoid函数, 以此类推, 可以最终得到output: tensor([[[0.5950, 1.2011, 0.8256],[1.0234, 0.4899, 0.7515],[1.2982, 1.2070, 0.9383]]]), 如果reduction=‘mean’的时候, 就是reduction=‘none’的output求平均值, 最终可以得到output:tensor(0.9256),如果reduction='sum',那就是reduction=‘none’的output求和,最终可以得到output:tensor(8.3301)

可以验证一下上面的代码,可以看到结果是一样的

a = torch.tensor([[[0.2070, 0.8432, 0.2494],
                   [0.5782, 0.4587, 0.1135],
                   [0.9794, 0.8516, 0.4418]]])
target = torch.tensor([[[1, 0, 0],
                        [0, 1, 0],
                        [0, 0, 0]]])
sa = torch.nn.Sigmoid()(a)
result = -(target * torch.log(sa) + (1 - target) * torch.log(1 - sa))
'''
output: tensor([[[0.5950, 1.2011, 0.8256],
         [1.0235, 0.4899, 0.7515],
         [1.2982, 1.2070, 0.9382]]])
'''
result_mean = result.mean()
'''
output: tensor(0.9256)
'''
result_sum = result.sum()
'''
output: tensor(8.3300)
'''

如果是bs = 2,reduction='mean'reduction='sum'的效果也是一样的,最终的结果也是一个值。代码如下, 可以看到均值不变, 求和的时候扩大2倍

import torch
# a = torch.rand((1, 3, 3))
a = torch.tensor([[[0.2070, 0.8432, 0.2494],
         [0.5782, 0.4587, 0.1135],
         [0.9794, 0.8516, 0.4418]], 
         [[0.2070, 0.8432, 0.2494],
         [0.5782, 0.4587, 0.1135],
         [0.9794, 0.8516, 0.4418]]])
target = torch.tensor([[[1, 0, 0],
                        [0, 1, 0],
                        [0, 0, 0]],
                        [[1, 0, 0],
                        [0, 1, 0],
                        [0, 0, 0]]])

b = torch.nn.BCEWithLogitsLoss(reduction='none')(a, target.to(a.dtype))
print(b)
'''
output: tensor([[[0.5950, 1.2011, 0.8256],
                 [1.0235, 0.4899, 0.7515],
                 [1.2982, 1.2070, 0.9382]],

		        [[0.5950, 1.2011, 0.8256],
		         [1.0235, 0.4899, 0.7515],
		         [1.2982, 1.2070, 0.9382]]])
'''

c = torch.nn.BCEWithLogitsLoss(reduction='mean')(a, target.to(a.dtype))
print(c)
'''
output: tensor(0.9256)
'''

d = torch.nn.BCEWithLogitsLoss(reduction='sum')(a, target.to(a.dtype))
print(d)
'''
output: tensor(16.6601)
'''

sa = torch.nn.Sigmoid()(a)
result = -(target * torch.log(sa) + (1 - target) * torch.log(1 - sa))
print(result)
'''
output: tensor([[[0.5950, 1.2011, 0.8256],
		         [1.0235, 0.4899, 0.7515],
		         [1.2982, 1.2070, 0.9382]],

		        [[0.5950, 1.2011, 0.8256],
		         [1.0235, 0.4899, 0.7515],
		         [1.2982, 1.2070, 0.9382]]])
'''

result_mean = result.mean()
'''
output: tensor(0.9256)
'''
result_sum = result.sum()
'''
output: tensor(16.6601)
'''
  • 25
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我将为您提供一个从零开始实现 logistic 回归的示例代码,并使用人工构造的数据集进行训练和测试。 首先,我们需要导入必要的库: ```python import numpy as np import torch import torch.nn as nn from sklearn.model_selection import train_test_split ``` 然后,我们定义 logistic 回归模型的类: ```python class LogisticRegression: def __init__(self, input_dim): self.weights = torch.zeros((input_dim, 1), dtype=torch.float32) self.bias = torch.zeros(1, dtype=torch.float32) def forward(self, X): linear = torch.matmul(X, self.weights) + self.bias return torch.sigmoid(linear) def backward(self, X, y, y_pred, lr): m = X.shape[0] grad_weights = torch.matmul(X.t(), (y_pred - y)) / m grad_bias = torch.sum(y_pred - y) / m self.weights -= lr * grad_weights self.bias -= lr * grad_bias def train(self, X, y, lr, num_epochs): for epoch in range(num_epochs): y_pred = self.forward(X) self.backward(X, y, y_pred, lr) def predict(self, X): y_pred = self.forward(X) return (y_pred >= 0.5).float() ``` 接下来,我们创建一个人工构造的数据集,并进行训练和测试: ```python # 生成数据集 np.random.seed(42) X = np.random.randn(1000, 2) y = np.random.randint(0, 2, (1000, 1)) # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) # 转换为PyTorch的Tensor X_train = torch.from_numpy(X_train).float() y_train = torch.from_numpy(y_train).float() X_test = torch.from_numpy(X_test).float() y_test = torch.from_numpy(y_test).float() # 创建模型实例并训练 model = LogisticRegression(input_dim=2) model.train(X_train, y_train, lr=0.01, num_epochs=100) # 在训练集和测试集上进行预测 train_preds = model.predict(X_train) test_preds = model.predict(X_test) # 计算准确率 train_acc = (train_preds == y_train).sum().item() / len(y_train) test_acc = (test_preds == y_test).sum().item() / len(y_test) print("训练集准确率:", train_acc) print("测试集准确率:", test_acc) ``` 在上述代码中,我们首先生成了一个包含1000个样本和2个特征的人工数据集。然后,使用`train_test_split`函数将数据集划分为训练集和测试集。接下来,我们将数据转换为PyTorch的Tensor,并创建一个 logistic 回归模型的实例。通过调用模型的`train`方法,可以在训练集上进行模型训练。最后,我们使用训练好的模型在训练集和测试集上进行预测,并计算准确率。 请注意,上述代码中的 logistic 回归模型是简化版本,仅包含了前向传播和反向传播的基本实现。对于更复杂的任务,您可能需要添加更多功能,如正则化、批量梯度下降等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值