pytorch的损失函数和优化器

1. 损失函数

pytorch的损失函数可以调用torch.nn.functional库中的函数,通过传入神经网络预测值和目标值来计算损失函数;也可以使用torch.nn中的模块,新建一个模块实例,通过调用相关的模块计算最终的损失函数。
训练数据一般是以迷你批次的形式输入神经网络,最后预测的值也是迷你批次的形式输出,但实际上损失函数的输出结果应该是一个标量张量。所以,对于迷你批次的归约,一种方法是对迷你批次的损失函数求和,另一种是对迷你批次的损失函数求平均。一般默认的是对迷你批次的损失函数求平均。
对于回归问题,一般情况下使用的是torch.nn.MSELoss模块,即平方损失函数,可以指定参数reduction=‘none’, 如果求和,可以指定参数reduction=‘sum’,在实例中传入神经网络预测的值和目标值,就可以计算最终的损失函数值。
对于二分类问题,可以使用交叉熵损失函数torch.nn.BCELoss模块实现。该函数一般是输入Sigmoid函数的输出,且需要输入两个张量,第一个张量是正分类标签的概率值,第二个张量是以0为负分类标签、1为正分类标签的目标数据值
对于多分类问题,可以使用负对数似然函数torch.nn.NLLLoss模块。该损失函数的计算过程是,根据预测值(经过Softmax的计算和对数计算)和目标值(使用度热编码)计算这两个值按照元素一一对应的乘积,然后对乘积求和,并取负值。所以,使用该损失函数需要先调用torch.nn.functional.log_softmax计算Softmax函数取对数的结果。另一个模块是torch.nn.CrossEntropyLoss,该损失函数可避免LogSoftmax的计算,在损失函数里整合Softmax输出概率,以及对概率区对数输出损失函数。
损失函数使用实例:

import torch
import torch.nn as nn

mse = nn.MSELoss()  # 初始化平方损失函数
t1 = torch.randn(5, requires_grad=True)
t2 = torch.randn(5, requires_grad=True)
print(mse(t1, t2))  # 计算t1和t2的平均损失函数
print('=' * 50)
bce = nn.BCELoss()  # 交叉熵损失函数
t1 = torch.randn(5, requires_grad=True)
t1s = torch.sigmoid(t1)  # 对张量求Sigmoid函数,转换为(0,1)之间的概率
t2 = torch.randint(0, 2, (5, )).float()  # 随机生成0,1的整数序列,并转换为浮点数
print(bce(t1s, t2))  #计算二分类的交叉熵
bce_logits = nn.BCEWithLogitsLoss()  # 交叉熵对数损失函数
print(bce_logits(t1, t2))  # 计算二分类交叉熵
print('=' * 50)
N = 10  # 定义分类数目
t1 = torch.randn(5, N, requires_grad=True)  # 预测张量
t2 = torch.randint(0, N, (5, ))  # 目标张量
t1s = torch.nn.functional.log_softmax(t1, -1)  # 计算预测张量的LogSoftmax
nll = nn.NLLLoss()  # NLL损失函数
print(nll(t1s, t2))
ce = nn.CrossEntropyLoss()  # 交叉熵损失函数
print(ce(t1, t2))

pytorch的损失函数和优化器_第1张图片

2. 优化器

有了损失函数之后,就可以使用优化器对模型进行优化。下面以随机梯度下降算法为例,对线性回归模型进行优化。

import torch
import torch.nn as nn
from sklearn.datasets import load_boston

boston = load_boston()

class LinearModel(nn.Module):
    def __init__(self, ndim):
        super(LinearModel, self).__init__()
        self.ndim = ndim
        
        self.weight = nn.Parameter(torch.randn(ndim, 1))  # 定义权重
        self.bias = nn.Parameter(torch.randn(1))  # 定义偏置
        
    def forward(self, x):
        # y = Wx + b
        return x.mm(self.weight) + self.bias
    
lm = LinearModel(13)
criterion = nn.MSELoss()
optim = torch.optim.SGD(lm.parameters(), lr=1e-6)  # 定义随机梯度优化器
data = torch.tensor(boston['data'], requires_grad=True, dtype=torch.float32)  # 特征数据
target = torch.tensor(boston['target'], dtype=torch.float32)  # 目标数据

for step in range(100000):
    predict = lm(data)  # 输出模型预测结果
    loss = criterion(predict, target)  # 输出损失函数
    if step and step % 10000 == 0:
        print('Loss:{:.3f}'.format(loss.item()))
    optim.zero_grad()  # 梯度清零
    loss.backward()  # 反向传播
    optim.step()

pytorch的损失函数和优化器_第2张图片
以上的模型构建过程是,首先构建13个参数的线性回归模型LinearModel(13),然后构建损失函数的计算模块criterion,并将其设置为MSELoss模块的实例,接着构建一个随机梯度下降算法的优化器,该优化器的第一个参数是线性回归模型参数的生成器,第二个参数是学习率(lr)。

你可能感兴趣的:(PyTorch,pytorch,深度学习,python)