损失函数 #

损失函数概述 #

损失函数(Loss Function)用于衡量模型预测值与真实值之间的差距,是模型训练优化的核心。

损失函数分类 #

text
┌─────────────────────────────────────────────────────────────┐
│                    损失函数分类                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  回归损失                                                    │
│  ├── MSE (均方误差)                                         │
│  ├── MAE (平均绝对误差)                                     │
│  ├── Huber Loss                                             │
│  └── Log-Cosh Loss                                          │
│                                                             │
│  分类损失                                                    │
│  ├── Binary Crossentropy                                    │
│  ├── Categorical Crossentropy                               │
│  ├── Sparse Categorical Crossentropy                        │
│  └── Hinge Loss                                             │
│                                                             │
│  其他损失                                                    │
│  ├── Contrastive Loss                                       │
│  ├── Triplet Loss                                           │
│  └── Focal Loss                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

回归损失 #

均方误差 (MSE) #

python
import tensorflow as tf
import numpy as np

y_true = tf.constant([1.0, 2.0, 3.0, 4.0])
y_pred = tf.constant([1.1, 1.9, 3.2, 3.8])

# 使用 API
mse = tf.keras.losses.MeanSquaredError()
loss = mse(y_true, y_pred)
print(f"MSE: {loss.numpy()}")

# 手动计算
mse_manual = tf.reduce_mean(tf.square(y_true - y_pred))
print(f"MSE (手动): {mse_manual.numpy()}")

# 在模型中使用
model.compile(
    optimizer='adam',
    loss=tf.keras.losses.MeanSquaredError()
)

# 或简写
model.compile(optimizer='adam', loss='mse')

平均绝对误差 (MAE) #

python
import tensorflow as tf

y_true = tf.constant([1.0, 2.0, 3.0, 4.0])
y_pred = tf.constant([1.1, 1.9, 3.2, 3.8])

mae = tf.keras.losses.MeanAbsoluteError()
loss = mae(y_true, y_pred)
print(f"MAE: {loss.numpy()}")

# 手动计算
mae_manual = tf.reduce_mean(tf.abs(y_true - y_pred))
print(f"MAE (手动): {mae_manual.numpy()}")

Huber Loss #

python
import tensorflow as tf

y_true = tf.constant([1.0, 2.0, 3.0, 10.0])
y_pred = tf.constant([1.1, 1.9, 3.2, 5.0])

# Huber Loss 对异常值更鲁棒
huber = tf.keras.losses.Huber(delta=1.0)
loss = huber(y_true, y_pred)
print(f"Huber Loss: {loss.numpy()}")

# 对比 MSE
mse = tf.keras.losses.MeanSquaredError()
mse_loss = mse(y_true, y_pred)
print(f"MSE: {mse_loss.numpy()}")

Log-Cosh Loss #

python
import tensorflow as tf

y_true = tf.constant([1.0, 2.0, 3.0, 4.0])
y_pred = tf.constant([1.1, 1.9, 3.2, 3.8])

log_cosh = tf.keras.losses.LogCosh()
loss = log_cosh(y_true, y_pred)
print(f"Log-Cosh Loss: {loss.numpy()}")

分类损失 #

二分类交叉熵 #

python
import tensorflow as tf

y_true = tf.constant([0, 1, 0, 1])
y_pred = tf.constant([0.1, 0.9, 0.2, 0.8])

# Binary Crossentropy
bce = tf.keras.losses.BinaryCrossentropy()
loss = bce(y_true, y_pred)
print(f"Binary Crossentropy: {loss.numpy()}")

# from_logits=True(输出层无激活函数)
y_logits = tf.constant([-2.0, 2.0, -1.0, 1.5])
bce_logits = tf.keras.losses.BinaryCrossentropy(from_logits=True)
loss = bce_logits(y_true, y_logits)
print(f"Binary CE (from logits): {loss.numpy()}")

# 在模型中使用
model = tf.keras.Sequential([
    tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='adam', loss='binary_crossentropy')

多分类交叉熵 #

python
import tensorflow as tf

y_true = tf.constant([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
y_pred = tf.constant([[0.9, 0.05, 0.05], [0.1, 0.8, 0.1], [0.1, 0.2, 0.7]])

# Categorical Crossentropy
cce = tf.keras.losses.CategoricalCrossentropy()
loss = cce(y_true, y_pred)
print(f"Categorical Crossentropy: {loss.numpy()}")

# from_logits=True
y_logits = tf.constant([[2.0, 0.5, 0.1], [0.5, 1.5, 0.3], [0.2, 0.5, 2.0]])
cce_logits = tf.keras.losses.CategoricalCrossentropy(from_logits=True)
loss = cce_logits(y_true, y_logits)
print(f"Categorical CE (from logits): {loss.numpy()}")

稀疏分类交叉熵 #

python
import tensorflow as tf

y_true = tf.constant([0, 1, 2])
y_pred = tf.constant([[0.9, 0.05, 0.05], [0.1, 0.8, 0.1], [0.1, 0.2, 0.7]])

# Sparse Categorical Crossentropy(标签为整数)
scce = tf.keras.losses.SparseCategoricalCrossentropy()
loss = scce(y_true, y_pred)
print(f"Sparse Categorical CE: {loss.numpy()}")

# from_logits=True
y_logits = tf.constant([[2.0, 0.5, 0.1], [0.5, 1.5, 0.3], [0.2, 0.5, 2.0]])
scce_logits = tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
loss = scce_logits(y_true, y_logits)
print(f"Sparse CE (from logits): {loss.numpy()}")

# 在模型中使用
model = tf.keras.Sequential([
    tf.keras.layers.Dense(10)
])
model.compile(
    optimizer='adam',
    loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True)
)

Hinge Loss #

python
import tensorflow as tf

y_true = tf.constant([-1, 1, -1, 1])
y_pred = tf.constant([-0.5, 0.8, -0.3, 0.9])

hinge = tf.keras.losses.Hinge()
loss = hinge(y_true, y_pred)
print(f"Hinge Loss: {loss.numpy()}")

# Squared Hinge
squared_hinge = tf.keras.losses.SquaredHinge()
loss = squared_hinge(y_true, y_pred)
print(f"Squared Hinge Loss: {loss.numpy()}")

自定义损失函数 #

函数式定义 #

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)

# 带参数的自定义损失
def weighted_mse(weight):
    def loss(y_true, y_pred):
        return tf.reduce_mean(weight * tf.square(y_true - y_pred))
    return loss

model.compile(optimizer='adam', loss=weighted_mse(2.0))

类式定义 #

python
import tensorflow as tf

class CustomLoss(tf.keras.losses.Loss):
    def __init__(self, name='custom_loss', **kwargs):
        super().__init__(name=name, **kwargs)
    
    def call(self, y_true, y_pred):
        return tf.reduce_mean(tf.square(y_true - y_pred))
    
    def get_config(self):
        return super().get_config()

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

Focal Loss #

python
import tensorflow as tf

class FocalLoss(tf.keras.losses.Loss):
    def __init__(self, gamma=2.0, alpha=0.25, name='focal_loss'):
        super().__init__(name=name)
        self.gamma = gamma
        self.alpha = alpha
    
    def call(self, y_true, y_pred):
        y_pred = tf.clip_by_value(y_pred, 1e-7, 1 - 1e-7)
        pt = tf.where(tf.equal(y_true, 1), y_pred, 1 - y_pred)
        alpha_t = tf.where(tf.equal(y_true, 1), self.alpha, 1 - self.alpha)
        focal_weight = alpha_t * tf.pow(1 - pt, self.gamma)
        bce = tf.keras.losses.binary_crossentropy(y_true, y_pred)
        return tf.reduce_mean(focal_weight * bce)

model.compile(optimizer='adam', loss=FocalLoss(gamma=2.0, alpha=0.25))

Dice Loss #

python
import tensorflow as tf

class DiceLoss(tf.keras.losses.Loss):
    def __init__(self, smooth=1e-6, name='dice_loss'):
        super().__init__(name=name)
        self.smooth = smooth
    
    def call(self, y_true, y_pred):
        y_true = tf.cast(y_true, tf.float32)
        y_pred = tf.cast(y_pred, tf.float32)
        
        intersection = tf.reduce_sum(y_true * y_pred)
        union = tf.reduce_sum(y_true) + tf.reduce_sum(y_pred)
        
        dice = (2.0 * intersection + self.smooth) / (union + self.smooth)
        return 1.0 - dice

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

多损失函数 #

多输出模型 #

python
import tensorflow as tf

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

# 分类输出
class_output = tf.keras.layers.Dense(10, activation='softmax', name='classification')(x)

# 回归输出
reg_output = tf.keras.layers.Dense(1, name='regression')(x)

model = tf.keras.Model(inputs=inputs, outputs=[class_output, reg_output])

model.compile(
    optimizer='adam',
    loss={
        'classification': 'sparse_categorical_crossentropy',
        'regression': 'mse'
    },
    loss_weights={
        'classification': 1.0,
        'regression': 0.5
    }
)

损失函数与正则化 #

python
import tensorflow as tf

# L2 正则化
model = tf.keras.Sequential([
    tf.keras.layers.Dense(
        64,
        activation='relu',
        kernel_regularizer=tf.keras.regularizers.l2(0.01)
    ),
    tf.keras.layers.Dense(10)
])

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

# 正则化损失会自动添加到总损失中

下一步 #

现在你已经掌握了损失函数,接下来学习 优化器,了解如何选择和配置优化算法!

最后更新:2026-04-04