1 损失函数概念
损失函数(loss function)是用来估量模型的预测值f(x)与真实值Y的不一致程度,它是一个非负实值函数,通常使用L(Y, f(x))来表示,损失函数越小,模型的鲁棒性就越好。
无论网络怎么定义,最终要做一件什么事,完全由损失函数决定的,损失函数决定了一个函数的走向
2 PyTorch安装
到PyTorch官方下载界面,提示建议使用Anaconda进行安装
所以选择以下几个安装包,若没有CUDA则还需安装CUDA
打开Windos的DOS窗口执行以下命令
conda install pytorch torchvision torchaudio cudatoolkit=11.6 -c pytorch -c conda-forge
查看pytorch的版本,安装成功
3 BCELOSS类实现的损失函数计算原理
查看PyTorch官方文档BCELLOS类,官方文档给出的损失函数是这样定义的
其中:
- x:代表预测值,范围取(0,1)之间的某个值,注意两边都是开区间
- y:代表真实值,只能取0或1
- reduction: 有两种reduction方式,取平均值或求和
根据官方文档的公式可以手动写代码实现一遍,看是否与官方的结果相同
4 代码实现BCELOSS类的损失函数的计算
4.1 导入需要的包
import torch
from torch import autograd
from torch import nn
import math
4.2 随机设置一组输入
input = autograd.Variable(torch.tensor([[ 1.9072, 1.1079, 1.4906],
[-0.6584, -0.0512, 0.7608],
[-0.0614, 0.6583, 0.1095]]), requires_grad=True)
print(input)
tensor([[ 1.9072, 1.1079, 1.4906],
[-0.6584, -0.0512, 0.7608],
[-0.0614, 0.6583, 0.1095]], requires_grad=True)
4.3 构造Sigmoid类型的对象将输入转变成0-1的范围,作为预测值
m = nn.Sigmoid()
print(m(input))
tensor([[0.8707, 0.7517, 0.8162],
[0.3411, 0.4872, 0.6815],
[0.4847, 0.6589, 0.5273]], grad_fn=<SigmoidBackward0>)
4.4 构建一个标签,作为真实值
target = torch.FloatTensor([[0, 1, 1], [1, 1, 1], [0, 0, 0]])
print(target)
tensor([[0., 1., 1.],
[1., 1., 1.],
[0., 0., 0.]])
4.5 根据官方提供的损失函数计算公式计算结果
r11 = 0 * math.log(0.8707) + (1-0) * math.log((1 - 0.8707))
r12 = 1 * math.log(0.7517) + (1-1) * math.log((1 - 0.7517))
r13 = 1 * math.log(0.8162) + (1-1) * math.log((1 - 0.8162))
r21 = 1 * math.log(0.3411) + (1-1) * math.log((1 - 0.3411))
r22 = 1 * math.log(0.4872) + (1-1) * math.log((1 - 0.4872))
r23 = 1 * math.log(0.6815) + (1-1) * math.log((1 - 0.6815))
r31 = 0 * math.log(0.4847) + (1-0) * math.log((1 - 0.4847))
r32 = 0 * math.log(0.6589) + (1-0) * math.log((1 - 0.6589))
r33 = 0 * math.log(0.5273) + (1-0) * math.log((1 - 0.5273))
bceloss = -(r11 + r12 + r13 + r21 + r22 + r23 + r31 + r32 + r33)/9
print(bceloss)
0.8000147727101611
4.6 使用PyTorch的nn模块下BCElOSS类计算结果
loss = nn.BCELoss()
print(loss(m(input), target))
tensor(0.8000, grad_fn=<BinaryCrossEntropyBackward0>) 结果与上面手动计算的结果一致