Loading... ## 前言 这里用来记录下使用过的部分损失的计算过程以及含义. ## 交叉熵损失 交叉熵损失(Cross-Entropy Loss)是用于分类任务中的一个常见损失函数,特别是在输出层使用了Softmax函数的情况下。它度量的是模型输出的概率分布与真实标签的概率分布之间的差异。交叉熵损失的计算公式提供了衡量预测概率分布P与目标分布Y之间差异的有效方式。 ### 损失定义 对于一个多类分类问题,假设真实的标签用one-hot编码表示,即对于每个实例的标签 $y$是一个长度为 $K$ 的向量,其中 $K$ 是类别的总数。在 $y$中,正确类别的位置为1,其余为0。假设 $p$ 是模型对每个类别预测的概率分布,即 Softmax 的输出。交叉熵损失定义为: $$ L=-\sum\limits_{i=1}^{K} y_i log(p_i) $$ 其中 $p_i$ 是模型预测第 i 类的概率,$y_i$ 是真实标签向量(one-hot编码)中第 i 个元素的值。 ### 直观解释 交叉熵损失的核心在于: **如果模型对真实类别的预测概率很高,那么损失值很小;如果模型对真实类别的预测概率很低,那么损失值很大。** 这是因为$log(p_i)$在 $p_i$ (对应分类的预测概率)接近1时值接近0,而在$p_i$接近0时向负无穷趋近。 *示例* 假设一个三分类问题($K=3$),其中正确的标签是第二个类(使用one-hot编码表示为` [0,1,0]`)。假设一个模型的输出概率(Softmax输出)为 `[0.1,0.7,0.2]`。则损失函数可以计算如下: $$ \begin{equation} \begin{aligned} L&=-(0 \times log(0.1) + 1 \times log(0.7) + 0 \times log(0.2)) \\ L&=-log(0.7) \end{aligned} \end{equation} $$ 这里,只有第二项(对应正确类别)对损失函数有贡献。 计算 $log(0.7)$的值,注意这里的对数通常是以 $e$ 为底(自然对数)。 让我们计算这个损失的具体值: 对于给定的预测概率 $p=0.7$(对应真实标签的类),交叉熵损失 $L$ 计算结果约为 0.357。这意味着模型对真实类别的预测相对准确,因此损失相对较低。如果模型的预测概率更低,比如 0.1 或 0.01,损失会显著增加,从而反映出模型预测的不准确性。 交叉熵损失通过惩罚错误预测的低概率值,有效地指导模型学习,使得模型的输出概率分布尽可能接近目标分布,这是它在分类问题中广泛使用的主要原因。 *梯度反传* * 对于输入X, 经过Softmax后输出在K个类别上的预测概率Y, 之后经过交叉熵损失计算得到结果损失L, 则对X的梯度如下 首先 交叉熵对X的梯度计算如下 * 根据链式求导法则L对于输入$X_j$的梯度 $$ \begin{equation} \begin{aligned} \frac {\partial L} {\partial X_j} =& \sum\limits_{i=1}^{K}\frac{\partial L}{\partial p_i} \frac {\partial p_i} {\partial X_j} \\ \frac {\partial L} {\partial X_j} =&\ p_j -y_j \\ \frac {\partial L} {\partial X} =& \ [p_1-y_1, p2-y2, p3-y3] = [0.1-0, 0.7-1, 0.2-0] \\ \frac {\partial L} {\partial X} =& \ [0.1, -0.3, 0.2] \end{aligned} \end{equation} $$ 这些梯度反映了如何调整输入 X 以减小损失 L(如何逼近0),即向量中的每个分量表明对应类别预测概率与实际标签的偏差。 --- ## Label Smoothing Label Smoothing (ce-loss 基础上调整了标签Y)是一种在训练深度学习模型时常用的正则化技术,它的目的是让模型对输出的预测不要过于自信,以防过拟合。在应用Label Smoothing时,真实的标签向量不再是一个严格的one-hot向量,而是变成了一个在所有类别上都有小量正数的向量。 ### 标签调整 使用Label Smoothing时,我们将原来的one-hot标签 $y$ 调整为: $$ y_i^{LS} = \begin{cases} 1-\alpha, & \text{if i=y=1}, \\ \alpha/(K-1), & \text{otherwise}, \end{cases} $$ 这里,$\alpha$ 是一个小的正数(一般设置0.1),$K$ 是类别总数。<span style='color:red'>这意味着即使对于正确的类别,我们也只赋予它 $1-\alpha$的权重,其他类别则平均分配剩余的 $\alpha$ </span> 公式参考: * https://zhuanlan.zhihu.com/p/302843504 * https://blog.csdn.net/sinat_38685124/article/details/108382216 ### 损失计算 假设我们的任务是三分类问题,具体设置如下: * 真实标签(未使用Label Smoothing): Y=[0,1, 0] * Softmax输出(模型预测概率): P=[0.2,0.7, 0.1] * Label Smoothing参数 $\alpha=0.1$ * 类别总数$K=3$ 则损失计算如下 ```latex y_{LS} = [0.9,0.05,0.05] L=−(0.05×log(0.2)+0.9×log(0.7)+0.05×log(0.1)) ``` ### 梯度反传 对照softmax+ce-loss示例过程, softmax+label Smoothing的过程区别如下 $$ \begin{equation} \begin{aligned} \frac {\partial L} {\partial X_j} =&\ p_j -y_j \\ Y =& [0,1,0] \\ \frac {\partial L} {\partial X} =& \ [p_1-y_1, p_2-y_2, p_3-y_3] = [0.1-0, 0.7-1, 0.2-0] \\ \frac {\partial L} {\partial X} =& \ [0.1, -0.3, 0.2] \\=&>\\ \frac {\partial L} {\partial X_j} =&\ p_j -y_j^{LS} \\ Y^{LS} =& [0.05,0.9,0.05] \\ \frac {\partial L} {\partial X} =& \ [p_1-y_1^{LS}, p_2-y_2^{LS}, p_3-y_3^{LS}] = [0.1-0.05, 0.7-0.9, 0.2-0.05] \\ \frac {\partial L} {\partial X} =& \ [0.05, -0.2, 0.15] \end{aligned} \end{equation} $$ --- ## Dice Loss 在医学图像分割等领域,Dice Loss 是一种常用的损失函数,特别适用于数据集中正负样本不平衡的情况。Dice Loss 基于 Dice 系数(也称为 Sørensen-Dice 系数),这是一种衡量两个样本相似性的统计工具。在二分类图像分割任务中,Dice 系数通常用来比较预测的分割结果和真实的标注(ground truth)。 ### Dice系数 DIce系数, 根据 Lee Raymond Dice命名,是一种**集合相似度度量函数**,通常用于计算两个样本的相似度(值范围为 [0, 1])。 $$ DiceCoefficient=\frac{2|P \cap Y|}{|P| + |Y|} $$ 其中$|P \cap Y|$表示X和Y集合的交集,$|P|$和$|Y|$表示其元素个数,**对于分割任务而言,|P|和|Y|表示分割的predict_mask和ground truth。** 更进一步,我们得到Dice Loss的公式: $$ DiceLoss = 1- DiceCoefficient= 1- \frac{2|P \cap Y|}{|P| + |Y|} $$ ### 手推案例(二分类DiceLoss) 在实际应用中,尤其是在使用神经网络进行图像分割时,我们通常对输出进行 sigmoid 或 softmax 函数处理,使其转换为概率输出。因此,Dice Loss 的计算需要稍作调整,以适应这种概率形式。具体来说: * **真实标签Y** 是二值图像,其中像素值为 1表示目标类,值为 0表示背景。 * **预测概率P** 是模型的输出,通过 sigmoid/softmax 函数转换后的结果,取值在 [0,1]范围内。 给定这样的设置,Dice 系数的实际计算方法可以调整为: $$ DiceCoefficient = \frac{2\times \sum(P \times Y)}{\sum{P} + \sum{Y}} $$ **其中,乘法和求和都是逐像素进行的。** 现在假设我们有以下简单的示例: * 真实标签$Y: [1,1,0,0,1]$ * 预测概率$P: [0.9,0.8,0.1,0.3,0.7]$ 我们将计算这个例子的 Dice Loss, 代码如下 * 先计算 Dice 系数,然后计算 Dice Loss。 ```python import numpy as np # 定义真实标签和预测概率 Y = np.array([1, 1, 0, 0, 1]) P = np.array([0.9, 0.8, 0.1, 0.3, 0.7]) # 计算 Dice 系数 # 注意分母的计算 smooth = 1e-6 # 避免分母有为0 dice_numerator = 2 * np.sum(Y * P) dice_denominator = np.sum(Y) + np.sum(P) dice_coefficient = (dice_numerator+ smooth) / (dice_denominator + smooth) # 计算 Dice Loss dice_loss = 1 - dice_coefficient ``` 在给定的示例中,Dice 系数计算得约为 0.828,因此相应的 Dice Loss 为约 0.172。这表明预测结果与真实标签之间有较高的相似度,Dice Loss 值较低,表示模型的分割效果较好。这种损失函数特别适合处理不平衡的数据集,例如在某些类别的样本远多于其他类别的情况下,它帮助模型更好地学习到较少样本的特征。 其它计算示例参考: https://www.cnblogs.com/PythonLearner/p/14034683.html *Pytorch实现示例* ```python def dice_coeff(pred, target): smooth = 1. num = pred.size(0) m1 = pred.view(num, -1) # Flatten m2 = target.view(num, -1) # Flatten intersection = (m1 * m2).sum() return (2. * intersection + smooth) / (m1.sum() + m2.sum() + smooth) def dice_loss(pred, target): smooth = 1. num = pred.size(0) m1 = pred.view(num, -1) # Flatten m2 = target.view(num, -1) # Flatten intersection = (m1 * m2).sum() # 1-dice_coefficient return 1-(2. * intersection + smooth) / (m1.sum() + m2.sum() + smooth) ``` *扩展* 假设是一个10分类的任务,那么我们应该会有一个这样的模型预测结果:[batch\_size,10,width,height],然后我们的ground truth需要改成one hot的形式,也变成[batch\_size,10,width,height]。剩下的和二分类的代码基本相同了,先ground truth和预测结果对应元素相乘,然后对相乘的结果求和。就是最后需要对每一个类别和每一个样本都求一次平均就行了。 ## 其它 待补充 THE END 本文作者:将夜 本文链接:https://zoe.red/2024/501.html 版权声明:本博客所有文章除特别声明外,均默认采用 CC BY-NC-SA 4.0 许可协议。 最后修改:2024 年 04 月 16 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏