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