TeamClass_MD/Tensorflow的损失函数.md

219 lines
7.9 KiB
Markdown
Raw Normal View History

2025-03-15 20:08:09 +08:00
### **1. 分类任务损失函数**
#### **(1) 交叉熵损失Cross-Entropy Loss**
- **原理**
用于衡量预测概率分布与真实标签分布之间的差异。
- **稀疏交叉熵**`SparseCategoricalCrossentropy`
标签为整数(如 `[0, 1, 2]`),直接计算类别索引的交叉熵。
**公式**
$$\
H(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i)
\ $$
- **多分类交叉熵**`CategoricalCrossentropy`
标签为 One-Hot 编码(如 `[[1,0,0], [0,1,0]]`)。
- **适用场景**
图像分类、文本分类等离散标签任务。
- **代码示例**
```python
from tensorflow.keras.losses import SparseCategoricalCrossentropy
model.compile(optimizer='adam', loss=SparseCategoricalCrossentropy(from_logits=True))
```
---
#### **(2) 对数损失Logistic Loss / Binary Cross-Entropy**
- **原理**
二分类任务的特例输出为概率值sigmoid 输出)。
**公式**
$$\
H(y, \hat{y}) = -\sum_{i} y_i \log(\hat{y}_i) - (1-y_i) \log(1-\hat{y}_i)
\ $$
- **适用场景**
二分类任务(如垃圾邮件检测)。
- **代码示例**
```python
from tensorflow.keras.losses import BinaryCrossentropy
model.compile(optimizer='adam', loss=BinaryCrossentropy())
```
---
#### **(3) Hinge Loss**
- **原理**
最大间隔分类器(如 SVM关注正确分类的边界。
**公式**
$$\
L(y, \hat{y}) = \max(0, 1 - y \cdot \hat{y})
\ $$
- \( y \in \{-1, 1\} \)\( \hat{y} \) 为模型输出(未归一化)。
- **适用场景**
文本分类、图像识别中的边界敏感任务。
- **代码示例**
```python
from tensorflow.keras.losses import Hinge
model.compile(optimizer='adam', loss=Hinge())
```
---
### **2. 回归任务损失函数**
#### **(1) 均方误差MSE / Mean Squared Error**
- **原理**
预测值与真实值差的平方的平均值。
**公式**
$$\
MSE = \frac{1}{N} \sum_{i=1}^{N} (y_{\text{true}}^{(i)} - y_{\text{pred}}^{(i)})^2
\ $$
- **适用场景**
回归任务(如房价预测、图像修复)。
- **代码示例**
```python
from tensorflow.keras.losses import MeanSquaredError
model.compile(optimizer='adam', loss=MeanSquaredError())
```
---
#### **(2) 平均绝对误差MAE / Mean Absolute Error**
- **原理**
预测值与真实值差的绝对值的平均值。
**公式**
$$\
MAE = \frac{1}{N} \sum_{i=1}^{N} |y_{\text{true}}^{(i)} - y_{\text{pred}}^{(i)}|
\ $$
- **适用场景**
对异常值不敏感的任务(如推荐系统评分预测)。
- **代码示例**
```python
from tensorflow.keras.losses import MeanAbsoluteError
model.compile(optimizer='adam', loss=MeanAbsoluteError())
```
---
#### **(3) Huber Loss**
- **原理**
结合 MSE 和 MAE对中等误差平方处理对大误差线性处理降低敏感度
**公式**
$$\
L_\delta(y, \hat{y}) =
\begin{cases}
\frac{1}{2}\delta^2 (y - \hat{y})^2 & \text{if } |y - \hat{y}| \leq \delta \\
\delta (|y - \hat{y}| - \delta) & \text{otherwise}
\end{cases}
\ $$
- $\delta$: 阈值(默认 1.0)。
- **适用场景**
存在异常值的回归任务(如自动驾驶中的目标检测)。
- **代码示例**
```python
from tensorflow.keras.losses import Huber
model.compile(optimizer='adam', loss=Huber(delta=1.0))
```
---
### **3. 序列任务损失函数**
#### **(1) CTC LossConnectionist Temporal Classification**
- **原理**
用于序列到序列任务(如语音识别),解决标签序列与预测序列长度不一致的问题。
**特点**
- 自动对齐输入和输出序列。
- 支持空格分隔符(如 `"hello world"``[h, e, l, l, o, _, w, o, r, l, d]`)。
- **适用场景**
语音识别、文本生成、时间序列预测。
- **代码示例**
```python
from tensorflow.keras.losses import CTCLoss
model.compile(optimizer='adam', loss=CTCLoss())
```
---
#### **(2) 自回归损失AutoRegressive Loss**
- **原理**
逐个预测序列中的每个时间步,累积误差。
**公式**
$$\
L = \sum_{t=1}^{T} \log P(y_t | y_{1:t-1}, x)
\ $$
- **适用场景**
机器翻译、文档摘要生成。
---
### **4. 自定义损失函数**
当内置损失函数无法满足需求时,可以自定义损失函数。以下是一个示例:
#### **(1) 自定义 MSE 损失**
```python
import tensorflow as tf
def custom_mse(y_true, y_pred):
return tf.reduce_mean(tf.square(y_true - y_pred))
model.compile(optimizer='adam', loss=custom_mse)
```
#### **(2) 多任务损失(加权组合)**
```python
def multi_task_loss(y_true, y_pred):
# 假设有两个输出层output1 和 output2
loss1 = tf.keras.losses.mse(y_true[0], y_pred[0])
loss2 = tf.keras.losses.binary_crossentropy(y_true[1], y_pred[1])
return 0.7 * loss1 + 0.3 * loss2 # 加权组合
model.compile(optimizer='adam', loss=multi_task_loss)
```
---
### **5. 其他特殊损失函数**
#### **(1) Poisson Loss**
- **原理**
适用于计数数据(如用户点击率预测)。
**公式**
$$\
L = \sum_{i=1}^{N} \left( y_{\text{true}}^{(i)} \log(y_{\text{pred}}^{(i)}) - y_{\text{pred}}^{(i)} \right)
\ $$
- **适用场景**
推荐系统、自然语言处理中的词频预测。
- **代码示例**
```python
from tensorflow.keras.losses import Poisson
model.compile(optimizer='adam', loss=Poisson())
```
---
#### **(2) Contrastive Loss**
- **原理**
通过对比正负样本的相似度来学习特征表示。
**公式**
$$\
L = y \cdot \log(d) + (1-y) \cdot \log(1-d)
\ $$
- \( d \): 正样本相似度,\( 1-d \): 负样本相似度。
- **适用场景**
图像检索、相似性学习。
- **代码示例**
```python
# 需自定义实现或使用库(如 TensorFlow Addons
```
---
### **6. 如何选择损失函数?**
| 任务类型 | 推荐损失函数 | 场景说明 |
|----------|--------------|----------|
| 二分类 | BinaryCrossentropy | 标签为 0/1 或 One-Hot 编码 |
| 多分类 | SparseCategoricalCrossentropy | 标签为整数(未 One-Hot |
| 回归 | MeanSquaredError 或 Huber | 数据分布均匀或存在异常值 |
| 序列标注 | CTC Loss | 语音识别、文本对齐 |
| 多任务学习 | 加权组合损失(如 MSE + CrossEntropy | 同时优化多个输出 |
| 异常检测 | Huber Loss | 对离群值不敏感 |
### 7. 高级配置
#### (1) 加权损失Weighted Loss
用于为不同类别分配不同的损失权重。
- 代码示例:
```python
# 为不同类别赋予不同权重
model.compile(
optimizer='adam',
loss='sparse_categorical_crossentropy',
loss_weights={'class_0': 1.0, 'class_1': 5.0} # 类别1的权重更高
)
```
#### (2) 自定义梯度裁剪
用于限制梯度的大小,防止梯度爆炸。
>p.s. 梯度爆炸是指在训练深度学习模型时,梯度(即损失函数关于模型参数的导数)的值变得非常大,导致模型参数更新过大,从而使得模型无法收敛到一个稳定的解。
- 代码示例:
```python
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
optimizer.clipnorm = 1.0 # 梯度范数不超过1.0
model.compile(optimizer=optimizer, loss='mse')
```
---
### 总结
- **分类任务**:优先选择交叉熵或其变体(如 `SparseCategoricalCrossentropy``CategoricalCrossentropy`)。
- **回归任务**:根据数据分布选择 `MeanSquaredError`MSE`MeanAbsoluteError`MAE`Huber`
- **序列任务**:使用 `CTC Loss` 或自回归损失。
- **自定义需求**:通过继承 `tf.keras.losses.Loss` 类实现灵活的损失函数。
通过合理选择损失函数,可以显著提升模型性能。建议结合具体任务和数据特点进行对比实验,以确定最佳的损失函数。在实际应用中,损失函数的选择可能会影响模型的收敛速度和最终性能,因此需要根据具体情况进行调整。