深度学习之常见损失函数(详细讲解定义、数学公式、实现代码)

 目录

前言


博主介绍:✌专注于前后端、机器学习、人工智能应用领域开发的优质创作者、秉着互联网精神开源贡献精神,答疑解惑、坚持优质作品共享。本人是掘金/腾讯云/阿里云等平台优质作者、擅长前后端项目开发和毕业项目实战,深受全网粉丝喜爱与支持✌有需要可以联系作者我哦!

🍅文末三连哦🍅

👇🏻 精彩专栏推荐订阅👇🏻 不然下次找不到哟

前言

损失函数在机器学习和深度学习的领域中占据着核心地位,它是连接模型预测与实际结果之间的桥梁,为模型的优化提供了明确的方向。损失函数是一个量化模型预测错误的数学工具。

在模型训练的过程中,损失函数用于计算模型预测的输出与实际标签之间的差异。这个差异值,即损失值,能够直观地反映出模型在当前参数下的性能。通过最小化这个损失值,我们可以驱使模型不断学习和改进,直至达到满意的预测精度。

损失函数的选择取决于具体的任务和数据类型。对于回归问题,常用的损失函数有均方误差(MSE)和平均绝对误差(MAE)。这些函数能够很好地衡量预测值与实际值之间的偏差。而对于分类问题,交叉熵损失则是更为常见的选择。它能够有效地处理概率分布之间的差异,特别是在处理多分类问题时表现出色。

损失函数的设计也需要考虑到一些实际因素。例如,对于噪声数据或异常值,某些损失函数可能过于敏感,导致模型过度拟合这些异常点。在这种情况下,我们可以选择更为鲁棒的损失函数,如Huber损失或平滑L1损失,它们能够在一定程度上减轻异常值对模型训练的影响。

此外,损失函数还可以与正则化项相结合,以控制模型的复杂度并防止过拟合。正则化项通常包括L1正则化和L2正则化,它们通过向损失函数中添加与模型参数相关的惩罚项来实现对模型复杂度的控制。通过合理选择和应用损失函数,我们可以构建出更加准确、鲁棒和高效的机器学习模型。在后续中,我们将进一步探讨不同类型的损失函数及其在实际问题中的应用。那我们在深度学习中有哪些常见的损失函数呢?

一、基于距离度量的损失函数

1、欧氏距离损失(Euclidean Distance Loss)

  • 概念:衡量模型输出值与真实值之间的欧氏距离。
  • 数学公式

EucLoss = \sqrt{\sum_{i=1}^{n} (\hat{y}_i - y_i)^2}

代码实现:

import numpy as np

def euclidean_distance_loss(y_true, y_pred):
    return np.sqrt(np.sum(np.square(y_pred - y_true)))

# 示例
y_true = np.array([1, 2, 3])
y_pred = np.array([2, 3, 4])
print(euclidean_distance_loss(y_true, y_pred))

2、曼哈顿距离损失(Manhattan Distance Loss)

  • 概念:衡量模型输出值与真实值之间的曼哈顿距离,也称为 L_{1}范数距离。
  • 数学公式

ManhLoss = \sum_{i=1}^{n} |\hat{y}_i - y_i|

代码实现:

import numpy as np

def manhattan_distance_loss(y_true, y_pred):
    return np.sum(np.abs(y_pred - y_true))

# 示例
y_true = np.array([1, 2, 3])
y_pred = np.array([2, 3, 4])
print(manhattan_distance_loss(y_true, y_pred))

3、切比雪夫距离损失(Chebyshev Distance Loss)

  • 概念:衡量模型输出值与真实值之间的切比雪夫距离,即两个向量各维度差的最大值。
  • 数学公式

ChebyshevLoss = \max_i |\hat{y}_i - y_i|

代码实现:

import numpy as np

def chebyshev_distance_loss(y_true, y_pred):
    return np.max(np.abs(y_pred - y_true))

# 示例
y_true = np.array([1, 2, 3])
y_pred = np.array([2, 3, 4])
print(chebyshev_distance_loss(y_true, y_pred))

4、马氏距离损失(Mahalanobis Distance Loss)

  • 概念:考虑特征之间的协方差,衡量样本之间的马氏距离,适用于高维空间中的聚类或分类问题。
  • 数学公式

MahalanobisLoss = \sqrt{(\hat{y} - y)^T \cdot S^{-1} \cdot (\hat{y} - y)}

代码实现:

import numpy as np

def mahalanobis_distance_loss(y_true, y_pred):
    return np.sqrt(np.sum(np.square(y_pred - y_true)))

# 示例
y_true = np.array([1, 2, 3])
y_pred = np.array([2, 3, 4])
print(mahalanobis_distance_loss(y_true, y_pred))

5、哈林顿距离损失(Hamming Loss)

  • 概念:用于度量两个向量之间的相似性,通常用于多标签分类任务,衡量两个向量对应元素不相等的比率。
  • 数学公式

HammingLoss = \frac{1}{n} \sum_{i=1}^{n} (\hat{y}_i \neq y_i)

代码实现: 

import numpy as np

def hamming_loss(y_true, y_pred):
    return np.mean(y_true != y_pred)

# 示例
y_true = np.array([1, 0, 1])
y_pred = np.array([0, 1, 1])
print(hamming_loss(y_true, y_pred))

6、余弦相似度损失(Cosine Similarity Loss)

  • 概念:衡量模型输出值与真实值之间的余弦相似度。
  • 数学公式

CosLoss = 1 - \frac{\sum_{i=1}^{n} \hat{y}_i \cdot y_i}{\sqrt{\sum_{i=1}^{n} \hat{y}_i^2} \cdot \sqrt{\sum_{i=1}^{n} y_i^2}}

代码实现:

import numpy as np

def cosine_similarity_loss(y_true, y_pred):
    dot_product = np.dot(y_pred, y_true)
    norm_pred = np.linalg.norm(y_pred)
    norm_true = np.linalg.norm(y_true)
    return 1 - (dot_product / (norm_pred * norm_true))

# 示例
y_true = np.array([1, 2, 3])
y_pred = np.array([2, 3, 4])
print(cosine_similarity_loss(y_true, y_pred))

7、Jaccard 距离损失(Jaccard Distance Loss)

  • 概念:用于度量集合之间的相似性,通常用于聚类或分类问题。
  • 数学公式

JaccardLoss = 1 - \frac{|A \cap B|}{|A \cup B|}

代码实现:

import numpy as np

def jaccard_distance_loss(y_true, y_pred):
    intersection = np.sum(np.minimum(y_true, y_pred))
    union = np.sum(np.maximum(y_true, y_pred))
    return 1 - intersection / union

# 示例
A = np.array([1, 0, 1, 0])
B = np.array([1, 1, 1, 0])
print(jaccard_distance_loss(A, B))

8、Wasserstein 距离损失(Wasserstein Distance Loss)

  • 概念:用于度量两个概率分布之间的差异,尤其在生成对抗网络(GAN)中应用广泛。
  • 数学公式

WassersteinLoss = \min_{\gamma \in \Gamma} \sum_{i,j} \gamma_{ij} \cdot c_{ij}

Wasserstein 距离损失是用于度量两个概率分布之间的差异的一种损失函数。它通常用于衡量生成对抗网络(GAN)中生成器产生的假样本与真实样本之间的差异。

其中:

\gamma表示两个分布之间的联合分布;
\Gamma是所有可能的联合分布的集合;
c_{ij}表示两个样本之间的成本(或距离);
\sum_{i,j} \gamma_{ij} \cdot c_{ij}表示在联合分布\gamma下的总成本。

Wasserstein 距离损失实际上是求解两个分布之间最小成本的问题,通常使用线性规划或其他数值方法进行求解。

代码实现:

import numpy as np
from scipy.optimize import linear_sum_assignment

def wasserstein_distance_loss(y_true, y_pred):
    # 构建 cost matrix
    cost_matrix = np.abs(np.subtract.outer(y_true, y_pred))
    # 使用线性求解器进行最小化
    row_ind, col_ind = linear_sum_assignment(cost_matrix)
    return cost_matrix[row_ind, col_ind].sum()

# 示例
y_true = np.array([1, 2, 3])
y_pred = np.array([2, 3, 4])
print(wasserstein_distance_loss(y_true, y_pred))

9、Huber损失函数

  • 概念:Huber损失函数是一种针对回归问题的损失函数,它在数据点靠近预测值时的表现类似于平方损失函数,而在远离预测值时的表现类似于绝对损失函数,因此在某种程度上结合了两者的优点。
  • 数学公式:

L_{\delta}(y, f(x)) = \begin{cases} \frac{1}{2}(y - f(x))^2, & \text{if } |y - f(x)| \leq \delta \\ \delta(|y - f(x)| - \frac{1}{2}\delta), & \text{otherwise} \end{cases}

其中,y是实际观测值,f(x)是模型的预测值,\delta是一个超参数,通常是一个非负数。当实际值和预测值的绝对差小于等于\delta时,采用平方损失函数,否则采用绝对损失函数。

Huber损失函数的优点在于它在靠近预测值时兼具平方损失函数的光滑性和绝对损失函数的鲁棒性,因此对于异常值的影响相对较小,使得模型更加稳健。在实际应用中,Huber损失函数常用于拟合异常值较多的数据或者对异常值较为敏感的回归任务中。

代码实现:

import numpy as np

def huber_loss(y_true, y_pred, delta):
    residual = np.abs(y_true - y_pred)
    huber_loss = np.where(residual <= delta, 0.5 * residual ** 2, delta * (residual - 0.5 * delta))
    return np.mean(huber_loss)

# 示例
y_true = np.array([1, 2, 3, 4, 5])
y_pred = np.array([2, 3, 4, 5, 9])  # 模型预测值,最后一个值偏离较大
delta = 1.0  # Huber 损失函数中的超参数

print("Huber Loss:", huber_loss(y_true, y_pred, delta))

重要损失函数图 : 

二、 基于概率分布度量的损失函数

1、交叉熵损失(Cross-Entropy Loss)

概念定义:用于衡量模型输出的概率分布与真实概率分布之间的差异。
数学公式:\text{CrossEntropyLoss} = -\sum_{i} y_i \log(\hat{y}_i)
其中,y_i是真实概率分布的第i个元素,\hat{y}_i是模型输出的第 i个类别的概率。

实现代码:

def cross_entropy_loss(y_true, y_pred):
    return -np.sum(y_true * np.log(y_pred))

# 示例
y_true = np.array([1, 0, 0])
y_pred = np.array([0.9, 0.05, 0.05])
print(cross_entropy_loss(y_true, y_pred))

2、其他常见的交叉熵损失函数: 

 Softmax 损失函数:
   适用于多分类任务,将模型的原始输出转换为类别概率分布。
   数学公式:\text{SoftmaxLoss} = -\frac{1}{N} \sum_{i=1}^{N} \sum_{j=1}^{M} y_{ij} \log(\text{softmax}(\hat{y}_i)_j)
   适用场景:多分类问题,输出为一个概率分布向量,经过 Softmax 函数处理。

Sigmoid 交叉熵损失函数:
   适用于二分类任务,将模型的原始输出通过 Sigmoid 函数转换为概率值。
   数学公式:\text{SigmoidCrossEntropyLoss} = -\frac{1}{N} \sum_{i=1}^{N} [y_i \log(\hat{y}_i) + (1 - y_i) \log(1 - \hat{y}_i)]
   适用场景:二分类问题,输出为单个标量,经过 Sigmoid 函数处理。

Focal Loss:
   用于处理类别不平衡和困难样本的问题,在多目标检测任务中表现良好。
   数学公式:\text{FocalLoss} = -\frac{1}{N} \sum_{i=1}^{N} [ (1 - \hat{y}_i)^\gamma y_i \log(\hat{y}_i) + \hat{y}_i^\gamma (1 - y_i) \log(1 - \hat{y}_i) ]
   适用场景:处理类别不平衡问题的多分类任务。

Dice Loss:
   主要用于图像分割任务中,适用于处理正负样本不平衡的情况。
   数学公式:\text{DiceLoss} = 1 - \frac{2 \sum_{i}^{N} p_i g_i}{\sum_{i}^{N} p_i^2 + \sum_{i}^{N} g_i^2}
   适用场景:图像分割任务,处理正负样本不平衡问题。

3、 KL 散度损失(Kullback-Leibler Divergence Loss)


  概念定义:用于衡量两个概率分布之间的差异。
  数学公式:\text{KLDivLoss} = \sum_{i} P(i) \log\left(\frac{P(i)}{Q(i)}\right)
  其中 PQ 是两个概率分布,P(i)Q(i) 分别是它们的第 i个元素。
 实现代码:

def kl_divergence_loss(P, Q):
    return np.sum(P * np.log(P / Q))

# 示例
P = np.array([0.5, 0.3, 0.2])
Q = np.array([0.4, 0.4, 0.2])
print(kl_divergence_loss(P, Q))

3、JS(Jensen-Shannon)散度

JS散度是一种用于度量两个概率分布之间的相似性的度量。它是 KL(Kullback-Leibler)散度的对称版本,也可以看作是两个概率分布的平均交叉熵与其平均分布之间交叉熵的均值。

给定两个概率分布PQ,JS 散度的数学公式如下:

\text{JS}(P \| Q) = \frac{1}{2} \left( \text{KL}(P \| M) + \text{KL}(Q \| M) \right)

其中,M = \frac{1}{2} (P + Q)是两个概率分布的平均分布。

JS 散度具有以下性质:

  • 非负性:JS 散度永远不会为负。
  • 对称性:JS 散度是对称的,即 \( \text{JS}(P \| Q) = \text{JS}(Q \| P) \)。
  • 介于 0 和 1 之间:当且仅当两个分布完全相同时,JS 散度达到最小值 0,当两个分布完全不同且没有重叠时,JS 散度达到最大值 1。

JS 散度常用于生成对抗网络(GAN)中的目标函数,用于度量生成器产生的假样本分布与真实样本分布之间的差异。

实现代码:

def kl_divergence(p, q):
    return np.sum(p * np.log(p / q))

def js_divergence(p, q):
    m = 0.5 * (p + q)
    return 0.5 * (kl_divergence(p, m) + kl_divergence(q, m))

# 示例
p = np.array([0.3, 0.5, 0.2])
q = np.array([0.1, 0.6, 0.3])

print("JS 散度:", js_divergence(p, q))

总结

损失函数通常作为学习准则与优化问题相联系,即通过最小化损失函数来求解和评估模型。损失函数在机器学习和深度学习中被广泛应用于指导模型训练和评估,以及调整参数以更好地拟合训练数据和提高性能。今日分享到这里了哦,感谢大家的阅览哦!

最后,创作不易!非常感谢大家的关注、点赞、评论啦!谢谢三连哦!好人好运连连,学习进步!工作顺利哦! 

  • 62
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序小勇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值