TeamClass_MD/Class1- DeepLearning 1/Topic1/Tensorflow的损失函数.md
2025-03-19 09:29:17 +08:00

219 lines
8.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

### **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` 类实现灵活的损失函数。
通过合理选择损失函数,可以显著提升模型性能。建议结合具体任务和数据特点进行对比实验,以确定最佳的损失函数。在实际应用中,损失函数的选择可能会影响模型的收敛速度和最终性能,因此需要根据具体情况进行调整。