损失函数 #

什么是损失函数? #

损失函数衡量模型预测值与真实值之间的差距,是模型优化的目标。

text
┌─────────────────────────────────────────────────────────────┐
│                    损失函数的作用                            │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  预测值 ──► 损失函数 ──► 损失值                             │
│     ↑                          │                            │
│  真实值 ────────────────────────┘                           │
│                                                             │
│  训练目标: 最小化损失函数                                   │
│                                                             │
│  选择原则:                                                  │
│  ├── 回归问题: MSE, MAE, Huber                             │
│  ├── 二分类: Binary Crossentropy                           │
│  └── 多分类: Categorical Crossentropy                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘

回归损失函数 #

MeanSquaredError(均方误差) #

text
┌─────────────────────────────────────────────────────────────┐
│                    MSE 公式                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  MSE = (1/n) × Σ(y_true - y_pred)²                          │
│                                                             │
│  特点:                                                      │
│  ├── 对大误差敏感(平方惩罚)                              │
│  ├── 数学性质好(可微分)                                  │
│  └── 适合回归问题                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import keras

model = keras.Sequential([
    keras.layers.Dense(64, activation='relu', input_shape=(10,)),
    keras.layers.Dense(1)
])

model.compile(
    optimizer='adam',
    loss='mse',
    metrics=['mae']
)

model.compile(
    optimizer='adam',
    loss=keras.losses.MeanSquaredError()
)

MeanAbsoluteError(平均绝对误差) #

text
┌─────────────────────────────────────────────────────────────┐
│                    MAE 公式                                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  MAE = (1/n) × Σ|y_true - y_pred|                           │
│                                                             │
│  特点:                                                      │
│  ├── 对异常值鲁棒                                          │
│  ├── 在零点不可微分                                        │
│  └── 适合有噪声的数据                                      │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import keras

model.compile(
    optimizer='adam',
    loss='mae'
)

model.compile(
    optimizer='adam',
    loss=keras.losses.MeanAbsoluteError()
)

Huber Loss #

text
┌─────────────────────────────────────────────────────────────┐
│                    Huber Loss                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  当 |y_true - y_pred| ≤ δ:                                  │
│    L = 0.5 × (y_true - y_pred)²                             │
│                                                             │
│  当 |y_true - y_pred| > δ:                                  │
│    L = δ × |y_true - y_pred| - 0.5 × δ²                     │
│                                                             │
│  特点:                                                      │
│  ├── 结合 MSE 和 MAE 的优点                                │
│  ├── 对小误差用 MSE(精确)                                │
│  ├── 对大误差用 MAE(鲁棒)                                │
│  └── 适合有噪声的回归问题                                  │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import keras

model.compile(
    optimizer='adam',
    loss=keras.losses.Huber(delta=1.0)
)

MeanAbsolutePercentageError #

python
import keras

model.compile(
    optimizer='adam',
    loss='mape'
)

model.compile(
    optimizer='adam',
    loss=keras.losses.MeanAbsolutePercentageError()
)

分类损失函数 #

BinaryCrossentropy(二元交叉熵) #

text
┌─────────────────────────────────────────────────────────────┐
│                    Binary Crossentropy                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  L = -[y_true × log(y_pred) + (1-y_true) × log(1-y_pred)]   │
│                                                             │
│  适用场景:                                                  │
│  ├── 二分类问题                                            │
│  └── 输出层使用 Sigmoid 激活                                │
│                                                             │
│  标签格式: 0 或 1                                           │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import keras

model = keras.Sequential([
    keras.layers.Dense(64, activation='relu', input_shape=(20,)),
    keras.layers.Dense(1, activation='sigmoid')
])

model.compile(
    optimizer='adam',
    loss='binary_crossentropy',
    metrics=['accuracy']
)

model.compile(
    optimizer='adam',
    loss=keras.losses.BinaryCrossentropy()
)

CategoricalCrossentropy(分类交叉熵) #

text
┌─────────────────────────────────────────────────────────────┐
│                    Categorical Crossentropy                  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  L = -Σ y_true × log(y_pred)                                │
│                                                             │
│  适用场景:                                                  │
│  ├── 多分类问题                                            │
│  └── 输出层使用 Softmax 激活                                │
│                                                             │
│  标签格式: one-hot 编码                                     │
│  例: [0, 0, 1, 0] 表示第 3 类                               │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import keras

model = keras.Sequential([
    keras.layers.Dense(64, activation='relu', input_shape=(784,)),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer='adam',
    loss='categorical_crossentropy',
    metrics=['accuracy']
)

model.compile(
    optimizer='adam',
    loss=keras.losses.CategoricalCrossentropy()
)

SparseCategoricalCrossentropy #

text
┌─────────────────────────────────────────────────────────────┐
│                    Sparse Categorical Crossentropy           │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  与 CategoricalCrossentropy 相同,但标签格式不同            │
│                                                             │
│  标签格式: 整数索引                                         │
│  例: 2 表示第 3 类                                          │
│                                                             │
│  优点:                                                      │
│  ├── 节省内存                                              │
│  └── 更方便使用                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘
python
import keras

model = keras.Sequential([
    keras.layers.Dense(64, activation='relu', input_shape=(784,)),
    keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer='adam',
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

model.compile(
    optimizer='adam',
    loss=keras.losses.SparseCategoricalCrossentropy()
)

from_logits 参数 #

python
import keras

model = keras.Sequential([
    keras.layers.Dense(64, activation='relu', input_shape=(784,)),
    keras.layers.Dense(10)
])

model.compile(
    optimizer='adam',
    loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True)
)

predictions = keras.ops.softmax(model.predict(x_test), axis=-1)

其他损失函数 #

KLDivergence(KL 散度) #

python
import keras

model.compile(
    optimizer='adam',
    loss=keras.losses.KLDivergence()
)

CosineSimilarity #

python
import keras

model.compile(
    optimizer='adam',
    loss=keras.losses.CosineSimilarity(axis=-1)
)

Poisson #

python
import keras

model.compile(
    optimizer='adam',
    loss=keras.losses.Poisson()
)

Hinge #

python
import keras

model.compile(
    optimizer='adam',
    loss=keras.losses.Hinge()
)

SquaredHinge #

python
import keras

model.compile(
    optimizer='adam',
    loss=keras.losses.SquaredHinge()
)

自定义损失函数 #

函数方式 #

python
import keras
import keras.ops as ops

def custom_mse(y_true, y_pred):
    return ops.mean(ops.square(y_true - y_pred))

model.compile(
    optimizer='adam',
    loss=custom_mse
)

类方式 #

python
import keras

class CustomLoss(keras.losses.Loss):
    def __init__(self, name='custom_loss'):
        super().__init__(name=name)
    
    def call(self, y_true, y_pred):
        return keras.ops.mean(keras.ops.square(y_true - y_pred))

model.compile(
    optimizer='adam',
    loss=CustomLoss()
)

多输出模型的损失函数 #

python
import keras

inputs = keras.Input(shape=(100,))
x = keras.layers.Dense(64, activation='relu')(inputs)

class_output = keras.layers.Dense(10, activation='softmax', name='class')(x)
bbox_output = keras.layers.Dense(4, name='bbox')(x)

model = keras.Model(inputs, [class_output, bbox_output])

model.compile(
    optimizer='adam',
    loss={
        'class': 'categorical_crossentropy',
        'bbox': 'mse'
    },
    loss_weights={
        'class': 1.0,
        'bbox': 10.0
    },
    metrics={
        'class': ['accuracy'],
        'bbox': ['mae']
    }
)

损失函数选择指南 #

text
┌─────────────────────────────────────────────────────────────┐
│                    损失函数选择                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  回归问题:                                                  │
│  ├── 一般情况: MSE                                         │
│  ├── 有异常值: MAE 或 Huber                                │
│  └── 需要相对误差: MAPE                                    │
│                                                             │
│  分类问题:                                                  │
│  ├── 二分类: Binary Crossentropy                           │
│  ├── 多分类 (one-hot): Categorical Crossentropy            │
│  ├── 多分类 (整数): Sparse Categorical Crossentropy        │
│  └── 大量类别: from_logits=True                            │
│                                                             │
│  其他:                                                      │
│  ├── VAE: MSE + KL Divergence                              │
│  ├── 相似度: Cosine Similarity                             │
│  └── SVM: Hinge                                            │
│                                                             │
└─────────────────────────────────────────────────────────────┘

下一步 #

现在你已经掌握了损失函数,接下来学习 优化器,了解如何优化模型参数!

最后更新:2026-04-04