目录
前言
在PyTorch中,Softmax和LogSoftmax函数是用于将多维张量的值转换为概率分布的函数。它们通常用于多分类问题中,将模型的输出转换为每个类别的概率。
在PyTorch中,NLLLoss
(负对数似然损失)和CrossEntropyLoss
(交叉熵损失)是两种常用的损失函数,它们通常用于多分类问题。
一、四种函数的概念
1.1 Softmax函数
Softmax函数通常用于多分类问题的输出层,它将一个K维的任意实数值向量转换为另一个K维的实数值向量,其中向量中的每个元素都在0到1之间,并且所有元素的和为1。这使得输出可以被解释为概率分布。
函数定义:
Softmax函数定义为:
其中, 是输入向量中的第 个元素,是 的指数值。
1.2 LogSoftmax函数
LogSoftmax函数是Softmax函数的对数形式,它首先计算Softmax函数的输出,然后对每个维度的值应用自然对数函数。这有助于数值稳定性,尤其是在处理非常大或非常小的数值时。
函数定义:
LogSoftmax函数定义为:
1.3 NLLLoss(负对数似然损失)
NLLLoss
(Negative Log Likelihood Loss)是用于多分类问题的损失函数,它计算的是负对数似然损失。在多分类问题中,模型的输出通常是一个对数概率分布,而NLLLoss
用于计算这个分布与真实标签之间的损失。
函数定义:
其中, 是模型输出的对数概率分布, 是真实标签的独热编码。
1.4 CrossEntropyLoss(交叉熵损失)
CrossEntropyLoss
是另一种用于多分类问题的损失函数,它结合了LogSoftmax
和NLLLoss
的功能。在计算交叉熵损失时,模型的输出首先通过LogSoftmax
函数转换为对数概率分布,然后计算这个分布与真实标签之间的负对数似然损失。
函数定义:
其中, 是模型输出的原始概率分布, 是真实标签的独热编码。
二、使用步骤
1.1 Softmax和LogSoftmax函数示例
代码展示:
import torch
import math
# 参数设置dim=1表示行和为1
softmax = torch.nn.Softmax(dim=1) # 定义Softmax函数
input = torch.Tensor([[1, 2, 3], [1, 2, 4]])
print("测试数据:", input)
output = softmax(input) # Softmax函数计算
print("输出softmax计算后结果:\n", output)
x00 = math.log(0.0900)
x01 = math.log(0.2447)
x02 = math.log(0.6652)
x10 = math.log(0.0420)
x11 = math.log(0.1142)
x12 = math.log(0.8438)
print("输出log计算结果:")
print(x00, x01, x02)
print(x10, x11, x12)
# 参数设置dim=1表示行和为1
lgsoftmax = torch.nn.LogSoftmax(dim=1) # 定义LogSoftmax函数
output = lgsoftmax(input) # LogSoftmax函数计算
print("输出LogSoftmax计算后结果:\n", output)
代码讲解:
1.定义一个Softmax函数实例,其中dim=1
表示在计算softmax时,将沿着每一行(dim=1)进行操作,使得每一行的元素和为1。
dim解释:在PyTorch中,dim
参数用于指定在哪个维度上应用函数。对于Softmax
和LogSoftmax
函数,dim
参数决定了函数将沿着哪个维度进行归一化操作。
对于Softmax
函数,dim
参数指定了输入张量的哪个维度将被归一化。例如,如果dim=1
,则函数将沿着输入张量的第二个维度(通常是类别维度)进行归一化,使得每个样本的输出概率和为1。如果dim=0
,则函数将沿着第一个维度(通常是样本维度)进行归一化。
对于LogSoftmax
函数,dim
参数同样指定了归一化的维度。LogSoftmax
函数首先计算Softmax
函数的输出,然后对每个维度的值应用自然对数函数。因此,LogSoftmax
函数的输出是Softmax
函数输出的对数,这有助于数值稳定性,尤其是在处理非常大或非常小的数值时。
在上述代码中,dim=1
表示Softmax
和LogSoftmax
函数将沿着输入张量的每一行(即每个样本的类别维度)进行归一化和对数运算。这意味着对于每个样本,函数将确保其类别概率的总和为1,并且输出的是每个类别的对数概率。
softmax = torch.nn.Softmax(dim=1)
2.创建一个2x3的Tensor作为输入数据。
input = torch.Tensor([[1, 2, 3], [1, 2, 4]])
3.打印输入数据。
print("测试数据:", input)
4.使用定义好的Softmax函数计算输入数据的softmax值,并打印结果。
output = softmax(input)
print("输出softmax计算后结果:\n", output)
5.手动计算输入数据的log值,用于后续与LogSoftmax的结果进行比较。
x00 = math.log(0.0900)
x01 = math.log(0.2447)
x02 = math.log(0.6652)
x10 = math.log(0.0420)
x11 = math.log(0.1142)
x12 = math.log(0.8438)
print("输出log计算结果:")
print(x00, x01, x02)
print(x10, x11, x12)
6.定义一个LogSoftmax函数实例,同样地,dim=1
表示在计算logsoftmax时,将沿着每一行进行操作。
lgsoftmax = torch.nn.LogSoftmax(dim=1)
7.使用定义好的LogSoftmax函数计算输入数据的logsoftmax值,并打印结果。
output = lgsoftmax(input)
print("输出LogSoftmax计算后结果:\n", output)
1.2 NLLLoss函数示例
代码展示:
import torch
# 参数设置dim=1表示行和为1
lgsoftmax = torch.nn.LogSoftmax(dim=1) # 定义LogSoftmax函数
input = torch.Tensor([[1, 2, 3], [1, 2, 4]]) # 测试数据
output = lgsoftmax(input) # LogSoftmax函数自动计算
print("输出LogSoftmax计算后结果:\n", output)
criterion = torch.nn.NLLLoss() # 定义NLLLoss函数
labels = torch.tensor([1, 2]) # 每一项的范围是[0,C-1] 0 1 2
loss = criterion(output, labels)
print(loss)
print((1.4076+0.1698)/2)
代码讲解:
lgsoftmax = torch.nn.LogSoftmax(dim=1) # 定义LogSoftmax函数
这里创建了一个LogSoftmax函数的实例。LogSoftmax函数是Softmax函数的对数形式,它将输入的任意实数值映射到(0, 1)区间,并且输出的总和为1。dim=1
参数指定了在哪个维度上进行softmax操作,这里是在行上进行操作。
input = torch.Tensor([[1, 2, 3], [1, 2, 4]]) # 测试数据
这行代码创建了一个2x3的Tensor,作为模型的输入数据。这个Tensor包含了两组数据,每组数据有三个特征。
output = lgsoftmax(input) # LogSoftmax函数自动计算
这行代码将LogSoftmax函数应用于输入数据input
,计算出每个元素的LogSoftmax值。
print("输出LogSoftmax计算后结果:\n", output)
打印出LogSoftmax计算后的结果。
criterion = torch.nn.NLLLoss() # 定义NLLLoss函数
这里创建了一个负对数似然损失(NLLLoss)函数的实例。NLLLoss通常用于多分类问题,它计算的是负对数似然损失,即预测概率分布的负对数似然。
labels = torch.tensor([1, 2]) # 每一项的范围是[0,C-1] 0 1 2
这行代码创建了一个Tensor,包含了两个标签,分别对应于输入数据中的两组数据。标签的值范围是从0到类别数减1。
loss = criterion(output, labels)
这行代码计算了使用NLLLoss函数的损失值。output
是LogSoftmax函数的输出,labels
是真实的标签。
1.3 CrossEntropyLoss函数示例
代码展示:
import torch
######### 使用 NLLLoss函数 ######################
# 参数设置dim=1表示行和为1
lgsoftmax = torch.nn.LogSoftmax(dim=1) # 定义LogSoftmax函数
input = torch.Tensor([[1, 2, 3], [1, 2, 4]]) # 测试数据
output = lgsoftmax(input) # LogSoftmax函数自动计算
print("输出LogSoftmax计算后结果:\n", output)
criterion1 = torch.nn.NLLLoss() # 定义NLLLoss函数
labels = torch.tensor([1, 2]) # 每一项的范围是[0,C-1] 0 1 2
loss1 = criterion1(output, labels)
print(loss1)
######### 使用 CrossEntropyLoss 交叉熵损失函数 ###################### CrossEntropyLoss = softmax + lg + NLLLoss
criterion2 = torch.nn.CrossEntropyLoss()
loss2 = criterion2(input, labels)
print(loss2)
代码讲解:
loss1 = criterion1(output, labels)
这行代码计算了使用NLLLoss函数的损失值。output
是LogSoftmax函数的输出,labels
是真实的标签。
criterion2 = torch.nn.CrossEntropyLoss()
这里创建了一个交叉熵损失(CrossEntropyLoss)函数的实例。CrossEntropyLoss是NLLLoss和LogSoftmax的组合,它直接计算了输入和目标之间的交叉熵损失。
loss2 = criterion2(input, labels)
这行代码计算了使用CrossEntropyLoss函数的损失值。input
是原始的输入数据,labels
是真实的标签。
总结
LogSoftmax:LogSoftmax函数是Softmax函数的对数形式,它将输入的任意实数值映射到(0, 1)区间,并且输出的总和为1。LogSoftmax通常与NLLLoss(负对数似然损失)一起使用,特别是在多分类问题中,它能够将模型的输出转换为概率分布,然后计算该分布的负对数似然损失。
NLLLoss (Negative Log Likelihood Loss):NLLLoss函数计算的是负对数似然损失,即预测概率分布的负对数似然。在多分类问题中,它通常与LogSoftmax一起使用,因为LogSoftmax的输出可以作为NLLLoss的输入。这种组合能够有效地衡量模型预测的准确性。
CrossEntropyLoss:CrossEntropyLoss是NLLLoss和LogSoftmax的组合,它直接计算了输入和目标之间的交叉熵损失。在多分类问题中,CrossEntropyLoss可以直接应用于模型的原始输出(通常是未经LogSoftmax处理的分数),而不需要先进行LogSoftmax转换。这种损失函数在处理多分类问题时非常常见,因为它能够直接衡量模型输出与真实标签之间的差异。
Softmax:Softmax函数将输入的任意实数值映射到(0, 1)区间,并且输出的总和为1。它通常用于多分类问题中,将模型的原始输出转换为概率分布。在某些情况下,Softmax可以与CrossEntropyLoss一起使用,尤其是在模型的输出已经是一个概率分布时。