首页
看点啥
插画图片
首页 科技看点 PyTorch损失函数CrossEntropyLoss用法及说明实用指南

PyTorch损失函数CrossEntropyLoss用法及说明实用指南

2026-10-21 0

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“PyTorch损失函数CrossEntropyLoss用法及说明”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

在这个场景下,将 input 经过 softmax 激活函数之后,再计算其与 target 的交叉熵损失。

阅读源码能够发现

该方法将 log_softmax 和 nll_loss 进行了结合

class CrossEntropyLoss(_WeightedLoss):

    def __init__(self, weight=None, size_average=None, ignore_index=-100,
                 reduce=None, reduction='mean'):
        super(CrossEntropyLoss, self).__init__(weight, size_average, reduce, reduction)
        self.ignore_index = ignore_index

    @weak_script_method
    def forward(self, input, target):
        return F.cross_entropy(input, target, weight=self.weight,
                               ignore_index=self.ignore_index, reduction=self.reduction)
                              
def cross_entropy(input, target, weight=None, size_average=None, ignore_index=-100,
                  reduce=None, reduction='mean'):
    if size_average is not None or reduce is not None:
        reduction = _Reduction.legacy_get_string(size_average, reduce)
    return nll_loss(log_softmax(input, 1), target, weight, None, ignore_index, None, reduction)

为什么要采用 softmax 激活函数

理解这一步时,因为交叉熵描述了两个概率分布的差异,而神经网络输出的是向量,同时不是概率分布的形式,所以需 softmax 激活函数将一个向量进行 “归一化” 成概率分布的形式,再采用交叉熵损失函数计算 loss

代码理解:

import torch
import torch.nn.functional as F
import torch.nn as nn

torch.manual_seed(2019)

output = torch.randn(2, 3) # 网络输出
target = torch.ones(2, dtype=torch.long).random_(3) # 真实标签
print('output:\n{}'.format(output))
print('target:\n{}\n'.format(target))

# 第一步,对output进行log_softmax运算
log_softmax = F.log_softmax(output, dim=1)
print('log_softmax:\n{}\n'.format(log_softmax))
# 第二步,将计算结果和target输入nll_loss损失函数计算交叉熵
nll_loss = F.nll_loss(log_softmax, target)
print('nll_loss:{}'.format(nll_loss))

# 直接使用cross_entropy损失函数计算output与target的交叉熵
cross_entropy_loss = F.cross_entropy(output, target)
print('cross_entropy_loss:{}'.format(cross_entropy_loss))

# 实例化类
criterion = nn.CrossEntropyLoss()
loss = criterion(output, target)
print('loss:{}'.format(loss))

"""
output:
tensor([[-0.1187, 0.2110, 0.7463],
        [-0.6136, -0.1186, 1.5565]])
target:
tensor([2, 0])

log_softmax:
tensor([[-1.5614, -1.2317, -0.6964],
        [-2.4335, -1.9386, -0.2635]])

nll_loss:1.564985990524292
cross_entropy_loss:1.564985990524292
loss:1.564985990524292
"""

log_softmax函数

实际处理时,先将 iutput 进行一次 softmax 运算,随后将结果作 log 对数运算

代码理解

import torch
import torch.nn.functional as F
import numpy as np

torch.manual_seed(2019)

output = torch.randn(2, 3) # 网路输出
print(output, '\n')

# torch进行softmax计算
torch_softmax = F.softmax(output, dim=1)
print(torch_softmax)
# torch计算以自然数e为底,矩阵的对数,得到的结果也是一个矩阵
torch_log_softmax = torch.log(torch_softmax)
print(torch_log_softmax)

# torch直接计算log_softmax
torch_log_softmax = F.log_softmax(output, dim=1)
print(torch_log_softmax)

# 张量直接调用log_softmax
torch_log_softmax = output.log_softmax(dim=1)
print(torch_log_softmax, '\n')

# numpy进行softmax计算
e_j = np.exp(output.numpy()) # 对矩阵内值进行e的幂次方运算
e_k = e_j.sum(axis=1).reshape(-1, 1) # 对每行的矩阵求和
np_softmax = e_j / e_k # 幂运算后的矩阵内的值,在每行矩阵中所占的概率分布值
print(np_softmax)
# numpy计算以自然数e为底,矩阵的对数,得到的结果也是一个矩阵
np_log_softmax = np.log(np_softmax)
print(np_log_softmax)

"""
tensor([[-0.1187, 0.2110, 0.7463],
        [-0.6136, -0.1186, 1.5565]])

tensor([[0.2098, 0.2918, 0.4984],
        [0.0877, 0.1439, 0.7684]])
tensor([[-1.5614, -1.2317, -0.6964],
        [-2.4335, -1.9386, -0.2635]])
tensor([[-1.5614, -1.2317, -0.6964],
        [-2.4335, -1.9386, -0.2635]])
tensor([[-1.5614, -1.2317, -0.6964],
        [-2.4335, -1.9386, -0.2635]])

[[0.20983616 0.29179907 0.49836478]
 [0.08772492 0.14391233 0.76836276]]
[[-1.5614283 -1.2316898 -0.696423 ]
 [-2.4335492 -1.938551 -0.2634933]]
 """

总结

落到代码里,总的来说,PyTorch损失函数适合结合实际项目边做边理解。先抓住核心思路,再逐步补上细节和边界处理,最后效果会更稳定,也更容易复用。

喜欢(0)

上一篇

Claude Code 的账号、模型与使用限制完整指南

下一篇

MongoDB与PostgreSQL两个数据库的特点详细对比指南实用指南

猜你喜欢