共计 2186 个字符,预计需要花费 6 分钟才能阅读完成。
1. 多分类问题与交叉熵基础
在深度学习中,多分类问题是指模型需要从多个类别中选择最合适的一个作为预测结果。交叉熵损失函数(Cross-Entropy Loss)是衡量模型预测概率分布与真实概率分布差异的重要指标,特别适用于分类任务。

数学上,交叉熵损失函数定义为:
$$ L = -\sum_{i=1}^{C} y_i \log(p_i) $$
其中,$C$ 是类别数量(这里 $C=10$),$y_i$ 是真实标签的 one-hot 编码,$p_i$ 是模型预测的第 $i$ 个类别的概率。
2. 二分类与多分类交叉熵对比
- 二分类交叉熵 :
- 类别数量 $C=2$
- 通常使用 sigmoid 激活函数
-
公式简化为:$L = -[y\log(p) + (1-y)\log(1-p)]$
-
多分类交叉熵 :
- 类别数量 $C>2$(本文 $C=10$)
- 使用 softmax 激活函数确保概率总和为 1
- 需要完整的 one-hot 编码标签
3. PyTorch 完整实现
以下是完整的 10 分类问题实现代码:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
# 数据预处理
transform = transforms.Compose([transforms.ToTensor(),
transforms.Normalize((0.5,), (0.5,))
])
# 加载 MNIST 数据集(10 分类)train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform)
train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=64, shuffle=False)
# 定义简单神经网络
class Net(nn.Module):
def __init__(self):
super(Net, self).__init__()
self.fc1 = nn.Linear(28*28, 128)
self.fc2 = nn.Linear(128, 10) # 10 个输出单元对应 10 个类别
def forward(self, x):
x = x.view(-1, 28*28) # 展平图像
x = torch.relu(self.fc1(x))
x = self.fc2(x) # 不在这里加 softmax,因为 CrossEntropyLoss 会自动处理
return x
model = Net()
# 定义损失函数和优化器
criterion = nn.CrossEntropyLoss() # 已经内置 softmax
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 训练循环
for epoch in range(10):
for i, (images, labels) in enumerate(train_loader):
# 前向传播
outputs = model(images)
loss = criterion(outputs, labels) # labels 是 0 - 9 的整数,不是 one-hot
# 反向传播和优化
optimizer.zero_grad()
loss.backward()
optimizer.step()
if (i+1) % 100 == 0:
print(f'Epoch [{epoch+1}/10], Step [{i+1}/{len(train_loader)}], Loss: {loss.item():.4f}')
4. 常见问题与解决方案
- 标签编码错误
- 错误做法:手动将标签转为 one-hot 编码
-
正确做法:PyTorch 的 CrossEntropyLoss 直接接受类索引(0- 9 的整数)
-
数值不稳定
- 现象:出现 NaN 或极大 loss 值
-
解决方案:
- 确保模型最后一层不使用 softmax(CrossEntropyLoss 已包含)
- 添加小的 epsilon 防止 log(0)
-
类别不平衡
- 现象:某些类别样本极少
- 解决方案:
- 在 CrossEntropyLoss 中设置 weight 参数
- 对稀有类别样本进行过采样
5. 模型调参建议
- 学习率 :
- 初始尝试 0.001(Adam 优化器)
-
使用学习率调度器(如 ReduceLROnPlateau)
-
批次大小 :
- 一般选择 32-256 之间
-
太大可能导致内存不足,太小可能导致训练不稳定
-
训练轮次 :
- 监控验证集准确率
- 提前停止(Early Stopping)防止过拟合
6. 思考与扩展
- 尝试将类别数量从 10 改为其他数值(如 20),观察模型性能变化
- 比较使用 weight 参数处理类别不平衡前后的效果差异
- 实现带 label smoothing 的交叉熵损失函数版本
- 可视化不同类别的预测概率分布
通过本文的学习,你应该已经掌握了 10 分类交叉熵损失函数的原理和实现方法。在实际应用中,理解损失函数的行为对于调试模型至关重要。建议从简单模型开始,逐步增加复杂度,并始终关注训练和验证损失的变化趋势。
正文完
发表至: 未分类
近一天内
