首页人工智能Pytorch【深度学习(PyTorch...

【深度学习(PyTorch篇)】25.损失函数

本系列文章配套代码获取有以下两种途径:

  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1XuxKa9_G00NznvSK0cr5qw?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/PyTorch





在前面实现线性回归时,在求解权重w和偏置b时就使用到了损失函数,即找到一组权重w和偏置b,使得对于给定的自变量x,预测的因变量与实际值之间的误差(损失函数)尽可能小。

【深度学习(PyTorch篇)】17.实现线性回归

可以说,损失函数在神经网络训练过程中起着导向作用。它告诉神经网络在每次迭代中应该如何调整其内部参数(如权重和偏置),以最小化预测误差。通过反复调整参数来减少损失函数的值,神经网络能够逐渐学习到从输入数据到期望输出的正确映射。

均方误差(Mean Squared Error, MSE)和交叉熵损失(Cross-Entropy Loss)是两种常用的损失函数,有时可能也会使用到负对数似然损失(Negative Log Likelihood Loss,NLLLoss),它们在不同的机器学习任务中发挥着关键作用

01

均方误差(MSE)


均方误差(Mean Squared Error,MSE)损失函数是一种常用的回归损失函数,用于衡量模型预测值与真实值之间的差异。其具体计算方式是将每个样本的预测值与真实值之差进行平方,然后对所有样本取平均。

其数学表达式如下:

均方误差计算简单,易于理解,通常用于回归任务,特别是当目标变量是连续的时。例如,在房价预测、温度预测等任务。

  • 基于Python实现:

Python中,可以使用NumPy库来计算MSE。自定义的mean_squared_error 函数接受两个NumPy数组作为输入:y_true(真实值)和y_pred(预测值)。函数计算这两个数组之间差值的平方,然后求平均值来得到MSE
import numpy as np  

# 定义函数
def mean_squared_error(y_true, y_pred):  
    """  
    计算均方误差MSE  
    :param y_true: 真实值数组  
    :param y_pred: 预测值数组  
    :return: 均方误差  
    """
  
    return np.mean((y_true - y_pred) ** 2)

# 生成y_true(真实值)示例数据
input = np.random.randn(35)
# 生成y_pred(预测值)示例数据
target = np.random.randn(35)

# 计算MSE  
mse = mean_squared_error(input , target)
print(f"Mean Squared Error (MSE): {mse}")

  • 基于PyTorch实现

PyTorch中,可以使用torch.nn模块中的MSELoss类来实现均方误差(MSE)。

import torch
import torch.nn as nn

# 转为tensor
input_tensor = torch.from_numpy(input)
target_tensor = torch.from_numpy(target)

# 使用torch.nn模块中的MSELoss类来实现均方误差(MSE)
loss = nn.MSELoss()

# 计算MSE  
output = loss(input_tensor, target_tensor)
print(f"Mean Squared Error (MSE): {output}")

02
负对数似然损失NLLLoss


PyTorch 中,NLLLossNegative Log Likelihood Loss)常用于多分类任务,其主要目的是衡量模型预测的概率分布与真实标签之间的差异。需要注意的是,NLLLoss与期望不同,它没有取概率操作,而是将对数概率张量作为输入。
其计算过程如下(默认参数下):
  • 输入input:通常是模型的预测结果,需要先经过log_softmax处理,将其转换为概率分布的形式,并取对数。
  • 确定目标类别class:这是真实的类别标签。
  • 计算损失:根据公式loss(input, class) = -input(class)计算损失值。具体来说,就是取input中对应class的元素,并取其负值作为损失。

  • 基于Python实现

使用NumPy来实现NLLLoss时,需要注意的是,input在输入NLLLoss之前,需要对其进行log_softmax处理。

import numpy as np  

def softmax(x):
    e_x = np.exp(x - np.max(x,axis=1, keepdims=True))
    return e_x / e_x.sum(axis=1, keepdims=True)

# 生成y_true(真实值)示例数据
input = np.random.randn(35)
input = np.log(softmax(input))
# 生成y_pred(预测值)示例数据
target = np.random.randint(0,5,size=(3))

# 定义函数
def nll_loss(input, targets):
    # 计算每个样本的损失
    losses = -input[range(input.shape[0]), target]
    # 返回平均损失
    return np.mean(losses)

# 计算NLLLoss
nll_loss = nll_loss(input , target)
print(f"Negative Log Likelihood Loss (NLLLoss): {nll_loss}")


  • 基于PyTorch实现

PyTorch中,可以使用torch.nn模块中的NLLLoss类来实现均方误差(NLLLoss)。

import torch
import torch.nn as nn

# 转为tensor
input = torch.from_numpy(input)
target = torch.from_numpy(target).to(dtype=torch.long)

# 创建NLLLoss损失函数对象  
nll_loss = nn.NLLLoss()  

# 计算NLLLoss
loss = nll_loss(input, target)  
print(f"Negative Log Likelihood Loss (NLLLoss): {loss}")

03

交叉熵损失Cross Entropy Loss


交叉熵损失(Cross Entropy Loss)是一种常用的损失函数,主要用于分类问题。它基于信息论中的交叉熵概念,用于衡量模型的预测结果与真实标签之间的差异。

假设p和q是数据x的两个概率分布,通过q来表示p的交叉熵可如下计算:

交叉熵刻画了两个概率分布之间的距离,旨在描绘通过概率q分布来表达p概率分布的困难程度。根据公式不难理解,交叉熵越小,两个概率分布p和q越接近。
在分类问题中,交叉熵损失函数的具体形式会根据问题的类型(二分类或多分类)而有所不同。
  • 二分类问题:

  • 多分类问题:

另外,在机器学习和深度学习中,目标(target)通常指的是我们想要模型学习并预测的真实结果。当我们处理分类问题时,目标可以采用两种形式:类索引(class indices)或类概率(class probabilities)。

(1)Example of target with class indices

类索引表示每个样本所属的类别。在多分类问题中,我们通常使用一个整数来表示每个类别的索引。例如,如果我们有三个类别:猫、狗和鸟,我们可以将它们分别标记为0、1和2。在这种情况下,模型的任务是预测出每个样本对应的类别索引。
  • 基于Python实现

import numpy as np  

# 生成y_true(真实值)示例数据
input = np.random.randn(35)
# 生成y_pred(预测值)示例数据
target = np.random.randint(0,5,size=(3))

def softmax(x):
    e_x = np.exp(x - np.max(x,axis=1, keepdims=True))
    return e_x / e_x.sum(axis=1, keepdims=True)

# 定义函数
def cross_entropy_loss(input , target):
    #计算输入softmax,此时可以看到每一行加到一起结果都是1
    soft_output=softmax(input)
    #在softmax的基础上取log
    log_output = -np.log(soft_output)
    # 根据真实标签选取对应的网络输出概率(取log后的),再求平均值
    res = np.mean(log_output[range(len(log_output)) , target])
    return res

# 计算Cross Entropy Loss
cross_entropy_loss = cross_entropy_loss(input , target)
print(f"Cross Entropy Loss: {cross_entropy_loss}")
  • 基于PyTorch实现
import torch
import torch.nn as nn

# 转为tensor
input = torch.from_numpy(input)
target = torch.from_numpy(target).to(dtype=torch.long)

# 创建CrossEntropyLoss损失函数对象  
loss = nn.CrossEntropyLoss()

# 计算Cross Entropy Loss
loss = loss(input, target)  
print(f"Cross Entropy Loss: {loss}")
(2)Example of target with class probabilities

类概率表示每个样本属于各个类别的概率分布。在多分类问题中,对于每个样本,我们会为每个类别分配一个概率值,这些概率值的总和为1。这通常用于表示模型对于样本属于每个类别的置信度。在这种情况下,模型的任务是预测出与真实概率分布尽可能接近的输出概率分布。

  • 基于Python实现

import numpy as np  

# 生成y_true(真实值)示例数据
input = np.random.randn(35)

def softmax(x):
    e_x = np.exp(x - np.max(x,axis=1, keepdims=True))
    return e_x / e_x.sum(axis=1, keepdims=True)

# 生成y_pred(预测值)示例数据
target = np.random.randn(35)
target = softmax(target)

# 定义函数
def cross_entropy_loss(input, target):
    #计算输入softmax,此时可以看到每一行加到一起结果都是1
    soft_output=softmax(input)
    #在softmax的基础上取log
    log_output = -np.log(soft_output)
    return np.mean(np.sum(target * log_output, 1))

# 计算Cross Entropy Loss
cross_entropy_loss = cross_entropy_loss(input , target)
print(f"Cross Entropy Loss: {cross_entropy_loss}")


  • 基于PyTorch实现

import torch
import torch.nn as nn

# 转为tensor
input = torch.from_numpy(input)
target = torch.from_numpy(target)

# 创建CrossEntropyLoss损失函数对象  
loss = nn.CrossEntropyLoss()

# 计算Cross Entropy Loss
loss = loss(input, target)  
print(f"Cross Entropy Loss: {loss}")

通过上述示例代码,可以看出,Pytorch中,CrossEntropyLoss()不单是做了交叉熵,而且在里面还加入了logsoftmax,即:

Cross Entropy Loss=softmax+log+NLLLoss


更多内容可以前往官网查看

https://pytorch.org/


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments