深度学习之——损失函数(loss)

article/2025/10/28 13:16:36

深度学习中的所有学习算法都必须有一个 最小化或最大化一个函数,称之为损失函数(loss function),或“目标函数”、“代价函数”。损失函数是衡量模型的效果评估。比如:求解一个函数最小点最常用的方法是梯度下降法:梯度下降详解

(比如:全批量梯度下降 Batch GD、随机梯度下降 SGD、小批量梯度下降 mini-batch GD、Adagrad法,Adadelta法、Adam法等)。损失函数就像起伏的山,梯度下降就像从山上滑下来到达最底部的点。

显然,不存在一个损失函数可以适用于所有的任务。损失函数的选择需要取决于很多因素,其中包括异常值的处理、深度学习算法的选择、梯度下降的时间效率等。本文的目的介绍损失函数,以及它们的基本原理。

损失函数(Loss_function):

在前面的学习中我们学习过机器学习模型(分类、回归、聚类,降维):机器学习基本模型介绍,在深度学习中:损失函数严格上可分为两类:分类损失回归损失,其中分类损失根据类别数量又可分为二分类损失多分类损失。在使用的时候需要注意的是:回归函数预测数量,分类函数预测标签。

1、均方差损失(MSE)

均方差 Mean Squared Error (MSE) 损失是机器学习、深度学习回归任务中最常用的一种损失函数。从直觉上理解均方差损失,这个损失函数的最小值为 0(当预测等于真实值时),最大值为无穷大。MSE就是计算预测值和真实值之间的欧式距离。预测值和真实值越接近,两者的均方差就越小,均方差函数常用于线性回归(linear regression),即函数拟合(function fitting)。

均方差损失函数是预测数据和原始数据对应点误差的平方和的均值,公式为:

MSE=\frac{1}{N}(\hat{y}-y)^{2}

N:样本个数,\hat{y}:样本真实值,y为输出值

MSE代码实现:

import torch.nn as nn
import torch
import random
#MSE损失参数
# loss_fun=nn.MSELoss(size_average=None, reduce=None, reduction='mean')
input=torch.randn(10)#定义输出(随机的1,10的数组)可以理解为概率分布
#tensor([-0.0712,  1.9697,  1.4352, -1.3250, -1.1089, -0.5237,  0.2443, -0.8244,0.2344,  2.0047])
print(input)
target= torch.zeros(10)#定义标签
target[random.randrange(10)]=1#one-hot编码
#tensor([0., 0., 0., 0., 0., 0., 0., 1., 0., 0.])
print(target)
loss_fun= nn.MSELoss()
output = loss_fun(input, target)#输出,标签
print(output)#loss:tensor(0.8843)#=============不用nn.MSELoss实现均方差===================
result=(input-target)**2
result =sum(result)/len(result)#求和之后求平均
print(result)#tensor(0.8843)
#其结果和上面一样

注意:若多分类任务中要使用均方差作为损失函数,需要将标签转换成one-hot编码形式:one-hot编码,这与交叉熵损失函数恰巧相反。均方差不宜和sigmoid函数一起使用(sigmoid函数有一个特点,那就是横坐标越远离坐标原点,导数越接近于0,当输出越接近1时导数越小,最终会造成梯度消失。)

2、交叉熵损失(Cross Entropy)

关于交叉熵损失函数的来厉和介绍我在这篇文章里有详细阐述:深度学习入门理解——从概率和信息的角度(数学篇后记)

我们现在可以这样它理解:在机器学习中,使用KL散度就可以评价真实标签与预测标签间的差异,但由于KL散度的第一项是个定值,故在优化过程中只关注交叉熵就可以了。一般大多数机器学习算法会选择交叉熵作为损失函数。

根据交叉熵的公式:

H(p,q)=-\sum _{i=1}^{n}p(x_{i})\log q(x_{i})

p(x_{i})代表真实标签,在真实标签中,除了对应类别其它类别的概率都为0,所以可以简写为:

H(p,q)=-logq(x_{class})

这里的x_{class}代表标签(label)

Cross Entropy代码实现:

#交叉熵
import torch.nn as nn
nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='mean')
import torch
import torch.nn as nn
# #假设batch size为4,待分类标签有3个,隐藏层的输出为:
input = torch.tensor([[ 0.8082,  1.3686, -0.6107],#1[ 1.2787,  0.1579,  0.6178],#0[-0.6033, -1.1306,  0.0672],#2[-0.7814,  0.1185, -0.2945]])#取1
target = torch.tensor([1,0,2,1])#假设标签值(不是one-hot编码,直接代表类别)
loss = nn.CrossEntropyLoss()#定义交叉熵损失函数(自带softmax输出函数)
output = loss(input, target)
print(output)#tensor(0.6172)#======不用 nn.CrossEntropyLoss(),解释其计算方法======
net_out=nn.Softmax(dim=1)(input)#input前面已经定义
print(net_out)
out= torch.log(net_out)#对每个size(每行求log)
"""
tensor([[-1.0964, -0.5360, -2.5153],[-0.6111, -1.7319, -1.2720],[-1.2657, -1.7930, -0.5952],[-1.6266, -0.7267, -1.1397]])
"""
print(out)
#根据公式求和
out=torch.max(out,dim=1)#我们默认取每个size的输出最大值为类别
print(out)
"""
torch.return_types.max(
values=tensor([-0.5360, -0.6111, -0.5952, -0.7267]),
indices=tensor([1, 0, 2, 1]))
"""
#tages=(1,0,2,2),这里的输出out就是每一个size(样本)的交叉熵损失
#别忘了除以batch size(4),我们最后求得的是整个batch(批次,一批次4个样本)的平均loss
#out求和再除以size(4)————————求平均
out_Input=-torch.mean(out.values)#这里求平均时只取max输出的values
print(out_Input)#tensor(0.6172)

注意:除了torch.nn.CrosEntropyLoss()函数外还有一个计算交叉熵的函数torch.nn.BCELoss(),与前者不同,该函数是用来计算二项分布(0-1分布)的交叉熵(含sigmiod输出函数)。


总结:

由于本人现阶段能力有限,没办法对这两个函数进行细致的比较,也没有了解更多的损失函数,还望见谅,后面通过学习,我会慢慢完善。

总的来说MSE要得到一个线性的梯度,必须输出不经过激活函数才行。这样的情况只有线性回归,所以SE较适合做回归问题,而CE更适合做分类问题,在分类问题中,CE都能得到线性的梯度,能有效的防止梯度的消失;MSE作为分类问题的loss时,由于激活函数求导的影响,造成连续乘以小于1大于0的数造成梯度的消失,同时也使得error曲面变的崎岖,更慢的到的局部最优值。


http://chatgpt.dhexx.cn/article/CIJlaAWe.shtml

相关文章

1_一些文献中的英文解释和用法整理

目录 1、Theorem、Proposition、Lemma和Corollary等的解释与区别 2、论文里的 Preliminaries 究竟是什么意思? (1)Preliminaries是什么? (2)Preliminaries应该写什么内容? (3)…

区分定理(Theorem)、引理(Lemma)、推论(Corollary)等概念

ZZ: http://blog.sina.com.cn/s/blog_a0e53bf70101jwv1.html Theorem:就是定理,比較重要的,簡寫是 Thm。 Lemma:小小的定理,通常是為了證明後面的定理,如果證明的篇幅很長時,可能會把證明拆成幾…

CodeForces - 1364D Ehabs Last Corollary(dfs树找最小环)

题目链接:点击查看 题目大意:给出一个由 n 个结点和 m 条边构成的无向图,再给出一个 k ,需要在图中完成下面任意一种操作: 找到一个大小恰好为 的独立集找到一个大小不超过 k 的环 题目分析: 题目已经…

Codeforces Round 649 (Rated for Div. 2)D. Ehab s Last Corollary详细题解(图论+简单环)

树 边 : 树边: 树边:深度优先森林中的边。如果结点v是因对(u,v)的探索而首先被发现,则(u,v)是一条树边。 后 向 边 : 后向边: 后向边:后向边(u,v)是将结点u连接到其在深度优先树中一个祖先节点v的边. (本文我就称之为反向边了,问题不大) 前…

#649 (Div. 2)D. Ehab‘s Last Corollary

题目描述 Given a connected undirected graph with n vertices and an integer k, you have to either: either find an independent set that has exactly ⌈k2⌉ vertices. or find a simple cycle of length at most k. An independent set is a set of vertices such that…

Ehabs Last Corollary

Given a connected undirected graph with n n n vertices and an integer k k k, you have to either: either find an independent set that has exactly ⌈ k 2 ⌉ ⌈\frac{k}{2}⌉ ⌈2k​⌉ vertices.or find a simple cycle of length at most k k k. An independen…

Latent Variables的理解

加入我们有X,Y两个随机变量,他们的概率分布如下。要直接用一个函数还表示这个分布是比较困难的。 但我们发现这个分布可以分成三个聚类。如果我们给每个聚类编号为。 那么就是简单的高斯函数了。 这里z就是 加入latent variable的意义在于&#xff0c…

Variable(变量)

深度学习入门之PyTorch 作者 廖星宇

对条件变量(condition variable)的讨论

作者:王东 1.1 什么是条件变量和条件等待? 简单的说: 条件变量(condition variable)是利用线程间共享的全局变量进行同步的一种机制,主要包括两个动作:一个线程等待某个条件为真,而将自己挂起&…

C++ condition_variable用法

概述 condition_variable类似于信号量机制,实现了线程的等待和唤醒。 函数接口: wait() :阻塞等待的同时释放锁(原子操作),还可以添加阻塞判断函数,详见代码 notify_all() : 唤醒所有阻塞等待的线程 no…

variable命令两种不同的使用方式“v_“和““的区别

大家好,我是小马老师。 本文介绍variable命令两种不同的使用方式:“v_“和”&"。 在lammps模拟中,variable命令用的相对比较多,可以根据需要定义不同的变量。 在使用自定义变量或者调用自定义变量的时候,lamm…

条件变量(Condition Variable)详解

条件变量(Condtion Variable)是在多线程程序中用来实现“等待->唤醒”逻辑常用的方法。举个简单的例子,应用程序A中包含两个线程t1和t2。t1需要在bool变量test_cond为true时才能继续执行,而test_cond的值是由t2来改变的,这种情况下&#x…

Java Variable 变量

目录 变量1. 变量的作用域a. 类级变量b. 成员变量c. 局部变量 2. 基本数据类型a. 按内存占用级数b. 自动类型转换i. 十进制转二进制 c. 强制类型转换i. (XXX)ii. parseXXX() 3. 引用数据类型 变量 同时被 final 和 static 修饰的变量是常量。 1. 变量的作用域 变量的作用域分…

About Variables

Assessing Variable Types “It all began with a variable”, the storyteller began. Just kidding, no one starts their stories that way, even though variables are where all data stories begin. Variables define datasets. They are the characteristics or attr…

pytorch的Variable和Parameters的联系和区别

文章目录 前言一、Variable二、Parameter总结 前言 首先看一下官方文档: 一、Variable torch.autograd.Variable Variable是对Tensor的封装,操作与tensor基本一致,不同的是,每一个Variable被构建的时候,都包含三个…

关于variable的理解

引用莫烦大大的话来说,tensor是一个鸡蛋,而variable相当于一个篮子,把tensor装起来 其中variable有三个参数: data:存储了Tensor,是本体的数据 grad:保存了data的梯度,本事是个Varia…

深度学习——Variable(已经过时了!)

一、简介 深度学习中使用pytorch框架,使用的数据一般是torch中的tensor形式。但是在参数表示中,一般是用variable变量形式。 二、variable的使用 (1)如何将tensor转化为variable pytorch1.0之后tensor和variable没有区别了&am…

Pytorch的Variable详解

pytorch两个基本对象:Tensor(张量)和Variable(变量) 其中,tensor不能反向传播,variable可以反向传播。 tensor的算术运算和选取操作与numpy一样,一次你numpy相似的运算操作都可以迁…

13.2 用Patsy创建模型

1、patsy适合描述statsmodels的线性模型,其公式是一个特殊的字符串语法,表示为模型设计矩阵 2、patsy.dmatrices函数接收一个公式字符串和一个数据集,为线性模型设计矩阵 3、Pasty对象可以直接传递到算法,如下面的最小二乘回归 4、…

Could not find a version

目标检测—教你利用yolov5训练自己的目标检测模型 我自己的另一篇配置文件和代码地址博客总结 CondaHTTPError: HTTP 000 CONNECTION FAILED for url 的问题终极解决方案 配置环境 安装pytorch 利用Anaconda安装pytorch和paddle深度学习环境pycharm安装—免额外安装CUDA和c…