目录
torch.nn子模块Loss Functions详解
nn.L1Loss
用途
用法
使用技巧
注意事项
代码示例
nn.MSELoss
用途
用法
使用技巧
注意事项
代码示例
nn.CrossEntropyLoss
用途
用法
使用技巧
注意事项
代码示例
使用类别索引
使用类别概率
nn.CTCLoss
用途
用法
使用技巧
注意事项
代码示例
有填充的目标
未填充的目标
nn.NLLLoss
用途
用法
使用技巧
注意事项
代码示例
一维损失示例
二维损失示例(例如,用于图像)
nn.PoissonNLLLoss
用途
用法
使用技巧
注意事项
代码示例
nn.GaussianNLLLoss
用途
用法
使用技巧
注意事项
代码示例
异方差(Heteroscedastic)示例
同方差(Homoscedastic)示例
nn.KLDivLoss
用途
用法
使用技巧
注意事项
代码示例
nn.BCELoss
用途
用法
使用技巧
注意事项
代码示例
nn.BCEWithLogitsLoss
用途
用法
使用技巧
注意事项
代码示例
nn.MarginRankingLoss
用途
用法
使用技巧
注意事项
代码示例
nn.HingeEmbeddingLoss
用途
用法
使用技巧
注意事项
代码示例
nn.MultiLabelMarginLoss
用途
用法
使用技巧
注意事项
代码示例
nn.HuberLoss
用途
用法
使用技巧
注意事项
代码示例
nn.SmoothL1Loss
用途
用法
使用技巧
注意事项
代码示例
nn.SoftMarginLoss
用途
用法
使用技巧
注意事项
代码示例
nn.MultiLabelSoftMarginLoss
用途
用法
使用技巧
注意事项
代码示例
nn.CosineEmbeddingLoss
用途
用法
使用技巧
注意事项
代码示例
nn.MultiMarginLoss
用途
用法
使用技巧
注意事项
代码示例
nn.TripletMarginLoss
用途
用法
使用技巧
注意事项
代码示例
nn.TripletMarginWithDistanceLoss
用途
用法
使用技巧
注意事项
代码示例
总结
在 torch.nn
模块中,L1Loss
是一个非常重要的损失函数,主要用于衡量模型预测值和真实值之间的差异。这个函数计算的是预测值和目标值之间的平均绝对误差(Mean Absolute Error, MAE)。在深度学习和机器学习中,损失函数是衡量模型性能的关键指标,L1Loss
在回归问题中尤其有用。
L1Loss
能有效地量化预测值和实际值之间的差异。L1Loss
对异常值更不敏感,因此在数据中有异常值时表现更好。size_average
(已废弃): 是否对损失进行平均。reduce
(已废弃): 是否应用缩减。reduction
: 指定缩减方式,可以是 'mean'
(默认) 或 'sum'
。input
(预测值) 和 target
(目标值) 应为相同形状的张量。L1Loss
使用均值。但在某些应用中,使用总和('sum'
)作为缩减方式可能更有意义。L1Loss
支持实数和复数输入。L1Loss
对异常值不敏感,确保数据预处理阶段处理了异常值。下面是一个简单的使用 torch.nn.L1Loss
的例子:
import torch
import torch.nn as nn
# 创建L1Loss损失函数实例
loss = nn.L1Loss()
# 随机生成输入数据和目标数据
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
# 输出损失值
print(output)
在这个例子中,我们首先创建了一个 L1Loss
实例。然后生成了随机的输入和目标张量,计算了它们之间的 L1Loss
,并通过 backward()
方法进行了反向传播。这样可以帮助我们理解 L1Loss
在实际中是如何工作的。
torch.nn.MSELoss
是 PyTorch 中一个常用的损失函数,用于计算模型预测值和真实值之间的均方误差(Mean Squared Error, MSE)。这个损失函数在回归问题中特别有用,尤其是当我们希望强调较大误差的情况时(因为误差是平方的,所以大误差的影响更大)。
MSELoss
主要用于回归问题,其中目标是最小化预测值和实际值之间的差距。MSELoss
对较大的误差更敏感,使得模型更加注重减少大的预测误差。size_average
(已废弃): 是否对损失进行平均。reduce
(已废弃): 是否应用缩减。reduction
: 指定缩减方式,可以是 'none'
, 'mean'
(默认) 或 'sum'
。input
(预测值) 和 target
(目标值) 应为相同形状的张量。'mean'
或 'sum'
作为缩减方式。MSELoss
对大的误差更敏感,确保对数据中的异常值进行适当处理。MSELoss
时,由于误差平方的原因,可能会导致梯度爆炸的问题,特别是在误差较大时。需要适当调整学习率或使用梯度裁剪等技术来控制。下面是一个简单的使用 torch.nn.MSELoss
的例子:
import torch
import torch.nn as nn
# 创建MSELoss损失函数实例
loss = nn.MSELoss()
# 随机生成输入数据和目标数据
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
# 输出损失值
print(output)
在这个例子中,我们创建了一个 MSELoss
实例,随机生成了输入和目标张量,然后计算了它们之间的均方误差,并通过 backward()
方法进行了反向传播。这个过程帮助我们理解 MSELoss
如何在实际中工作,并对模型的训练过程产生影响。
torch.nn.CrossEntropyLoss
是 PyTorch 中用于分类问题的关键损失函数。它结合了 LogSoftmax 和 NLLLoss(Negative Log Likelihood Loss)的功能,通常用于多类分类问题中。这个损失函数计算输入的 logits(未经归一化的预测值)和目标类别之间的交叉熵损失。
weight
参数为各个类别指定不同的权重,这对于处理类别不平衡的数据集非常有用。weight
(Tensor, 可选): 给每个类别指定的权重。ignore_index
(int, 可选): 指定一个目标值,该值在计算损失时会被忽略。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。label_smoothing
(float, 可选): 用于计算损失时的标签平滑,范围在 [0.0, 1.0]。input
应该包含每个类别的未经归一化的 logits。target
可以包含类别索引或类别概率。input
和 target
的维度一致,特别是在处理多维数据时(如图像)。target
包含类别索引时,它们应该在 [0, C)
范围内,其中 C
是类别的数量。以下是使用 torch.nn.CrossEntropyLoss
的两个例子,分别展示了使用类别索引和类别概率作为目标的情况:
import torch
import torch.nn as nn
# 创建 CrossEntropyLoss 实例
loss = nn.CrossEntropyLoss()
# 随机生成输入数据和目标类别索引
input = torch.randn(3, 5, requires_grad=True)
target = torch.empty(3, dtype=torch.long).random_(5)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
import torch
import torch.nn as nn
# 创建 CrossEntropyLoss 实例
loss = nn.CrossEntropyLoss()
# 随机生成输入数据和目标类别概率
input = torch.randn(3, 5, requires_grad=True)
target = torch.randn(3, 5).softmax(dim=1)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
在这些例子中,我们创建了 CrossEntropyLoss
实例,随机生成了输入数据和目标(类别索引或类别概率),计算了损失,并执行了反向传播。这有助于我们理解 CrossEntropyLoss
在实际应用中的工作方式。
torch.nn.CTCLoss
是 PyTorch 中用于处理序列学习任务的损失函数,特别是在不需要将输入数据分割成固定大小的场景中非常有用。这个损失函数通常与循环神经网络(RNNs)结合使用,用于任务如语音识别或手写识别,其中输入数据是连续的时间序列。
CTCLoss
能够处理输入序列和目标序列长度不一致的情况,这在许多序列到序列的学习任务中非常常见。blank
(int, 可选): 指定空白标签的索引,默认为 0。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。zero_infinity
(bool, 可选): 是否将无限损失置零及其相关的梯度,默认为 False。log_probs
应为 log softmax 后的概率分布。targets
包含目标序列的类别索引。以下是使用 torch.nn.CTCLoss
的示例,展示了如何在有填充和未填充目标的情况下使用它:
import torch
import torch.nn as nn
T, C, N, S = 50, 20, 16, 30 # 定义输入序列长度、类别数、批量大小和目标序列长度
# 初始化输入向量
input = torch.randn(T, N, C).log_softmax(2).detach().requires_grad_()
# 初始化目标
target = torch.randint(1, C, (N, S), dtype=torch.long)
# 输入和目标的长度
input_lengths = torch.full((N,), T, dtype=torch.long)
target_lengths = torch.randint(10, S, (N,), dtype=torch.long)
# CTCLoss
ctc_loss = nn.CTCLoss()
loss = ctc_loss(input, target, input_lengths, target_lengths)
loss.backward()
import torch
import torch.nn as nn
T, C, N = 50, 20, 16 # 定义输入序列长度、类别数、批量大小
# 初始化输入向量
input = torch.randn(T, N, C).log_softmax(2).detach().requires_grad_()
input_lengths = torch.full((N,), T, dtype=torch.long)
# 初始化目标
target_lengths = torch.randint(1, T, (N,), dtype=torch.long)
target = torch.randint(1, C, (sum(target_lengths),), dtype=torch.long)
# CTCLoss
ctc_loss = nn.CTCLoss()
loss = ctc_loss(input, target, input_lengths, target_lengths)
loss.backward()
在这些例子中,我们首先初始化了输入数据和目标数据,其中输入数据通过 log softmax 转换成概率分布。然后定义了输入和目标的长度,并使用 CTCLoss
计算损失,最后执行了反向传播。这些步骤展示了 CTCLoss
在序列学习任务中的应用方式。
torch.nn.NLLLoss
(Negative Log Likelihood Loss)是 PyTorch 中用于分类问题的一种损失函数,特别适用于具有 C 个类别的分类问题。它通常与 LogSoftmax 层一起使用,用于训练神经网络。
weight
参数,可以为每个类别指定不同的权重,这对于处理类别不平衡的数据集非常有用。weight
(Tensor, 可选): 为每个类别分配的权重。ignore_index
(int, 可选): 指定一个目标值,该值在计算损失时会被忽略。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
应包含每个类别的 log 概率。target
应为类别索引,范围在 [0, C-1]
。CrossEntropyLoss
,它结合了 LogSoftmax 和 NLLLoss。target
中的每个值都在 [0, C-1]
的范围内。以下是使用 torch.nn.NLLLoss
的两个例子,分别展示了一维和二维损失的使用:
import torch
import torch.nn as nn
import torch.nn.functional as F
m = nn.LogSoftmax(dim=1)
loss = nn.NLLLoss()
# 输入尺寸 N x C = 3 x 5
input = torch.randn(3, 5, requires_grad=True)
# 目标类别索引
target = torch.tensor([1, 0, 4])
# 计算损失
output = loss(m(input), target)
output.backward()
import torch
import torch.nn as nn
import torch.nn.functional as F
N, C = 5, 4
loss = nn.NLLLoss()
# 输入尺寸 N x C x height x width
data = torch.randn(N, 16, 10, 10)
conv = nn.Conv2d(16, C, (3, 3))
m = nn.LogSoftmax(dim=1)
# 目标类别索引
target = torch.empty(N, 8, 8, dtype=torch.long).random_(0, C)
# 计算损失
output = loss(m(conv(data)), target)
output.backward()
在这些例子中,我们首先使用 LogSoftmax 层将网络的输出转换为 log 概率,然后使用这些 log 概率和目标类别索引来计算 NLL 损失。最后,执行反向传播以更新模型的参数。这展示了 NLLLoss
在分类问题中的应用方式。
torch.nn.PoissonNLLLoss
是 PyTorch 中用于处理具有泊松分布目标的负对数似然损失函数。这个损失函数通常用于模型输出表示事件发生率的情况,如计数数据或事件频率的预测。
log_input
(bool, 可选): 如果为 True,则输入被解释为 log 形式的事件率,否则直接解释为事件率。full
(bool, 可选): 是否计算完整的损失,包括斯特林近似项。eps
(float, 可选): 避免在 log_input=False
时计算 log(0) 的小值。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
应为预测的事件发生率(可以是 log 形式)。target
为实际观测到的事件次数。log_input
的正确值。以下是使用 torch.nn.PoissonNLLLoss
的示例:
import torch
import torch.nn as nn
# 创建 PoissonNLLLoss 实例
loss = nn.PoissonNLLLoss()
# 随机生成 log 输入和目标数据
log_input = torch.randn(5, 2, requires_grad=True)
target = torch.randn(5, 2)
# 计算损失
output = loss(log_input, target)
# 反向传播
output.backward()
在这个例子中,我们首先创建了一个 PoissonNLLLoss
实例。然后生成了随机的 log 输入和目标数据,计算了它们之间的泊松负对数似然损失,并通过 backward()
方法进行了反向传播。这有助于我们理解 PoissonNLLLoss
在实际中是如何工作的,特别是在处理事件频率或计数数据的预测时。
torch.nn.GaussianNLLLoss
是 PyTorch 中的一个损失函数,用于处理目标值被认为是由神经网络预测的期望值和方差参数化的高斯分布的情况。这种损失函数通常用于回归问题,其中模型的输出表示目标值的预测分布。
full
(bool, 可选): 是否包含损失计算中的常数项,默认为 False。eps
(float, 可选): 用于稳定性的小值,用于在计算中限制方差,默认为 1e-6。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
应为预测的期望值。target
为实际观测值。var
为预测的方差值。var
应保持为正值,通常通过模型输出非负值并加上一个小的 eps
值来实现。var
可以与 input
具有相同的形状,或者有一维为 1 以实现广播。以下是使用 torch.nn.GaussianNLLLoss
的示例:
import torch
import torch.nn as nn
# 创建 GaussianNLLLoss 实例
loss = nn.GaussianNLLLoss()
# 随机生成输入、目标和方差数据
input = torch.randn(5, 2, requires_grad=True)
target = torch.randn(5, 2)
var = torch.ones(5, 2, requires_grad=True) # 异方差
# 计算损失
output = loss(input, target, var)
output.backward()
import torch
import torch.nn as nn
# 创建 GaussianNLLLoss 实例
loss = nn.GaussianNLLLoss()
# 随机生成输入、目标和方差数据
input = torch.randn(5, 2, requires_grad=True)
target = torch.randn(5, 2)
var = torch.ones(5, 1, requires_grad=True) # 同方差
# 计算损失
output = loss(input, target, var)
output.backward()
在这些示例中,我们首先创建了一个 GaussianNLLLoss
实例。然后生成了输入(预测的期望)、目标和方差(预测的方差)数据,并计算了它们之间的高斯负对数似然损失。通过 backward()
方法进行反向传播有助于理解 GaussianNLLLoss
在实际应用中的工作方式,尤其是在处理预测分布的回归问题时。
torch.nn.KLDivLoss
是 PyTorch 中用于计算两个概率分布之间的 Kullback-Leibler 散度(KL 散度)的损失函数。这个损失函数用于衡量模型预测的概率分布与目标概率分布之间的差异。
reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
、'batchmean'
或 'sum'
。log_target
(bool, 可选): 指定目标是否在 log 空间,默认为 False。input
应为预测的 log 概率分布。target
为目标概率分布,可以是概率分布或其 log 形式(取决于 log_target
)。log_softmax
函数来实现。'batchmean'
作为 reduction
可以得到数学上更准确的 KL 散度值。以下是使用 torch.nn.KLDivLoss
的示例:
import torch
import torch.nn as nn
import torch.nn.functional as F
# 创建 KLDivLoss 实例
kl_loss = nn.KLDivLoss(reduction="batchmean")
# 输入应为 log 概率分布
input = F.log_softmax(torch.randn(3, 5, requires_grad=True), dim=1)
# 目标为概率分布
target = F.softmax(torch.rand(3, 5), dim=1)
# 计算损失
output = kl_loss(input, target)
# 使用 log 目标的示例
kl_loss = nn.KLDivLoss(reduction="batchmean", log_target=True)
log_target = F.log_softmax(torch.rand(3, 5), dim=1)
output = kl_loss(input, log_target)
在这些示例中,我们创建了 KLDivLoss
实例,然后为输入和目标生成了 log 概率分布和概率分布。接着,我们计算了它们之间的 KL 散度损失,并通过 backward()
方法进行反向传播。这些步骤展示了 KLDivLoss
在实际应用中如何用于衡量两个概率分布之间的差异。
torch.nn.BCELoss
(Binary Cross Entropy Loss)是 PyTorch 中用于衡量二元分类问题中目标值和输入概率之间的二元交叉熵的损失函数。这个损失函数常用于具有两个类别(如 0 和 1)的分类任务。
weight
(Tensor, 可选): 为每个批次元素的损失赋予的手动调整权重。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
应为预测的概率值,范围在 [0, 1]。target
为实际的标签值,也应在 [0, 1] 范围内。import torch
import torch.nn as nn
# 创建 BCELoss 实例
loss = nn.BCELoss()
# 使用 Sigmoid 函数将输入压缩到 [0, 1] 范围
m = nn.Sigmoid()
input = torch.randn(3, 2, requires_grad=True)
# 目标值也在 [0, 1] 范围内
target = torch.rand(3, 2)
# 计算损失
output = loss(m(input), target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 BCELoss
实例。然后使用 Sigmoid 激活函数处理输入数据,以确保它们在 [0, 1] 的范围内。接着,我们计算了输入和目标之间的二元交叉熵损失,并执行了反向传播。这个过程展示了 BCELoss
在处理二元分类问题时的应用方式。
torch.nn.BCEWithLogitsLoss
是 PyTorch 中的一个损失函数,它结合了一个 Sigmoid 层和 BCELoss(二元交叉熵损失)到一个单独的类中。这种组合比单独使用 Sigmoid 激活后跟 BCELoss 更数值稳定,因为它利用了数值稳定性技巧(log-sum-exp)。
pos_weight
(Tensor, 可选): 正例的权重。这对于不平衡的数据集(例如,正例比反例少得多)非常有用。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
应为模型的原始输出(未经 Sigmoid 激活)。target
为实际的标签值,应在 [0, 1] 范围内。pos_weight
参数调整正例和反例的权重,可以改善模型在不平衡数据集上的性能。import torch
import torch.nn as nn
# 创建 BCEWithLogitsLoss 实例
loss = nn.BCEWithLogitsLoss()
# 输入为模型的原始输出
input = torch.randn(3, requires_grad=True)
# 目标值在 [0, 1] 范围内
target = torch.empty(3).random_(2)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
在这个示例中,我们创建了一个 BCEWithLogitsLoss
实例。然后为输入和目标生成了数据,其中输入是模型的原始输出(未经 Sigmoid 激活处理),目标是二元标签。接着,我们计算了输入和目标之间的损失,并执行了反向传播。这个过程展示了 BCEWithLogitsLoss
在处理二元分类问题时的应用方式。
torch.nn.MarginRankingLoss
是 PyTorch 中用于衡量排名任务的损失函数。这个损失函数用于比较两组输入,并根据一个标签(1 或 -1)判断哪组输入应该有更高的排名。
margin
(float, 可选): 设定的间隔阈值,默认为 0。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input1
和 input2
: 两组进行比较的输入。target
: 包含 1 或 -1 的标签,指示哪组输入应该有更高的排名。margin
参数来控制排名错误的惩罚程度。input1
、input2
和 target
的尺寸匹配。target
中的 1 表示 input1
应该排名高于 input2
,-1 则相反。import torch
import torch.nn as nn
# 创建 MarginRankingLoss 实例
loss = nn.MarginRankingLoss()
# 输入样本
input1 = torch.randn(3, requires_grad=True)
input2 = torch.randn(3, requires_grad=True)
# 目标标签
target = torch.randn(3).sign() # 随机生成 1 或 -1
# 计算损失
output = loss(input1, input2, target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 MarginRankingLoss
实例。然后生成了两组输入样本和对应的目标标签。接着,我们计算了基于这些输入和标签的损失,并执行了反向传播。这个过程展示了 MarginRankingLoss
在比较两组输入的排名时的应用方式。
torch.nn.HingeEmbeddingLoss
是 PyTorch 中用于衡量输入张量 x
和标签张量 y
(包含 1 或 -1)之间损失的函数。这通常用于测量两个输入是否相似或不相似,例如使用 L1 对成对距离作为 x
,并且通常用于学习非线性嵌入或半监督学习。
margin
(float, 可选): 间隔阈值,默认为 1。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
表示输入的特征。target
包含 1 或 -1,表示两个输入是相似(1)还是不相似(-1)。margin
参数来控制相似和不相似的样本之间的差异。target
中的值为 1 或 -1。import torch
import torch.nn as nn
# 创建 HingeEmbeddingLoss 实例
loss = nn.HingeEmbeddingLoss()
# 输入样本
input = torch.randn(3, requires_grad=True)
# 目标标签
target = torch.tensor([1, -1, 1], dtype=torch.float) # 标签为 1 或 -1
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 HingeEmbeddingLoss
实例。然后生成了输入样本和相应的目标标签。接着,我们计算了基于这些输入和标签的损失,并执行了反向传播。这个过程展示了 HingeEmbeddingLoss
在区分输入样本是否相似的任务中的应用方式。
torch.nn.MultiLabelMarginLoss
是 PyTorch 中用于多标签分类任务的损失函数。这个损失函数优化了多类别多分类的铰链损失(基于间隔的损失),适用于那些每个样本可能属于多个类别的情况。
reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
为模型的预测结果,尺寸为 (N, C)
,其中 N
是批量大小,C
是类别数。target
是目标类别的索引,同样尺寸为 (N, C)
,但使用 -1 来填充不相关的类别。target
中应包含每个样本的目标类别索引,非目标类别位置用 -1 填充。import torch
import torch.nn as nn
# 创建 MultiLabelMarginLoss 实例
loss = nn.MultiLabelMarginLoss()
# 输入样本
x = torch.FloatTensor([[0.1, 0.2, 0.4, 0.8]])
# 目标标签(3 和 0 是目标类别,-1 表示填充)
y = torch.LongTensor([[3, 0, -1, 1]])
# 计算损失
output = loss(x, y)
# 输出损失
print(output)
在这个示例中,我们首先创建了一个 MultiLabelMarginLoss
实例。然后定义了输入张量 x
和目标张量 y
。目标张量中,3 和 0 是目标类别,其余位置用 -1 填充以表示这些位置不是目标类别。接着,我们计算了损失并打印了结果。这个过程展示了 MultiLabelMarginLoss
在多标签分类任务中的应用方式。
torch.nn.HuberLoss
是 PyTorch 中的一个损失函数,用于结合 L1 损失和 L2 损失的优点。这个损失函数在绝对元素误差低于某个阈值 delta
时使用平方项(类似于 L2 损失),而在误差高于 delta
时使用 delta
缩放的 L1 损失。这样的设计使得 Huber 损失对于离群值(outliers)的敏感性低于 L2 损失,同时在靠近零的区域相比 L1 损失提供了更平滑的梯度。
reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。delta
(float, 可选): 在此阈值以下使用 L2 损失,在此阈值以上使用 L1 损失。默认值为 1.0。input
为模型的预测结果。target
为真实的目标值。delta
: 根据具体任务调整 delta
值,以平衡 L1 和 L2 损失之间的敏感性。delta
附近,损失函数提供了平滑的梯度,远离 delta
时,则表现为 L1 损失,这有助于处理离群值。import torch
import torch.nn as nn
# 创建 HuberLoss 实例
loss = nn.HuberLoss()
# 输入样本和目标
input = torch.randn(3, requires_grad=True)
target = torch.randn(3)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 HuberLoss
实例。然后为输入和目标生成了随机数据。接着,我们计算了基于这些输入和目标的 Huber 损失,并执行了反向传播。这个过程展示了 HuberLoss
在处理回归任务时的应用方式,尤其是在数据中可能包含离群值的情况下。
torch.nn.SmoothL1Loss
是 PyTorch 中的一个损失函数,用于计算输入和目标之间的平滑 L1 损失。它是 L1 损失和 L2 损失的结合体,当绝对误差小于某个阈值 beta
时使用平方项(类似于 L2 损失),而在误差大于 beta
时使用 L1 损失。这种设计使得 Smooth L1 损失对离群值不那么敏感,并且在靠近 0 的区域提供更平滑的梯度。
beta
(float, 可选): 在此阈值以下使用 L2 损失,在此阈值以上使用 L1 损失。默认值为 1.0。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
为模型的预测结果。target
为真实的目标值。beta
: 根据具体任务调整 beta
值,以平衡 L1 和 L2 损失之间的敏感性。beta
附近,损失函数提供了平滑的梯度,远离 beta
时,则表现为 L1 损失,这有助于处理离群值。import torch
import torch.nn as nn
# 创建 SmoothL1Loss 实例
loss = nn.SmoothL1Loss()
# 输入样本和目标
input = torch.randn(3, requires_grad=True)
target = torch.randn(3)
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 SmoothL1Loss
实例。然后为输入和目标生成了随机数据。接着,我们计算了基于这些输入和目标的 Smooth L1 损失,并执行了反向传播。这个过程展示了 SmoothL1Loss
在处理回归任务时的应用方式,尤其是在数据中可能包含离群值的情况下。
torch.nn.SoftMarginLoss
是 PyTorch 中用于二元分类问题的损失函数。它优化了输入张量 x
和目标张量 y
(包含 1 或 -1)之间的逻辑损失(logistic loss)。
reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
应为模型的预测结果。target
包含 1 或 -1,表示正类或负类。import torch
import torch.nn as nn
# 创建 SoftMarginLoss 实例
loss = nn.SoftMarginLoss()
# 输入样本
input = torch.randn(3, requires_grad=True)
# 目标标签
target = torch.tensor([1, -1, 1], dtype=torch.float) # 标签为 1 或 -1
# 计算损失
output = loss(input, target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 SoftMarginLoss
实例。然后为输入和目标生成了数据,其中目标是二元标签(1 或 -1)。接着,我们计算了基于这些输入和目标的逻辑损失,并执行了反向传播。这个过程展示了 SoftMarginLoss
在处理二元分类问题时的应用方式。
torch.nn.MultiLabelSoftMarginLoss
是 PyTorch 中用于多标签分类问题的损失函数。这个损失函数基于最大熵原理,优化了多标签一对多(one-versus-all)的损失,适用于每个样本可能属于多个类别的情况。
weight
(Tensor, 可选): 为每个类别分配的权重。如果给定,它必须是大小为 C 的张量。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
为模型的预测结果,尺寸为 (N, C)
,其中 N
是批量大小,C
是类别数。target
是目标类别的标签,同样尺寸为 (N, C)
。target
中应包含每个样本的目标类别标签,其中每个位置上的值为 0 或 1。weight
参数调整每个类别的损失权重。import torch
import torch.nn as nn
# 创建 MultiLabelSoftMarginLoss 实例
loss = nn.MultiLabelSoftMarginLoss()
# 输入样本
x = torch.FloatTensor([[0.1, 0.2, 0.4, 0.8]])
# 目标标签
y = torch.FloatTensor([[0, 1, 0, 1]])
# 计算损失
output = loss(x, y)
# 输出损失
print(output)
在这个示例中,我们首先创建了一个 MultiLabelSoftMarginLoss
实例。然后定义了输入张量 x
和目标张量 y
。目标张量中的每个位置代表一个类别,其中值为 1 表示该类别是目标类别,0 表示非目标类别。接着,我们计算了损失并打印了结果。这个过程展示了 MultiLabelSoftMarginLoss
在多标签分类任务中的应用方式。
torch.nn.CosineEmbeddingLoss
是 PyTorch 中用于衡量两个输入之间相似性或不相似性的损失函数。这个函数基于余弦相似度来测量输入之间的关系,通常用于学习非线性嵌入或半监督学习任务。
margin
(float, 可选): 间隔阈值,应在 -1 到 1 之间,通常建议在 0 到 0.5 之间。默认值为 0。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input1
和 input2
为需要比较的两个输入张量。target
包含 1 或 -1,表示两个输入是相似(1)还是不相似(-1)。margin
参数来控制相似和不相似样本之间的差异。input1
、input2
和 target
的尺寸匹配。target
中的 1 表示两个输入应该是相似的,而 -1 表示它们应该是不相似的。import torch
import torch.nn as nn
# 创建 CosineEmbeddingLoss 实例
loss = nn.CosineEmbeddingLoss()
# 输入样本
input1 = torch.randn(3, 5, requires_grad=True)
input2 = torch.randn(3, 5, requires_grad=True)
# 目标标签
target = torch.tensor([1, -1, 1], dtype=torch.float) # 标签为 1 或 -1
# 计算损失
output = loss(input1, input2, target)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 CosineEmbeddingLoss
实例。然后为两组输入生成了数据,以及相应的目标标签。接着,我们计算了基于这些输入和标签的余弦嵌入损失,并执行了反向传播。这个过程展示了 CosineEmbeddingLoss
在衡量两个输入是否相似的任务中的应用方式。
torch.nn.MultiMarginLoss
是 PyTorch 中用于多类别分类的铰链损失(hinge loss)函数。这个损失函数是一种边际基损失(margin-based loss),用于优化多类别分类问题中的输入 x
(一个二维的小批量张量)和输出 y
(一个包含目标类别索引的一维张量)之间的关系。
p
(int, 可选): 默认值为 1。1 和 2 是唯一支持的值。margin
(float, 可选): 边际值,默认为 1。weight
(Tensor, 可选): 给每个类别的损失赋予的手动调整权重。如果给定,它必须是大小为 C 的张量。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。input
为模型的预测结果,尺寸为 (N, C)
,其中 N
是批量大小,C
是类别数。target
包含目标类别的索引,每个值应在 0
到 C-1
的范围内。weight
参数调整每个类别的损失权重。p
和 margin
。import torch
import torch.nn as nn
# 创建 MultiMarginLoss 实例
loss = nn.MultiMarginLoss()
# 输入样本
x = torch.tensor([[0.1, 0.2, 0.4, 0.8]])
# 目标标签
y = torch.tensor([3]) # 目标类别为 3
# 计算损失
output = loss(x, y)
# 输出损失
print(output)
在这个示例中,我们首先创建了一个 MultiMarginLoss
实例。然后定义了输入张量 x
和目标张量 y
。目标张量中的值表示目标类别的索引。接着,我们计算了损失并打印了结果。这个过程展示了 MultiMarginLoss
在多类别分类任务中的应用方式。
torch.nn.TripletMarginLoss
是 PyTorch 中的一个损失函数,用于衡量给定的三元组输入张量之间的相对相似性。这个函数常用于度量样本间的相对相似性,例如在人脸识别或其他形式的度量学习中。三元组由锚点(anchor)、正样本(positive examples)和负样本(negative examples)组成。所有输入张量的形状应为 (N, D)
,其中 N
是批量大小,D
是向量维度。
margin
(float, 可选): 边界值,默认为 1.0。p
(int, 可选): 用于计算成对距离的范数度,默认为 2。eps
(float, 可选): 数值稳定性常数,默认为 1e-6。swap
(bool, 可选): 是否使用距离交换,默认为 False。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。anchor
, positive
, negative
分别为锚点、正样本和负样本张量。margin
、p
和 eps
参数。import torch
import torch.nn as nn
# 创建 TripletMarginLoss 实例
triplet_loss = nn.TripletMarginLoss(margin=1.0, p=2, eps=1e-7)
# 输入样本
anchor = torch.randn(100, 128, requires_grad=True)
positive = torch.randn(100, 128, requires_grad=True)
negative = torch.randn(100, 128, requires_grad=True)
# 计算损失
output = triplet_loss(anchor, positive, negative)
# 反向传播
output.backward()
在这个示例中,我们首先创建了一个 TripletMarginLoss
实例。然后定义了锚点、正样本和负样本张量。接着,我们计算了这些输入基于三元组损失的输出,并执行了反向传播。这个过程展示了 TripletMarginLoss
在度量学习和相对相似性度量任务中的应用方式。
torch.nn.TripletMarginWithDistanceLoss
是 PyTorch 中的一个损失函数,它用于度量三个输入张量(表示为锚点(anchor)、正样本(positive)和负样本(negative))之间的三元组损失,并且允许使用自定义的距离函数来计算锚点与正负样本之间的距离。
distance_function
(Callable, 可选): 用于量化两个张量之间接近程度的非负实值函数。margin
(float, 可选): 边界值,用于确定正负样本距离差异的最小值。swap
(bool, 可选): 是否使用距离交换策略。reduction
(str, 可选): 指定损失的缩减方式,可以是 'none'
、'mean'
或 'sum'
。anchor
, positive
, negative
分别为锚点、正样本和负样本张量。margin
和 swap
参数以满足特定任务的需求。import torch
import torch.nn as nn
import torch.nn.functional as F
# 初始化嵌入
embedding = nn.Embedding(1000, 128)
anchor_ids = torch.randint(0, 1000, (1,))
positive_ids = torch.randint(0, 1000, (1,))
negative_ids = torch.randint(0, 1000, (1,))
anchor = embedding(anchor_ids)
positive = embedding(positive_ids)
negative = embedding(negative_ids)
# 使用内置距离函数
triplet_loss = nn.TripletMarginWithDistanceLoss(distance_function=nn.PairwiseDistance())
output = triplet_loss(anchor, positive, negative)
output.backward()
# 使用自定义距离函数
def l_infinity(x1, x2):
return torch.max(torch.abs(x1 - x2), dim=1).values
triplet_loss = nn.TripletMarginWithDistanceLoss(distance_function=l_infinity, margin=1.5)
output = triplet_loss(anchor, positive, negative)
output.backward()
# 使用 Lambda 自定义距离函数
triplet_loss = nn.TripletMarginWithDistanceLoss(
distance_function=lambda x, y: 1.0 - F.cosine_similarity(x, y))
output = triplet_loss(anchor, positive, negative)
output.backward()
在这个示例中,我们演示了如何使用 TripletMarginWithDistanceLoss
损失函数,并展示了如何使用内置的距离函数以及如何定义和使用自定义的距离函数。这个过程展示了 TripletMarginWithDistanceLoss
在度量学习任务中的应用方式。
这篇博客探讨了 PyTorch 中的各种损失函数,包括 L1Loss、MSELoss、CrossEntropyLoss、CTCLoss、NLLLoss、PoissonNLLLoss、GaussianNLLLoss、KLDivLoss、BCELoss、BCEWithLogitsLoss、MarginRankingLoss、HingeEmbeddingLoss、MultiLabelMarginLoss、HuberLoss、SmoothL1Loss、SoftMarginLoss、MultiLabelSoftMarginLoss、CosineEmbeddingLoss、MultiMarginLoss、TripletMarginLoss 和 TripletMarginWithDistanceLoss。每种损失函数都详细描述了其用途、实现方式、使用技巧和注意事项,并提供了实际代码示例,使读者能够更好地理解和应用这些损失函数于各种机器学习和深度学习场景。