Pytorch常用损失函数

Title Pytorch常用损失函数
Framework PyTorch
User wy8817399@vip.qq.com
Id 37
Created 2/2/26, 3:48 AM
Modified 2/4/26, 3:33 PM
Published Yes
Content

损失函数介绍:

    概述:

        损失函数也叫成本函数, 目标函数, 代价函数, 误差函数, 就是用来衡量 模型好坏(模型拟合情况)的.

    分类:

        分类问题:

            多分类交叉熵损失: CrossEntropyLoss 【实际情况可替代BCELoss】

            二分类交叉熵损失: BCELoss

        回归问题:

            MAE: Mean Absolute Error, 平均绝对误差.

            MSE: Mean Squared Error, 均方误差.

            Smooth L1: 结合上述两个的特点做的升级, 优化.【实际情况可替代MAE和MSE】

 

多分类交叉熵损失: CrossEntropyLoss

    设计思路:

        Loss = - Σylog(S(f(x)))

    简单记忆:

        x:          样本

        f(x):       加权求和

        S(f(x)):    处理后的概率

        y:          样本x属于某一个类别的 真实概率.

    大白话解释:

        损失函数结果 = 最小化 正确类别所对应的 预测概率的对数的 负值(损失值最小)...

    细节:

        CrossEntropyLoss = Softmax() + 损失计算, 后续如果用这个损失函数, 则: 输出层就不用额外调用 softmax()激活函数了.

# 导包
import torch
import torch.nn as nn


# 1. 定义函数, 演示: 多分类交叉熵损失.
def dm01():
    # 1. 手动创建样本的真实值 -> 就是上述公式中的 y
    y_true = torch.tensor([[0, 1, 0], [1, 0, 0]], dtype=torch.float)
    # y_true = torch.tensor([1, 2])

    # 2. 手动创建样本的预测值 -> 就是上述公式中的 f(x)
    y_pred = torch.tensor([[0.1, 0.8, 0.1], [0.7, 0.2, 0.1]], requires_grad=True, dtype=torch.float)

    # 3. 创建多分类交叉熵损失函数.
    criterion = nn.CrossEntropyLoss()       # 平均损失, 来源于参数: reduction: str = "mean",

    # 4. 计算损失值.
    loss = criterion(y_pred, y_true)
    print(f'损失值: {loss}')


# 2. 测试
if __name__ == '__main__':
    dm01()

 

二分类任务的损失函数(BCELoss):

    公式:

        Loss = -ylog(预测值) - (1 - y)log(1 - 预测值)

    细节:

        因为公式中没有包含Sigmoid激活函数, 所以使用BCELoss的时候, 还需要手动指定 Sigmoid.

# 导包
import torch
import torch.nn as nn


# 1. 定义函数, 演示: 二分类任务的损失函数.
def dm01():
    # 1. 设置真实值.
    y_true = torch.tensor([0, 1, 0], dtype=torch.float)

    # 2. 设置预测值(概率)
    y_pred = torch.tensor([0.6901, 0.5423, 0.2639])

    # 3. 创建二分类交叉熵损失函数.
    criterion = nn.BCELoss()    # reduction: str = "mean" -> 均值

    # 4. 计算损失值.
    loss = criterion(y_pred, y_true)
    print(f'损失值: {loss}')

# 2. 测试
if __name__ == '__main__':
    dm01()

 

回归任务常用损失函数如下:

    MAE:   Mean Absolute Error, 平均绝对误差.

        公式:

            误差绝对值之和 / 样本总数

        类似于L1正则化, 权重可以降维0, 数据会变得稀疏.

 

        弊端:

            在0点不平滑, 可能错过最小值.

 

    MSE:   Mean Squared Error, 均方误差.

        公式:

            误差平方之和 / 样本总数

        弊端:

            如果差值过大, 可能存在梯度爆炸的情况.

 

    Smooth L1:

        就是基于MAE 和 MSE做的综合, 在 [-1, 1]是 L2(MSE), 其它段时L1.

        这样即解决了L1不平滑的问题(0点不可导, 可能错过最小值)

        又解决了L2(MSE)的 梯度爆炸的问题.

# 导包
import torch
import torch.nn as nn

# 1. 定义函数, 演示: MAE 损失函数.
def dm01():
    # 1. 定义变量, 记录: 真实值.
    y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)

    # 2. 定义变量, 记录: 预测值.
    y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)

    # 3. 创建MAE损失函数对象.
    criterion = nn.L1Loss()

    # 4. 计算损失.
    loss = criterion(y_pred, y_true)

    # 5. 输出损失.
    print(f'MAE: {loss}')


# 2. 定义函数, 演示: MSE 损失函数.
def dm02():
    # 1. 定义变量, 记录: 真实值.
    y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)

    # 2. 定义变量, 记录: 预测值.
    y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)

    # 3. 创建MSE损失函数对象.
    criterion = nn.MSELoss()

    # 4. 计算损失.
    loss = criterion(y_pred, y_true)

    # 5. 输出损失.
    print(f'MSE: {loss}')


# 3. 定义函数, 演示: Smooth L1 损失函数.
def dm03():
    # 1. 定义变量, 记录: 真实值.
    y_true = torch.tensor([2.0, 2.0, 2.0], dtype=torch.float)

    # 2. 定义变量, 记录: 预测值.
    y_pred = torch.tensor([1.0, 1.0, 1.9], requires_grad=True)

    # 3. 创建Smooth L1损失函数对象.
    criterion = nn.SmoothL1Loss()

    # 4. 计算损失.
    loss = criterion(y_pred, y_true)

    # 5. 输出损失.
    print(f'Smooth L1: {loss}')




# 4. 测试
if __name__ == '__main__':
    # dm01()    # 0.699999988079071
    # dm02()    # 0.6700000166893005
    dm03()      # 0.33500000834465027