辽宁网站建设上海网站建设的

青岛悦航教育科技有限公司 2026/09/09 19:01:06

本文讨论了深度学习中常用的损失函数,包括交叉熵损失函数、余弦相似度损失函数和双曲余弦对数损失函数,并对它们在PyTorch中的应用细节进行了介绍,通过MNIST手写体数字识别实验展示它们的应用。损失函数有很多,读者可以在了解基本知识的基础上,要求AI大模型给出相关损失函数的原理细节,并给出相应的应用代码供使用或参考。

本专栏之三中简要讨论了损失函数的概念及最容易理解的损失函数MSE,MSE是基于欧氏距离的损失函数。多层神经网络中常用的损失函数还有KL(Kullback-Leibler Divergence)散度损失函数、交叉熵(Crossentropy)损失函数、余弦相似度损失函数、双曲余弦对数(logarithm of the hyperbolic cosine)损失函数等。

了解不同损失函数对优化的影响,以及它们应用的特点,是设计深度学习模型、指导AI大模型调整模型的重要知识。

本文还进一步讨论了凸函数理论,供想深入研究的读者参考。

1.相对熵损失函数和交叉熵损失函数

交叉熵可以用来衡量两个分布之间的差距,还是以示例入手讨论。

在本专栏之五的讨论误差反向传播学习算法时,使用了一个用神经网络模拟异或运算的例子,其中使用的示例的最后预测输出与实际标签值的对比如下:

a)[ 0.07158904 0.92822515 ] -> [ 0. 1.]

b)[ 0.9138734 0.08633152 ] -> [ 1. 0.]

c)[ 0.91375259 0.08644981 ] -> [ 1. 0.]

d)[ 0.11774177 0.88200493 ] -> [ 0. 1.]

对于a和d两项输出,标签值都是[ 0. 1.],直观来看a的预测应该更准一些。如何形式化地度量它们与标签值的差距呢?

将预测输出值看作概率,如 a 项中,预测为 1 的概率为 0.07158904,预测为 0 的概率为 0.92822515。

信息熵(有关信息熵及其在机器学习领域中的应用,可参考文献[1]中的4.1节)的定义为:H(X)=−∑i=1npilog⁡piH(X) = -sum_{i=1}^n p_i log p_iH(X)=i=1npilogpi。用pip_ipi表示第 i 个输出的标签值,即真实值,用qiq_iqi表示第 i 个输出值,即预测值。将它们都视为概率值,pip_ipiqiq_iqi之间的对数差在pip_ipi上的期望值称为相对熵:
DKL(p∣∣q)=Ep(log⁡pi−log⁡qi)=∑i=1npi(log⁡pi−log⁡qi)=∑i=1npilog⁡piqi(式10-1) D_{KL}(p||q) = E_p(log p_i - log q_i) = sum_{i=1}^n p_i (log p_i - log q_i)=sum_{i=1}^n p_i log frac{p_i}{q_i} ag{式10-1}DKL(p∣∣q)=Ep(logpilogqi)=i=1npi(logpilogqi)=i=1npilogqipi(10-1)
将上述与熵的定义式进行对比,可见是用log⁡qi−log⁡pilog q_i - log p_ilogqilogpi代替了log⁡pilog p_ilogpi,用来度量两个分布之间的差异。计算 a 和 d 两项输出的相对熵:

Da=0×log⁡00.07158904+1×log⁡10.92822515=0.07447962 D_a = 0 imes log frac{0}{0.07158904} + 1 imes log frac{1}{0.92822515} = 0.07447962Da=0×log0.071589040+1×log0.928225151=0.07447962

Dd=0×log⁡00.11774177+1×log⁡10.88200493=0.12555622 D_d = 0 imes log frac{0}{0.11774177} + 1 imes log frac{1}{0.88200493} = 0.12555622Dd=0×log0.117741770+1×log0.882004931=0.12555622

式中,0×log⁡00 imes log 00×log0计为 0。

可见,与直接观察的结论相同。相对熵越大的输出与标签值差距越大。如果pip_ipiqiq_iqi相同,那么DKL(p∣∣q)=0D_{KL}(p||q) = 0DKL(p∣∣q)=0

值得注意的是,相对熵不具有对称性。相对熵又称为 KL 散度。

将相对熵的定义式 10-1 进一步展开:

DKL(p∣∣q)=∑i=1npi(log⁡pi−log⁡qi) D_{KL}(p||q) = sum_{i=1}^{n} p_i(log p_i - log q_i)DKL(p∣∣q)=i=1npi(logpilogqi)

=∑i=1npilog⁡pi+[−∑i=1npilog⁡qi](式10-2) = sum_{i=1}^{n} p_ilog p_i + left[ -sum_{i=1}^{n} p_ilog q_i ight] ag{式10-2}=i=1npilogpi+[i=1npilogqi](10-2)

=−H(pi)+[−∑i=1npilog⁡qi] = -H(p_i) + left[ -sum_{i=1}^{n} p_ilog q_i ight]=H(pi)+[i=1npilogqi]

前一项正好是标签分布熵的负值,保持不变,因此一般用后一项作为两个分布之间差异的度量,称为交叉熵:

H(p,q)=−∑i=1npilog⁡qi(式10-3) H(p,q) = -sum_{i=1}^{n} p_ilog q_i ag{式10-3}H(p,q)=i=1npilogqi(10-3)

如果只有正负两个分类(标签记为 1 和 0),记第iii个输出的标签值为yiy_iyi,记它被预测为正类的概率为pip_ipi,那么上式为:

H(y,p)=−1n∑i=1n[yilog⁡pi+(1−yi)log⁡(1−pi)] H(y,p) = -frac{1}{n}sum_{i=1}^{n} [y_ilog p_i + (1-y_i)log(1-p_i)]H(y,p)=n1i=1n[yilogpi+(1yi)log(1pi)]

交叉熵损失函数在梯度下降法中可以改善 MSE 学习速率降低的问题,得到了广泛的应用。

PyTorch中实现的交叉熵损失函数有:多分类交叉熵损失函数torch.nn.CrossEntropyLoss()、 二元交叉熵损失函数torch.nn.BCELoss()和带Sigmoid的二元交叉熵损失函数torch.nn.BCEWithLogitsLoss()等,实现KL散度损失函数的有:torch.nn.KLDivLoss()。使用CrossEntropyLoss()时,不需要提前将标签值转换成独热编码,这是使用它的一个便利特性。

仍然采用MNIST数据集进行手写体数字识别实验示例如代码10-1.1 所示,采用SGD优化方法,三层分别采用relu、relu和softmax激活函数,训练 10 轮,不同的损失函数会有不同的识别率。要注意的是,本示例仅示意各损失函数的差异,并没有严格地定义实验条件,因此结果并不具备广泛性。

代码10-1.1 损失函数应用示例

### 1.导入和设置环境importtorchimporttorch.nnasnnimporttorch.optimasoptimfromtorch.utils.dataimportDataLoader,TensorDatasetimportdatetimefromtorchvisionimportdatasets,transforms# 设置随机种子torch.manual_seed(0)### 2.训练样本和验证样本数据预处理# 数据预处理方式transform=transforms.Compose([transforms.ToTensor(),# 转换为 torch.Tensor])# 加载MNIST数据集train_dataset=datasets.MNIST('./data',train=True,download=True,transform=transform)val_dataset=datasets.MNIST('./data',train=False,transform=transform)# 样本拉平、归一化后X_train=train_dataset.data.float().view(-1,784)/255.0y_train=train_dataset.targets X_val=val_dataset.data.float().view(-1,784)/255.0y_val=val_dataset.targets# 转换为独热编码y_train=torch.nn.functional.one_hot(y_train,num_classes=10).float()y_val=torch.nn.functional.one_hot(y_val,num_classes=10).float()# 创建数据加载器batch_size=200train_loader=DataLoader(TensorDataset(X_train,y_train),batch_size=batch_size,shuffle=True)val_loader=DataLoader(TensorDataset(X_val,y_val),batch_size=batch_size)### 3.定义神经网络模型# relu-relu-softmaxclassMNISTModel(nn.Module):def__init__(self):super(MNISTModel,self).__init__()self.fc1=nn.Linear(784,784)self.fc2=nn.Linear(784,784)self.fc3=nn.Linear(784,10)self.relu=nn.ReLU()self.softmax=nn.Softmax()defforward(self,x):x=self.relu(self.fc1(x))x=self.relu(self.fc2(x))x=self.softmax(self.fc3(x))returnx### 4.采用不同的损失函数进行对比试验criterion=nn.CrossEntropyLoss()# 定义损失函数model=MNISTModel()# 实例化模型类得到模型对象optimizer=optim.SGD(model.parameters(),lr=0.15)# 定义优化器# 训练模型,开始计时start_time=datetime.datetime.now()epochs=10forepochinrange(epochs):# 每轮中的训练model.train()train_loss=0.0forbatch_X,batch_yintrain_loader:optimizer.zero_grad()outputs=model(batch_X)loss=criterion(outputs,batch_y)loss.backward()optimizer.step()train_loss+=loss.item()# 看一下该轮训练后的效果model.eval()correct=0total=0withtorch.no_grad():forbatch_X,batch_yintrain_loader:outputs=model(batch_X)_,predicted=torch.max(outputs.data,1)# 模型预测值的独热编码_,labels=torch.max(batch_y.data,1)# 真实标签值的独热编码total+=labels.size(0)correct+=(predicted==labels).sum().item()# 准确率print(f'Epoch{epoch+1}/{epochs}, 对训练样本进行预测的准确率(Train Acc):{100*correct/total:.2f}%')# 训练结束,终止计时end_time=datetime.datetime.now()print(f"训练用时:{end_time-start_time}")

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 64.97% Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 82.14% Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 83.63% Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 84.34% Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 84.81% Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 91.00% Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 91.88% Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 92.22% Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 93.04% Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 93.51% 训练用时: 0:01:25.518433

通过设置MSE损失函数、多分类交叉熵损失函数、二元交叉熵损失函数、带Sigmoid的二元交叉熵损失函数BCEWithLogitsLoss损失函数、KL散度损失函数进行试验,对训练样本的预测准确率为:89.14%、93.51%、93.23%、68.93%、56.66%,详见本文所附代码文件。

交叉熵系列损失函数中,还可以通过设置weight和pos_weight参数来处理样本类别不平衡的问题。样本类别不平衡问题详见本专栏之九的文章。

2.余弦相似度损失函数

余弦相似度刻画的是两个向量之间的夹角,它适合于与向量方向相关的距离度量。

设特征空间Xmathcal{X}Xnnn维实数向量空间Rnmathbb{R}^nRn,点xi,xj∈Xmathbf{x}_i , mathbf{x}_j in mathcal{X}xi,xjXxi=(xi,1,xi,2,…,xi,m)mathbf{x}_i = (x_{i,1}, x_{i,2}, dots, x_{i,m})xi=(xi,1,xi,2,,xi,m)xj=(xj,1,xj,2,…,xj,m)mathbf{x}_j = (x_{j,1}, x_{j,2}, dots, x_{j,m})xj=(xj,1,xj,2,,xj,m)

xi,xjmathbf{x}_i, mathbf{x}_jxi,xj的余弦相似度为:
cos⁡θ=xi⋅xj∥xi∥∥xj∥=∑k=1nxi(k)xj(k)∑k=1n(xi(k))2∑k=1n(xj(k))2(式10-4) cos heta = frac{mathbf{x}_i cdot mathbf{x}_j}{|mathbf{x}_i||mathbf{x}_j|} = frac{sum_{k=1}^n x_i^{(k)} x_j^{(k)}}{sqrt{sum_{k=1}^n (x_i^{(k)})^2} sqrt{sum_{k=1}^n (x_j^{(k)})^2}} quad ag{式10-4}cosθ=xi∥∥xjxixj=k=1n(xi(k))2k=1n(xj(k))2k=1nxi(k)xj(k)(10-4)
将标签和预测看作值向量,可用式10-4计算得到余弦相似度作为损失函数(Cosine Similarity Loss)。

余弦相似度损失函数主要用于需要衡量向量方向一致性的任务,特别适用于处理高维特征且关注相对关系的场景,主要有图像分类与人脸识别、文本检索与语义匹配‌、推荐系统‌等。

使用余弦相似度损失函数的示例如代码10-1.2所示。

代码10-1.2 余弦相似度损失函数应用示例

### 使用余弦相似度损失函数需要先自定义一个适配器classCosineLossAdapter(nn.Module):def__init__(self,margin=0.5):super(CosineLossAdapter,self).__init__()self.cosine_loss=nn.CosineEmbeddingLoss(margin=margin)defforward(self,predictions,targets):# CosineEmbeddingLoss需要两个输入张量和一个目标张量# 我们将预测视为第一个输入,目标视为第二个输入# 目标标签设为1(表示我们希望它们相似)target_labels=torch.ones(predictions.size(0)).to(predictions.device)# 计算损失loss=self.cosine_loss(predictions,targets,target_labels)returnloss criterion=CosineLossAdapter(margin=0.5)# 使用适配器model=MNISTModel()# 实例化模型类得到模型对象optimizer=optim.SGD(model.parameters(),lr=0.15)# 定义优化器# 训练模型,开始计时start_time=datetime.datetime.now()epochs=10forepochinrange(epochs):# 每轮中的训练model.train()train_loss=0.0forbatch_X,batch_yintrain_loader:optimizer.zero_grad()outputs=model(batch_X)loss=criterion(outputs,batch_y)# 现在只需要两个参数loss.backward()optimizer.step()train_loss+=loss.item()# 看一下该轮训练后的效果model.eval()correct=0total=0withtorch.no_grad():forbatch_X,batch_yintrain_loader:outputs=model(batch_X)_,predicted=torch.max(outputs.data,1)# 模型预测值的独热编码_,labels=torch.max(batch_y.data,1)# 真实标签值的独热编码total+=labels.size(0)correct+=(predicted==labels).sum().item()# 准确率print(f'Epoch{epoch+1}/{epochs}, 对训练样本进行预测的准确率(Train Acc):{100*correct/total:.2f}%')# 训练结束,终止计时end_time=datetime.datetime.now()print(f"训练用时:{end_time-start_time}")

输出:

Epoch 1/10, 对训练样本进行预测的准确率(Train Acc): 89.40% Epoch 2/10, 对训练样本进行预测的准确率(Train Acc): 91.37% Epoch 3/10, 对训练样本进行预测的准确率(Train Acc): 92.52% Epoch 4/10, 对训练样本进行预测的准确率(Train Acc): 93.10% Epoch 5/10, 对训练样本进行预测的准确率(Train Acc): 93.67% Epoch 6/10, 对训练样本进行预测的准确率(Train Acc): 94.39% Epoch 7/10, 对训练样本进行预测的准确率(Train Acc): 94.86% Epoch 8/10, 对训练样本进行预测的准确率(Train Acc): 95.37% Epoch 9/10, 对训练样本进行预测的准确率(Train Acc): 95.69% Epoch 10/10, 对训练样本进行预测的准确率(Train Acc): 96.10% 训练用时: 0:01:13.835299

3. 双曲余弦对数损失函数

双曲余弦对数(Log-Cosh Loss)的计算方法为:
log⁡cosh⁡(p,q)=∑i=1nlog⁡(eqi−pi+e−(qi−pi)2)=∑i=1nlog⁡(eqi−pi⋅(1+e−2(qi−pi))/2)=∑i=1n[log⁡(eqi−pi)+log⁡(1+e−2(qi−pi))−log⁡(2)]=∑i=1n[(qi−pi)+log⁡(1+e−2(qi−pi))−log⁡(2)]=∑i=1n[(qi−pi)+softplus(−2(qi−pi))−log⁡(2)](式10-5) egin{align*} log cosh(p, q) &= sum_{i=1}^n logleft(frac{e^{q_i - p_i} + e^{-(q_i - p_i)}}{2} ight) \ &=sum_{i=1}^n log(e^{q_i - p_i} cdot (1 + e^{-2(q_i - p_i)})/2) \ &=sum_{i=1}^n [ log(e^{q_i - p_i}) + log(1 + e^{-2(q_i - p_i)}) - log(2)] \ &=sum_{i=1}^n [ (q_i - p_i) + log(1 + e^{-2(q_i - p_i)}) - log(2) ]\ &=sum_{i=1}^n [ (q_i - p_i) + ext{softplus}(-2(q_i - p_i)) - log(2)] end{align*} ag{式10-5}logcosh(p,q)=i=1nlog(2eqipi+e(qipi))=i=1nlog(eqipi(1+e2(qipi))/2)=i=1n[log(eq

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

海南网站建设网站建设解决方案

大语言模型GPU部署全攻略:从零配置到生产级优化【免费下载链接】DeepSeek-LLMDeepSeek LLM: Let there be answers项目地址: https://g

2026/06/30 12:04:59

pc网站建设郴州网站建设

SMAPI终极指南:快速掌握星露谷物语模组开发API【免费下载链接】SMAPIThe modding API for Stardew Valley.项目地址: https://gitco

2026/06/30 13:51:07

网站建设制作网站建设专家

终极LaTeX模板指南:3小时搞定国家自然科学基金申请【免费下载链接】iNSFCAn awesome LaTeX template for NSFC proposal.项目地址: htt

2026/06/30 10:34:50

郴州网站建设网站建设基本流程

1. 为什么这个毕设项目值得你 pick ?毕设无需从零敲!该系统基于Java语言和SpringMVC开发框架,采用MySQL数据库进行数据管理。其主要功能模块包括会员账户

2026/06/30 12:35:02

苏州网站建设绵阳网站建设

Fashion-MNIST实战指南:从入门到精通的计算机视觉数据集深度解析【免费下载链接】fashion-mnistfashion-mnist - 提供了一个替代MNIST的时尚产品图片

2026/06/30 13:30:36

网站建设系统住房和城乡建设部网站

还在为字幕与语音不同步而烦恼吗?🤔 精心制作的视频,却因为字幕时间轴错位而显得不够专业?作为内容创作者,精准的字幕对齐直接影响观

2026/06/30 14:19:39

中山网站建设岳阳网站建设

5步搭建专属AI工作流:零代码自托管解决方案全揭秘【免费下载链接】self-hosted-ai-starter-kitThe Self-hosted AI Starter Kit is

2026/06/30 11:27:25

网站建设模板服装网站建设

一、明确核心定位:发挥Java的工程化优势1. 专注大模型能力封装与集成Java程序员的核心竞争力在于企业级系统架构能力。应重点将大模型作为“工具”嵌入现有业务系统,例如&

2026/06/30 12:16:00

贵阳网站建设晋江网站建设

从踩坑到精通:Nx 调试实战指南(新手避坑全记录)你有没有经历过这样的场景?刚写完代码,信心满满地敲下nx serve myapp

2026/06/30 11:01:53

深圳外贸网站建设asp网站建设

在当今数字化时代,人脸识别技术已经深入到我们生活的方方面面,从家庭安防到企业门禁,从社交媒体到智能家居。然而,不同的人脸识别软件各有特色

2026/06/30 13:45:37