PyTorch nn.CrossEntropyLoss 实战:3种权重设置与标签平滑对比(附代码)
PyTorch nn.CrossEntropyLoss 实战3种权重设置与标签平滑对比附代码交叉熵损失函数是深度学习分类任务中最核心的组件之一。PyTorch框架中的nn.CrossEntropyLoss不仅实现了标准的交叉熵计算还提供了weight和label_smoothing两个关键参数来解决实际训练中的类别不平衡和过拟合问题。本文将深入解析这些高级参数的实现原理并通过完整的代码对比展示不同配置下的训练效果差异。1. 交叉熵损失函数核心原理回顾在进入高级参数实战之前我们需要明确几个关键概念Logits模型最后一层线性层的原始输出值未经过softmaxSoftmax将logits转换为概率分布的函数$p_i \frac{e^{z_i}}{\sum_j e^{z_j}}$交叉熵衡量预测概率分布与真实分布的差异$H(p,q) -\sum p_i \log q_i$PyTorch的nn.CrossEntropyLoss实际上同时完成了softmax和交叉熵计算其数学表达式为loss(x, class) -log(exp(x[class]) / sum(exp(x[i]))) -x[class] log(sum(exp(x[i])))这种实现方式在数值稳定性上优于分开计算softmax和交叉熵。2. 权重参数的三种设置方式类别不平衡是现实数据中的常见问题。weight参数允许我们为不同类别分配不同的损失权重其核心公式变为$$ loss(x, class) weight[class] \times (-x[class] \log(\sum_j e^{x[j]})) $$2.1 手动指定权重最直接的方式是根据领域知识手动设置各类别权重。例如在医疗诊断场景中罕见病类别的权重通常更高import torch import torch.nn as nn # 假设3分类问题类别0、1、2的权重分别为1.0, 2.5, 1.8 weights torch.tensor([1.0, 2.5, 1.8]) criterion nn.CrossEntropyLoss(weightweights) # 示例计算 logits torch.tensor([[2.0, 1.0, 0.5], [0.5, 2.0, 1.5]]) # 2个样本的logits targets torch.tensor([0, 1]) # 真实类别 loss criterion(logits, targets) print(f加权损失值: {loss.item():.4f})2.2 自动计算类别权重更科学的方式是根据训练集统计自动计算权重常用方法是反比于类别频率def calculate_weights(train_labels): class_counts torch.bincount(train_labels) num_classes len(class_counts) weights 1. / (class_counts.float() / class_counts.float().sum()) return weights / weights.sum() * num_classes # 归一化 # 假设训练集中3个类别的样本数分别为100, 30, 20 train_labels torch.cat([ torch.zeros(100), torch.ones(30), torch.full((20,), 2) ]).long() weights calculate_weights(train_labels) print(f自动计算权重: {weights})2.3 类别平衡权重在极端不平衡场景下可以使用更激进的平衡策略def balanced_weights(train_labels, beta0.9): class_counts torch.bincount(train_labels) effective_num 1.0 - torch.pow(beta, class_counts) weights (1.0 - beta) / effective_num return weights / weights.sum() * len(weights) weights balanced_weights(train_labels) print(f平衡权重: {weights})三种权重计算方式对比表方法类型优点缺点适用场景手动指定灵活可控依赖领域知识类别重要性明确自动计算数据驱动对极端少数类敏感一般不平衡数据平衡权重强调少数类可能过度补偿极端不平衡数据3. 标签平滑技术解析与实现标签平滑(Label Smoothing)是一种正则化技术通过软化one-hot编码来防止模型对标签的过度自信。其数学表达为$$ y (1 - \alpha) \times y \alpha / K $$其中$K$是类别数$\alpha$是平滑系数。3.1 基础实现PyTorch 2.0直接支持label_smoothing参数criterion nn.CrossEntropyLoss(label_smoothing0.1) # 等效手动实现 def smooth_one_hot(labels, alpha, num_classes): smoothed torch.full((labels.size(0), num_classes), alpha / (num_classes-1)) smoothed.scatter_(1, labels.unsqueeze(1), 1.0 - alpha) return smoothed smoothed_targets smooth_one_hot(targets, 0.1, 3)3.2 与权重的组合使用标签平滑可以与权重参数协同工作criterion nn.CrossEntropyLoss( weighttorch.tensor([1.0, 2.0, 1.5]), label_smoothing0.1 )3.3 不同平滑系数的效果对比我们通过一个简单的实验观察不同$\alpha$值的影响import matplotlib.pyplot as plt def test_smoothing_effects(logits, targets): alphas [0, 0.05, 0.1, 0.2, 0.3] losses [] for alpha in alphas: criterion nn.CrossEntropyLoss(label_smoothingalpha) loss criterion(logits, targets) losses.append(loss.item()) plt.plot(alphas, losses, markero) plt.xlabel(Smoothing Alpha) plt.ylabel(Loss Value) plt.title(Label Smoothing Effect on Loss) plt.grid(True) plt.show() test_smoothing_effects(logits, targets)典型情况下损失值会随$\alpha$增大而先降后升最优值通常在0.05-0.2之间。4. 完整训练案例对比现在我们实现一个完整的图像分类训练流程对比不同参数配置的效果。使用CIFAR-10数据集人为制造类别不平衡import torchvision from torch.utils.data import WeightedRandomSampler # 创建不平衡的CIFAR-10数据集 transform torchvision.transforms.Compose([ torchvision.transforms.ToTensor(), torchvision.transforms.Normalize((0.5,0.5,0.5), (0.5,0.5,0.5)) ]) dataset torchvision.datasets.CIFAR10(root./data, trainTrue, downloadTrue, transformtransform) # 人为制造不平衡各类别样本数指数递减 class_counts [5000] [5000 // (2**i) for i in range(1,10)] print(各类别样本数:, class_counts) # 创建带权重的DataLoader weights 1. / torch.tensor(class_counts, dtypetorch.float) samples_weights weights[torch.tensor(dataset.targets)] sampler WeightedRandomSampler(samples_weights, len(samples_weights)) train_loader torch.utils.data.DataLoader(dataset, batch_size64, samplersampler)定义测试函数def train_and_evaluate(criterion, epochs10): model torchvision.models.resnet18(num_classes10) optimizer torch.optim.Adam(model.parameters(), lr1e-3) train_losses [] accuracies [] for epoch in range(epochs): model.train() total_loss 0 for inputs, labels in train_loader: optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() total_loss loss.item() # 评估 model.eval() correct 0 total 0 with torch.no_grad(): for inputs, labels in test_loader: outputs model(inputs) _, predicted torch.max(outputs.data, 1) total labels.size(0) correct (predicted labels).sum().item() acc correct / total train_losses.append(total_loss/len(train_loader)) accuracies.append(acc) print(fEpoch {epoch1}: Loss{train_losses[-1]:.4f}, Acc{acc:.4f}) return train_losses, accuracies配置对比实验# 实验配置 configs [ {name: Baseline, criterion: nn.CrossEntropyLoss()}, {name: Weighted, criterion: nn.CrossEntropyLoss(weightweights)}, {name: Smoothing(0.1), criterion: nn.CrossEntropyLoss(label_smoothing0.1)}, {name: WeightedSmoothing, criterion: nn.CrossEntropyLoss(weightweights, label_smoothing0.1)} ] # 运行实验 results {} for config in configs: print(f\nRunning {config[name]}...) losses, accs train_and_evaluate(config[criterion]) results[config[name]] {loss: losses, acc: accs}可视化结果plt.figure(figsize(12,5)) plt.subplot(1,2,1) for name, res in results.items(): plt.plot(res[loss], labelname) plt.xlabel(Epoch) plt.ylabel(Training Loss) plt.legend() plt.subplot(1,2,2) for name, res in results.items(): plt.plot(res[acc], labelname) plt.xlabel(Epoch) plt.ylabel(Test Accuracy) plt.legend() plt.tight_layout() plt.show()典型实验结果会显示加权方法能显著提升少数类的识别率标签平滑有助于提高最终准确率组合使用可能获得最佳平衡5. 高级技巧与注意事项5.1 权重归一化当使用较大权重值时建议进行归一化以避免梯度爆炸weights weights / weights.sum() * len(weights)5.2 动态权重调整在训练过程中可以动态调整权重def dynamic_weight_adjustment(epoch, max_epoch): base_weights torch.tensor([...]) # 基础权重 # 随训练进程逐渐降低权重影响 factor 1.0 - min(epoch / max_epoch, 0.8) return base_weights * factor5.3 标签平滑与MixUp的结合MixUp数据增强与标签平滑有协同效应def mixup_data(x, y, alpha0.2): lam np.random.beta(alpha, alpha) batch_size x.size(0) index torch.randperm(batch_size) mixed_x lam * x (1 - lam) * x[index] y_a, y_b y, y[index] return mixed_x, y_a, y_b, lam # 在训练循环中 inputs, targets_a, targets_b, lam mixup_data(inputs, targets) outputs model(inputs) loss lam * criterion(outputs, targets_a) (1 - lam) * criterion(outputs, targets_b)5.4 类别权重与学习率对于高权重类别可以相应降低学习率optimizer torch.optim.SGD([ {params: model.base.parameters()}, {params: model.classifier.parameters(), lr: 1e-3 * weights.mean()} ], lr1e-3)

相关新闻

UE4SS深度解析:从DLL注入到Lua脚本,解锁虚幻引擎游戏模组开发

UE4SS深度解析:从DLL注入到Lua脚本,解锁虚幻引擎游戏模组开发

1. 项目概述:UE4SS是什么,以及为什么你需要它如果你正在折腾虚幻引擎4或5的游戏,无论是想做个简单的修改,还是开发一个功能完整的模组,你大概率都听说过UE4SS。它不是一个具体的模组,而是一个强大的“脚本系…

2026/7/9 23:50:00阅读更多 →
VSCode集成Claude Opus的合法工作流重建指南

VSCode集成Claude Opus的合法工作流重建指南

1. 这不是“接入API”,而是重建本地AI工作流的信任链 你搜到的标题里写着“Claude Opus 4.6 接入 VSCode 自定义 API 教程”,但我要先说一句实话: Anthropic 官方从未开放过 Claude Opus 模型的直接 API 调用权限,更不存在所谓“…

2026/7/9 23:44:52阅读更多 →
电动汽车充电设备 GB/T 18487.1-2015 绝缘与防护:4类测试电压与2种SPD选型场景

电动汽车充电设备 GB/T 18487.1-2015 绝缘与防护:4类测试电压与2种SPD选型场景

电动汽车充电设备安全合规实战指南:GB/T 18487.1-2015绝缘防护与雷电防护深度解析充电设备的安全性直接关系到用户生命财产安全和电网稳定运行。GB/T 18487.1-2015作为电动汽车充电设备的基础标准,其绝缘防护和雷电防护要求是产品设计的核心难点。本文将…

2026/7/9 23:44:52阅读更多 →
S16.2第一性原理做产品(2):从《从0到1》看AI创业——在“能做“通胀时代,找到你的秘密

S16.2第一性原理做产品(2):从《从0到1》看AI创业——在“能做“通胀时代,找到你的秘密

第一性原理做产品(2):从《从0到1》看AI创业——在"能做"通胀时代,找到你的秘密 本文是专栏「第一性原理做产品:AI时代从"能做"到"做好"的破局之道」第2篇。Peter Thiel说"竞争是失…

2026/7/10 0:55:06阅读更多 →
Ralph Loop 实践解析:300行代码写个编码Agent的背后逻辑与边界

Ralph Loop 实践解析:300行代码写个编码Agent的背后逻辑与边界

Ralph Loop 实践解析:300行代码写个编码Agent的背后逻辑与边界 先说结论Ralph Loop的核心是“刻意遗忘”和最小上下文,让agent长时间循环运行而非一次性生成。它最适合语言移植、小范围修复等任务,但不适用于需要全局理解的架构级改造。代码审…

2026/7/10 0:55:06阅读更多 →
3分钟搞定抖音批量下载:douyin-downloader的终极使用指南

3分钟搞定抖音批量下载:douyin-downloader的终极使用指南

3分钟搞定抖音批量下载:douyin-downloader的终极使用指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback su…

2026/7/10 0:55:06阅读更多 →
Docker 网段冲突实战:3步修改默认网桥 docker0 至 192.168.100.0/24

Docker 网段冲突实战:3步修改默认网桥 docker0 至 192.168.100.0/24

Docker 网段冲突实战:3步修改默认网桥 docker0 至 192.168.100.0/24在企业级 Docker 部署中,网络规划往往是技术团队容易忽视的环节。当 Docker 默认的 172.17.0.0/16 网段与企业内网发生冲突时,容器与宿主机间的通信会突然中断,这…

2026/7/10 0:55:06阅读更多 →
AI 数据分析脚手架:一个 Prompt 模板管一类分析场景

AI 数据分析脚手架:一个 Prompt 模板管一类分析场景

AI 数据分析脚手架:一个 Prompt 模板管一类分析场景 一、每次分析都"重写 Prompt"的困境 先问一个问题:你上一次在 ChatGPT 或 Claude 里做数据分析时,花了多少时间写 Prompt? 我统计了一下我们团队的数据&#xff1…

2026/7/10 0:55:06阅读更多 →
ChatGPT GPTs商店上线前必做的7项合规检查:GDPR/数据主权/模型版权三重红线预警

ChatGPT GPTs商店上线前必做的7项合规检查:GDPR/数据主权/模型版权三重红线预警

更多请点击: https://codechina.net 第一章:ChatGPT GPTs商店上线前的合规性总览 在GPTs商店正式向公众开放前,OpenAI要求所有开发者完成一系列强制性合规审查流程,涵盖数据隐私、内容安全、知识产权及地域监管适配四大维度。这些…

2026/7/10 0:50:06阅读更多 →
从GitHub安全案例解析常见漏洞与防护实践

从GitHub安全案例解析常见漏洞与防护实践

1. 项目概述:从GitHub Trending看安全实战 最近在GitHub Trending上看到一个项目,叫 skills4/skills ,它因为一些安全漏洞案例被大家讨论。这其实是一个挺典型的场景:一个旨在展示或教授某种技能的仓库,本身却成了安…

2026/7/9 5:56:19阅读更多 →
MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

MLT 2026启示:因果推理与概率建模驱动下一代LLM应用

# MLT 2026启示:因果推理与概率建模驱动下一代LLM应用## 一、背景与挑战:从“黑箱预测”到“可信推理”2026年6月,第7届机器学习与趋势国际会议(MLT 2026)将在悉尼召开。会议议程中,“因果与可解释机器学习…

2026/7/9 9:45:20阅读更多 →
通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

通达OA SQL注入漏洞深度剖析:从手工注入到自动化利用与防御

1. 项目概述与漏洞背景最近在梳理一些历史OA系统的安全风险时,通达OA v11.6版本中的一个老漏洞又进入了我的视线。这个漏洞位于/general/bi_design/appcenter/report_bi.func.php文件中,是一个典型的SQL注入点。虽然这个漏洞的利用方式看起来并不复杂&am…

2026/7/9 2:47:07阅读更多 →
浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比

浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比

浏览器缓存行为深度解析:Chrome/Firefox/Safari 对 304 响应的 5 种触发场景对比当你在浏览器地址栏敲入一个网址时,背后可能隐藏着一场关于"要不要重新下载资源"的精密博弈。这场博弈的裁判是HTTP缓存机制,而304状态码则是这场博弈…

2026/7/10 0:00:01阅读更多 →
RoboWits:面向创造性问题求解的双臂机器人认知推理基准

RoboWits:面向创造性问题求解的双臂机器人认知推理基准

1. 项目概述:这不是又一个机器人抓取数据集,而是一次对“思考力”的压力测试 RoboWits——这个名字里藏着两个关键信号:“Robo”直指物理世界中的具身智能体,“Wits”则毫不掩饰地指向人类最核心的认知能力:机敏、判断…

2026/7/10 0:00:01阅读更多 →
5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能

5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能

5分钟完全指南:如何使用TegraRcmGUI图形化工具解锁Switch无限可能 【免费下载链接】TegraRcmGUI C GUI for TegraRcmSmash (Fuse Gele exploit for Nintendo Switch) 项目地址: https://gitcode.com/gh_mirrors/te/TegraRcmGUI TegraRcmGUI是一款专为Windows…

2026/7/10 0:00:01阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/9 9:45:20阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/9 15:50:44阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/9 14:14:17阅读更多 →