面试高频4–评价指标-损失函数理解
笔记链接
前言:
损失函数用来评价模型的预测值和真实值不一样的程度,损失函数越好,通常模型的性能越好。
不同的模型用的损失函数一般也不一样。
损失函数分为经验风险损失函数和结构风险损失函数。经验风险损失函数指预测结果和实际结果的差别,
结构风险损失函数是指经验风险损失函数加上正则项。
自己整理推导-19种损失函数
1. L1范数损失:L1 loss(MAE)
解释: 计算output 与 target 差的绝对值
torch.nn.L1Loss(reduction='mean)
参数:
reduction三个取值:
1) None:不使用约简;
2) mean: 返回loss和的平均;
3) sum: 返回 loss的和;
默认: mean
2. 均方误差损失: MSELoss ⭐ (MSE)
解释: 计算 output 与 target 差的均方差。
torch.nn.MSELoss(reduction='mean')
参数:
reduction三个取值:
1) None:不使用约简;
2) mean: 返回loss和的平均;
3) sum: 返回 loss的和;
默认: mean
3. 交叉熵损失: CrossEntropyLoss ⭐⭐⭐
损失函数 - 交叉熵损失函数
Softmax函数与交叉熵⭐
一文搞懂交叉熵损失⭐
说明: 当训练有C个类别的问题时候很有效, 可选参数 weight 必须是一个 一维的tensor, 权重将被分配给各个类,
对于不平衡的训练集非常有效。 ⭐
在多分类任务中,经常采用 softmax 激活函数 + 交叉熵损失函数, 因为交叉熵描述了两个概率分布的差异,
然而神经网络的输出是向量,并不是 概率分布的形式。
所以需要 softmax 激活函数将一个向量进行’归一化‘成概率分布的形式, 再采用交叉熵损失函数计算loss。
# 上述公式没有太理解;
torch.nn.CrossEntropyLoss(weight=None,ignore_index=-100, reduction='mean')
参数:
1. weight (Tensor, optional) – 自定义的每个类别的权重. 必须是一个长度为 C 的 Tensor
2. ignore_index (int, optional) – 设置一个目标值, 该目标值会被忽略, 从而不会影响到 输入的梯度。
3. reduction-三个值,
1) none: 不使用约简;
2) mean:返回loss和的平均值;
3) sum:返回loss的和。默认:mean。
4. KL散度损失:KLDivLoss
说明: 计算input 和 target 之间的 KL散度。 KL散度可以用于衡量不同的连续分布之间的距离;
在连续的输出空间上(离散采样)上进行直接回归时,很有效。
torch.nn.KLDivLoss(reduction='mean')
参数:
reduction-三个值,
1) none: 不使用约简;
2) mean:返回loss和的平均值;
3) sum:返回loss的和。默认:mean。
5. 二进制交叉熵损失:BCELoss ⭐⭐
nn.BCELoss与nn.CrossEntropyLoss的区别
损失函数(BCELoss)⭐
- BCELoss需要自己添加 Sigmod 激活函数;
- CrossEntropyLoss自己添加了softmax; Softmax–Log–NLLLoss合并成一步;
- 所以: BCELoss和CrossEntropyLoss结果不同;
说明: 二进制分类任务时的交叉熵计算函数。
torch.nn.BCELoss(weight=None, reduction='mean')
参数:
weight (Tensor, optional) – 自定义的每个 batch 元素的 loss 的权重. 必须是一个长度为 “nbatch” 的 的 Tensor
6. BCEWithLogitsLoss ⭐【待进一步理解】
说明: BCEWithLogitsLoss 损失函数把 sigmod 层集成到了 BCELoss类中,
该版本用一个简单的 Sigmod 层 和 BCELoss在数值上更稳定, 因为把这两个操作合并为一个层之后,
可以利用 log-sum-exp 的技巧来实现数值稳定;
torch.nn.BCEWithLogitsLoss(weight=None, reduction='mean', pos_weight=None)
参数: weight (Tensor, optional) – 自定义的每个 batch 元素的 loss 的权重.
必须是一个长度 为 “nbatch” 的 Tensor
7. MarginRankingLoss 【待进一步理解】
torch.nn.MarginRankingLoss(margin=0.0, reduction='mean')
参数:
margin:默认值0
对于 mini-batch(小批量) 中每个实例的损失函数如下:
8. HingeEmbeddingLoss 【待进一步理解】
PyTorch中的损失函数–MarginRanking/Hinge/Cosine
torch.nn.HingeEmbeddingLoss(margin=1.0, reduction='mean')
参数:
margin:默认值1
对于 mini-batch(小批量) 中每个实例的损失函数如下:
9. 多标签分类损失: MultiLabelMarginLoss
torch.nn.MultiLabelMarginLoss(reduction='mean')
对于mini-batch(小批量) 中的每个样本按如下公式计算损失:
10.平滑版L1损失:SmoothL1Loss (Huber损失函数)
torch.nn.SmoothL1Loss(reduction='mean')
其中
11. 2分类的logitic损失 SoftMarginLoss
torch.nn.SoftMarginLoss(reduction='mean')
12. 多标签 one-versus-all 损失 MultiLabelSoftMarginLoss
torch.nn.MultiLabelSoftMarginLoss(weight=None, reduction='mean')
13. cosine 损失 CosineEmbeddingLoss
torch.nn.CosineEmbeddingLoss(margin=0.0, reduction='mean')
参数:
margin:默认值0
14. 多类别分类的hinge损失 MultiMarginLoss.
torch.nn.MultiMarginLoss(p=1, margin=1.0, weight=None, reduction='mean')
参数:
p=1或者2 默认值:1
margin:默认值1
15. 三元组损失 TripletMarginLoss
和孪生网络相似,具体例子:给一个A,然后再给B、C,看看B、C谁和A更像。
torch.nn.TripletMarginLoss(margin=1.0, p=2.0, eps=1e-06, swap=False, reduction='mean')
16 连接时序分类损失 CTCLoss
CTC连接时序分类损失,可以对没有对齐的数据进行自动对齐,主要用在没有事先对齐的序列化数据训练上。
比如语音识别、ocr识别等等。
torch.nn.CTCLoss(blank=0, reduction='mean')
参数:
reduction-三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。
17. 负对数似然损失:NLLLoss
pytorch损失函数之nn.CrossEntropyLoss()、nn.NLLLoss()
Pytorch详解NLLLoss和CrossEntropyLoss
# 上述NLLLoss过程写错了;
loss = nn.NLLLoss()
target = torch.tensor([0, 2, 1])
loss(torch.log(sm(input)), target)
负对数似然损失. 用于训练 C 个类别的分类问题.
torch.nn.NLLLoss(weight=None, ignore_index=-100, reduction='mean')
参数:
weight (Tensor, optional) :自定义的每个类别的权重. 必须是一个长度为 C 的 Tensor
ignore_index (int, optional) : 设置一个目标值, 该目标值会被忽略, 从而不会影响到 输入的梯度.
18. NLLLoss2d
对于图片输入的负对数似然损失. 它计算每个像素的负对数似然损失.
torch.nn.NLLLoss2d(weight=None, ignore_index=-100, reduction='mean')
参数:
weight (Tensor, optional) : 自定义的每个类别的权重. 必须是一个长度为 C 的 Tensor
reduction:三个值,none: 不使用约简;mean:返回loss和的平均值;sum:返回loss的和。默认:mean。
19. PoissonNLLLoss
目标值为泊松分布的负对数似然损失
torch.nn.PoissonNLLLoss(log_input=True, full=False, eps=1e-08, reduction='mean')
参数:
log_input (bool, optional) : 如果设置为 True , loss 将会按照公 式 exp(input) - target * input 来计算,
如果设置为 False , loss 将会按照 input - target * log(input+eps) 计算.
full (bool, optional) – 是否计算全部的 loss, i. e. 加上 Stirling 近似项 target * log(target) - target + 0.5 * log(2 * pi * target).
eps (float, optional) – 默认值: 1e-8
20. 0-1损失函数(zero-one loss)
21. 指数损失函数(exponential loss)
22. Hinge 损失函数
. 总结:
- 感知机: 0-1损失
- 逻辑回归: 交叉熵, 对数损失
- LR: MSE
- AdaBoost: 指数损失
- SVM: Hingle损失
- 二分类、多分类: 交叉熵;
交叉熵专栏: ⭐⭐⭐
损失函数 - 交叉熵损失函数
Softmax函数与交叉熵⭐
一文搞懂交叉熵损失⭐
测试
- softmax做二分类和sigmod做二分类本质也是相同虽然结构、公式不一样,但是可以推导出相同的形式; 后面都是跟的 二分类交叉熵作为 损失函数;
多标签分类学习
1. 周志华团队:深度森林挑战多标签学习,9大数据集超越传统方法
2. 大规模多标签分类
3. 大规模多标签分类的各种模型的实验结果和代码实现
常见任务的评价指标:
-
P、R、F:
-
AOC
常见问题整理:
1. 1.交叉熵函数与最大似然函数的联系和区别?
2. 在用sigmoid作为激活函数的时候,为什么要用交叉熵损失函数,而不用均方误差损失函数?
3. 激活函数、损失函数、任务搭配选择问题?
知乎问题-使用ReLU作为激活函数还有必要用交叉熵计算损失函数吗?
4. 2分类、多分类、多标签分类的区别与评价指标?
- 后面已经回答,宏平均、微平均
-
数据有14个标签,每种标签有3种可能的取值,这种算多标签多分类吗?
-
-
-
宏平均、微平均的计算:
-
多分类问题:
-
label: [1, 2, 3, 1, 2] 3分类
-
pred:[1, 3, 3, 2, 2]
[1,1] + [3, 3] + [2, 2] = 3
P: 3 / 5
R: 3/ 5
上述可以看作微平均; 同样可以从: 每个类别的 混淆矩阵得到; -
宏平均计算:
-
类别1: 预测了: 1个,正确了: 1, 原本正确:2个;
- P: 1/1 = 1
- R = 1/2
- F1 = 211/2 / (1+1/2) = 2/3
-
类别2:预测了:2个,正确了:1, 原本正确2个;
- P : 1 / 2
- R : 1 /2
- F:2 * 1/2 * 1/2 / (1/2 + 1/2) = 1/2
-
类别3:预测了:2个, 正确了:1个, 原本正确: 1个。
- P: 1/ 2
- R:1/1 = 1
- F:2 * 1/2 * 1 / (1/2 + 1) = 2/3
-
宏平均:
- P:(1+1/2+1/2) / 3 = 2/3
- R:(1/2 + 1/2 + 1) / 3 = 2/3
- F_1:(2/3 + 1/2 + 2/3)/ 3 = 11 / 18
- F_2:: (2 * 2/3 * 2/3) / (2/3 + 2/3) = 2/3
-
NER多个句子多个实体角度分析:
- 应该把整个batch或者整个测试集一起考虑,每个样本统计,预测数量,正确预测数量,标签数量,然后最后统一计算PRF, 如果每个样本都单独各自计算,最后的结果会有差异。
- 每个样本统计正确、预测、正确预测数量与针对各个类分别进行数量统计混淆矩阵最后的结果是一样的。
- 每个样本分别计算PRF最后求平均的方法有问题: 原因: 会随着 类别数量变化变化, 另一种做法,分子相加,分母相加就是最终的结果,不用求平均。
8- 多标签分类: BCELoss / BCEWithLogitLoss : 对于输入分别进行二分类交叉熵的损失计算;
多标签分类: 一般做法有几种标签就最后输入几个 值; 然后分别进行 sogmoid后面进行二分类计算,使用二分类交叉熵;
9- 多分类: CrossEntropyLoss: 对于输入直接按照交叉熵进行计算;
- 多标签并且每个标签下面又有很多的值怎么处理? 比如: 政治:123, 宗教:123,这种如何处理?