一、损失函数的核心分类

根据机器学习任务类型,损失函数可分为三大类:回归损失函数(预测连续值)、分类损失函数(预测离散类别)、其他特殊损失函数(适用于排序、生成等任务)。

二、回归损失函数(Regression Loss)

1. 均方误差(Mean Squared Error, MSE)

数学公式
  • 单个样本的损失(平方误差,SE): L S E ( y ^ i , y i ) = ( y ^ i − y i ) 2 L_{SE}(\hat{y}_i, y_i) = (\hat{y}_i - y_i)^2 LSE(y^i,yi)=(y^iyi)2
  • 全样本的损失(均方误差,MSE): L M S E ( y ^ , y ) = 1 n ∑ i = 1 n ( y ^ i − y i ) 2 L_{MSE}(\hat{y}, y) = \frac{1}{n} \sum_{i=1}^n (\hat{y}_i - y_i)^2 LMSE(y^,y)=n1i=1n(y^iyi)2
代码实现
import numpy as np
import tensorflow as tf
from tensorflow.keras.losses import MeanSquaredError

def mse_loss(y_true, y_pred):
    n = len(y_true)
    return np.sum((y_pred - y_true) ** 2) / n

y_true = tf.constant([[1.2], [2.5], [3.1], [4.7], [5.3], 
                      [6.8], [7.2], [8.5], [9.1], [10.4]], dtype=tf.float32)
y_pred = tf.constant([[1.0], [2.3], [3.5], [4.9], [5.1], 
                      [6.6], [7.5], [8.3], [9.4], [10.2]], dtype=tf.float32)

tf_mse_manual = tf.reduce_mean(tf.square(y_pred - y_true))
tf_mse = MeanSquaredError()(y_true, y_pred)

print("NumPy MSE:", mse_loss(y_true.numpy(), y_pred.numpy()))
print("TensorFlow manual MSE:", tf_mse_manual.numpy())
print("TensorFlow built-in MSE:", tf_mse.numpy())

MSE Loss Calculation Comparison

2. 平均绝对误差(Mean Absolute Error, MAE)

数学公式
  • 单个样本的损失(绝对误差,AE): L A E ( y ^ i , y i ) = ∣ y ^ i − y i ∣ L_{AE}(\hat{y}_i, y_i) = |\hat{y}_i - y_i| LAE(y^i,yi)=y^iyi
  • 全样本的损失(平均绝对误差,MAE): L M A E ( y ^ , y ) = 1 n ∑ i = 1 n ∣ y ^ i − y i ∣ L_{MAE}(\hat{y}, y) = \frac{1}{n} \sum_{i=1}^n |\hat{y}_i - y_i| LMAE(y^,y)=n1i=1ny^iyi
代码实现
import numpy as np
import tensorflow as tf
from tensorflow.keras.losses import MeanAbsoluteError

def mae_loss(y_true, y_pred):
    n = len(y_true)
    return np.sum(np.abs(y_pred - y_true)) / n

y_true = tf.constant([[1.2], [2.5], [3.1], [4.7], [5.3], 
                      [6.8], [7.2], [8.5], [9.1], [10.4]], dtype=tf.float32)
y_pred = tf.constant([[1.0], [2.3], [3.5], [4.9], [5.1], 
                      [6.6], [7.5], [8.3], [9.4], [10.2]], dtype=tf.float32)

tf_mae_manual = tf.reduce_mean(tf.abs(y_pred - y_true))
tf_mae = MeanAbsoluteError()(y_true, y_pred)

print("NumPy MAE:", mae_loss(y_true.numpy(), y_pred.numpy()))
print("TensorFlow manual MAE:", tf_mae_manual.numpy())
print("TensorFlow built-in MAE:", tf_mae.numpy())

MAE Loss Calculation Comparison

3. Huber损失(Huber Loss)

数学公式

L H u b e r ( y ^ i , y i ) = { 1 2 ( y ^ i − y i ) 2 if  ∣ y ^ i − y i ∣ ≤ δ δ ( ∣ y ^ i − y i ∣ − 1 2 δ ) if  ∣ y ^ i − y i ∣ > δ L_{Huber}(\hat{y}_i, y_i) = \begin{cases} \frac{1}{2}(\hat{y}_i - y_i)^2 & \text{if } |\hat{y}_i - y_i| \leq \delta \\ \delta(|\hat{y}_i - y_i| - \frac{1}{2}\delta) & \text{if } |\hat{y}_i - y_i| > \delta \end{cases} LHuber(y^i,yi)={21(y^iyi)2δ(y^iyi21δ)if y^iyiδif y^iyi>δ

全样本损失: L H u b e r ( y ^ , y ) = 1 n ∑ i = 1 n L H u b e r ( y ^ i , y i ) L_{Huber}(\hat{y}, y) = \frac{1}{n} \sum_{i=1}^n L_{Huber}(\hat{y}_i, y_i) LHuber(y^,y)=n1i=1nLHuber(y^i,yi)

代码实现
import tensorflow as tf

def huber_loss(y_true, y_pred, delta=1.0):
    error = y_pred - y_true
    abs_error = tf.abs(error)
    huber_term = tf.where(abs_error <= delta, 
                          0.5 * tf.square(error), 
                          delta * (abs_error - 0.5 * delta))
    return tf.reduce_mean(huber_term)

y_true = tf.constant([[1.2], [2.5], [3.1], [4.7], [20.0],
                      [6.8], [7.2], [8.5], [9.1], [10.4]], dtype=tf.float32)
y_pred = tf.constant([[1.0], [2.3], [3.5], [4.9], [5.1],
                      [6.6], [7.5], [8.3], [9.4], [10.2]], dtype=tf.float32)

huber = huber_loss(y_true, y_pred, delta=2.0)
mse = tf.reduce_mean(tf.square(y_pred - y_true))

print("Huber loss (delta=2.0):", huber.numpy())
print("MSE loss:", mse.numpy())

三、分类损失函数(Classification Loss)

1. 二元交叉熵(Binary Cross-Entropy, BCE)

数学公式
  • 单个样本的损失: L B C E ( p ^ i , y i ) = − [ y i ⋅ log ⁡ ( p ^ i ) + ( 1 − y i ) ⋅ log ⁡ ( 1 − p ^ i ) ] L_{BCE}(\hat{p}_i, y_i) = -[y_i \cdot \log(\hat{p}_i) + (1 - y_i) \cdot \log(1 - \hat{p}_i)] LBCE(p^i,yi)=[yilog(p^i)+(1yi)log(1p^i)]
  • 全样本的损失: L B C E ( p ^ , y ) = − 1 n ∑ i = 1 n [ y i ⋅ log ⁡ ( p ^ i ) + ( 1 − y i ) ⋅ log ⁡ ( 1 − p ^ i ) ] L_{BCE}(\hat{p}, y) = -\frac{1}{n} \sum_{i=1}^n [y_i \cdot \log(\hat{p}_i) + (1 - y_i) \cdot \log(1 - \hat{p}_i)] LBCE(p^,y)=n1i=1n[yilog(p^i)+(1yi)log(1p^i)]
代码实现
import tensorflow as tf
from tensorflow.keras.losses import BinaryCrossentropy

y_true = tf.constant([[1], [0], [1], [0], [1], [0], [1], [0], [1], [0]], dtype=tf.float32)
y_pred_logits = tf.constant([[2.3], [-1.2], [3.1], [-2.5], [1.8], 
                             [-0.9], [4.2], [-3.7], [2.9], [-1.5]], dtype=tf.float32)

bce_with_logits = BinaryCrossentropy(from_logits=True)(y_true, y_pred_logits)
y_pred_prob = tf.sigmoid(y_pred_logits)
bce_with_prob = BinaryCrossentropy(from_logits=False)(y_true, y_pred_prob)

print("BCE (with logits):", bce_with_logits.numpy())
print("BCE (with probabilities):", bce_with_prob.numpy())

2. Categorical交叉熵(Categorical Cross-Entropy, CCE)

数学公式
  • 单个样本的损失: L C C E ( p ^ i , y i ) = − ∑ c = 1 C y i , c ⋅ log ⁡ ( p ^ i , c ) L_{CCE}(\hat{p}_i, y_i) = -\sum_{c=1}^C y_{i,c} \cdot \log(\hat{p}_{i,c}) LCCE(p^i,yi)=c=1Cyi,clog(p^i,c)
  • 全样本的损失: L C C E ( p ^ , y ) = − 1 n ∑ i = 1 n ∑ c = 1 C y i , c ⋅ log ⁡ ( p ^ i , c ) L_{CCE}(\hat{p}, y) = -\frac{1}{n} \sum_{i=1}^n \sum_{c=1}^C y_{i,c} \cdot \log(\hat{p}_{i,c}) LCCE(p^,y)=n1i=1nc=1Cyi,clog(p^i,c)
代码实现
import tensorflow as tf
from tensorflow.keras.losses import CategoricalCrossentropy

y_true = tf.constant([[1,0,0], [0,1,0], [0,0,1], [1,0,0], [0,1,0],
                      [0,0,1], [1,0,0], [0,1,0], [0,0,1], [1,0,0]], dtype=tf.float32)
y_pred_logits = tf.constant([[3.2, 1.5, 0.8], [2.1, 4.3, 1.2], [0.5, 1.8, 5.1],
                             [4.7, 0.9, 2.3], [1.8, 3.9, 0.7], [2.2, 1.5, 4.8],
                             [3.5, 2.1, 1.0], [0.9, 5.2, 1.5], [1.2, 2.3, 3.8],
                             [4.1, 1.3, 0.6]], dtype=tf.float32)

cce_with_logits = CategoricalCrossentropy(from_logits=True)(y_true, y_pred_logits)
y_pred_prob = tf.nn.softmax(y_pred_logits)
cce_with_prob = CategoricalCrossentropy(from_logits=False)(y_true, y_pred_prob)

print("CCE (with logits):", cce_with_logits.numpy())
print("CCE (with probabilities):", cce_with_prob.numpy())

3. Sparse Categorical交叉熵(Sparse CCE)

数学公式

与CCE相同,仅真实标签为类别索引: y i ∈ { 0 , 1 , . . . , C − 1 } y_i \in \{0,1,...,C-1\} yi{0,1,...,C1}

代码实现
import tensorflow as tf
from tensorflow.keras.losses import SparseCategoricalCrossentropy

y_true = tf.constant([0, 1, 2, 0, 1, 2, 0, 1, 2, 0], dtype=tf.int32)
y_pred_logits = tf.constant([[3.2, 1.5, 0.8], [2.1, 4.3, 1.2], [0.5, 1.8, 5.1],
                             [4.7, 0.9, 2.3], [1.8, 3.9, 0.7], [2.2, 1.5, 4.8],
                             [3.5, 2.1, 1.0], [0.9, 5.2, 1.5], [1.2, 2.3, 3.8],
                             [4.1, 1.3, 0.6]], dtype=tf.float32)

sparse_cce = SparseCategoricalCrossentropy(from_logits=True)(y_true, y_pred_logits)
print("Sparse CCE:", sparse_cce.numpy())

4. 铰链损失(Hinge Loss)

数学公式

L H i n g e ( y i , y ^ i ) = max ⁡ ( 0 , 1 − y i ⋅ y ^ i ) L_{Hinge}(y_i, \hat{y}_i) = \max(0, 1 - y_i \cdot \hat{y}_i) LHinge(yi,y^i)=max(0,1yiy^i),其中 y i ∈ { − 1 , 1 } y_i \in \{-1, 1\} yi{1,1}为真实标签, y ^ i \hat{y}_i y^i为模型未归一化的输出

代码实现
import tensorflow as tf
from tensorflow.keras.losses import Hinge

y_true = tf.constant([[1], [-1], [1], [-1], [1]], dtype=tf.float32)
y_pred = tf.constant([[0.8], [-0.9], [1.2], [-0.7], [0.3]], dtype=tf.float32)

hinge_loss = Hinge()(y_true, y_pred)
print("Hinge loss:", hinge_loss.numpy())

四、损失函数的选择原则

  1. 回归任务优先考虑MSE(无异常值)或MAE(有异常值),Huber损失为折中方案
  2. 二分类任务使用二元交叉熵(BCE)
  3. 多分类任务:
    • 标签为独热编码 → Categorical交叉熵
    • 标签为类别索引 → Sparse Categorical交叉熵
  4. 支持向量机等间隔最大化模型 → 铰链损失

选择时需结合数据特性(是否有异常值)、任务类型(分类/回归)和模型输出形式综合判断。

另外我整理了损失函数相关资料,感兴趣的dd!

原文 资料 这里!

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐