正则化层 #

为什么需要正则化? #

text
┌─────────────────────────────────────────────────────────────┐
│                    过拟合问题                                │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  欠拟合 (Underfitting)                                      │
│  ├── 训练误差高                                            │
│  ├── 测试误差高                                            │
│  └── 原因: 模型太简单                                      │
│                                                             │
│  过拟合 (Overfitting)                                       │
│  ├── 训练误差低                                            │
│  ├── 测试误差高                                            │
│  └── 原因: 模型太复杂                                      │
│                                                             │
│  正则化目标:                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │  在保持训练性能的同时,提高泛化能力                  │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Dropout 层 #

原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Dropout 原理                              │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  训练时:                                                    │
│  ┌───┬───┬───┬───┐       ┌───┬───┬───┬───┐               │
│  │ 1 │ 2 │ 3 │ 4 │  ───► │ 1 │ 0 │ 3 │ 0 │               │
│  └───┴───┴───┴───┘       └───┴───┴───┴───┘               │
│                           随机丢弃 rate 比例               │
│                                                             │
│  推理时:                                                    │
│  所有神经元都参与,输出乘以 (1 - rate)                      │
│                                                             │
│  效果:                                                      │
│  ├── 防止神经元过度依赖特定特征                             │
│  ├── 相当于训练多个子网络的集成                             │
│  └── 提高模型泛化能力                                       │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基本用法 #

python
import keras

model = keras.Sequential([
    keras.layers.Dense(512, activation='relu', input_shape=(784,)),
    keras.layers.Dropout(0.5),
    keras.layers.Dense(256, activation='relu'),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(10, activation='softmax')
])

参数详解 #

python
keras.layers.Dropout(
    rate=0.5,
    noise_shape=None,
    seed=None
)

不同位置的 Dropout #

python
import keras

inputs = keras.Input(shape=(784,))

x = keras.layers.Dense(512, activation='relu')(inputs)
x = keras.layers.Dropout(0.5)(x)

x = keras.layers.Dense(256, activation='relu')(x)
x = keras.layers.Dropout(0.3)(x)

outputs = keras.layers.Dense(10, activation='softmax')(x)

model = keras.Model(inputs, outputs)

Dropout 规律 #

text
┌─────────────────────────────────────────────────────────────┐
│                    Dropout 使用建议                          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  常用丢弃率:                                                │
│  ├── 输入层后: 0.1 - 0.2                                   │
│  ├── 隐藏层: 0.3 - 0.5                                     │
│  └── 输出层前: 0.3 - 0.5                                   │
│                                                             │
│  注意事项:                                                  │
│  ├── 丢弃率不宜过高 (通常 < 0.5)                           │
│  ├── 只在训练时生效                                        │
│  ├── 增加训练时间                                          │
│  └── 小数据集慎用                                          │
│                                                             │
└─────────────────────────────────────────────────────────────┘

BatchNormalization 层 #

原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    BatchNormalization 原理                   │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  输入: x (batch_size, features)                             │
│                                                             │
│  步骤:                                                      │
│  1. 计算批次均值: μ = mean(x, axis=0)                       │
│  2. 计算批次方差: σ² = var(x, axis=0)                       │
│  3. 归一化: x̂ = (x - μ) / √(σ² + ε)                        │
│  4. 缩放平移: y = γ × x̂ + β                                │
│                                                             │
│  可学习参数:                                                │
│  ├── γ (gamma): 缩放因子                                   │
│  └── β (beta): 平移因子                                    │
│                                                             │
│  优点:                                                      │
│  ├── 加速收敛                                              │
│  ├── 允许更大学习率                                        │
│  ├── 减少对初始化的敏感                                    │
│  └── 轻微正则化效果                                        │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基本用法 #

python
import keras

model = keras.Sequential([
    keras.layers.Dense(512, input_shape=(784,)),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.Dropout(0.3),
    keras.layers.Dense(256),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.Dense(10, activation='softmax')
])

CNN 中的 BatchNormalization #

python
import keras

model = keras.Sequential([
    keras.layers.Conv2D(64, 3, padding='same', input_shape=(32, 32, 3)),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.Conv2D(64, 3, padding='same'),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.MaxPooling2D(),
    keras.layers.Flatten(),
    keras.layers.Dense(10, activation='softmax')
])

参数详解 #

python
keras.layers.BatchNormalization(
    axis=-1,
    momentum=0.99,
    epsilon=0.001,
    center=True,
    scale=True,
    beta_initializer='zeros',
    gamma_initializer='ones'
)

LayerNormalization 层 #

原理 #

text
┌─────────────────────────────────────────────────────────────┐
│                    LayerNormalization vs BatchNorm          │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  BatchNormalization:                                        │
│  ├── 在批次维度上归一化                                    │
│  ├── 依赖批次大小                                          │
│  └── 适合 CNN                                              │
│                                                             │
│  LayerNormalization:                                        │
│  ├── 在特征维度上归一化                                    │
│  ├── 不依赖批次大小                                        │
│  └── 适合 RNN/Transformer                                  │
│                                                             │
│  示例 (batch=2, features=3):                               │
│                                                             │
│  BatchNorm: 在每列上归一化                                  │
│  ┌───┬───┬───┐                                             │
│  │ a │ b │ c │  ← 归一化这一列                             │
│  ├───┼───┼───┤                                             │
│  │ d │ e │ f │  ← 归一化这一列                             │
│  └───┴───┴───┘                                             │
│                                                             │
│  LayerNorm: 在每行上归一化                                  │
│  ┌───┬───┬───┐                                             │
│  │ a │ b │ c │  ← 归一化这一行                             │
│  └───┴───┴───┘                                             │
│  ┌───┬───┬───┐                                             │
│  │ d │ e │ f │  ← 归一化这一行                             │
│  └───┴───┴───┘                                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

基本用法 #

python
import keras

model = keras.Sequential([
    keras.layers.Embedding(10000, 128, input_length=100),
    keras.layers.LSTM(64, return_sequences=True),
    keras.layers.LayerNormalization(),
    keras.layers.Dense(10, activation='softmax')
])

Transformer 中的 LayerNormalization #

python
import keras

def transformer_encoder(inputs, head_size, num_heads, ff_dim, dropout=0):
    x = keras.layers.MultiHeadAttention(
        num_heads=num_heads, key_dim=head_size
    )(inputs, inputs)
    x = keras.layers.Dropout(dropout)(x)
    x = keras.layers.LayerNormalization(epsilon=1e-6)(x + inputs)
    
    x = keras.layers.Conv1D(filters=ff_dim, kernel_size=1, activation='relu')(x)
    x = keras.layers.Dropout(dropout)(x)
    x = keras.layers.Conv1D(filters=inputs.shape[-1], kernel_size=1)(x)
    x = keras.layers.LayerNormalization(epsilon=1e-6)(x + inputs)
    
    return x

AlphaDropout 层 #

AlphaDropout 保持自归一化属性,适合 SELU 激活函数。

python
import keras

model = keras.Sequential([
    keras.layers.Dense(512, activation='selu', input_shape=(784,)),
    keras.layers.AlphaDropout(0.1),
    keras.layers.Dense(256, activation='selu'),
    keras.layers.AlphaDropout(0.1),
    keras.layers.Dense(10, activation='softmax')
])

GaussianDropout 层 #

GaussianDropout 使用乘法高斯噪声。

python
import keras

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

GaussianNoise 层 #

GaussianNoise 添加高斯噪声,用于输入正则化。

python
import keras

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

SpatialDropout 层 #

SpatialDropout 整个特征图一起丢弃,适合 CNN。

python
import keras

model = keras.Sequential([
    keras.layers.Conv2D(32, 3, activation='relu', input_shape=(28, 28, 1)),
    keras.layers.SpatialDropout2D(0.2),
    keras.layers.Conv2D(64, 3, activation='relu'),
    keras.layers.SpatialDropout2D(0.2),
    keras.layers.Flatten(),
    keras.layers.Dense(10, activation='softmax')
])

ActivityRegularization 层 #

ActivityRegularization 对层输出应用 L1/L2 正则化。

python
import keras

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

权重正则化 #

除了正则化层,还可以在层上应用权重正则化。

python
import keras

model = keras.Sequential([
    keras.layers.Dense(
        64,
        activation='relu',
        kernel_regularizer=keras.regularizers.L2(0.01),
        bias_regularizer=keras.regularizers.L2(0.01),
        activity_regularizer=keras.regularizers.L1(0.01),
        input_shape=(784,)
    ),
    keras.layers.Dense(10, activation='softmax')
])

完整示例 #

python
import keras

model = keras.Sequential([
    keras.layers.Input(shape=(784,)),
    
    keras.layers.Dense(512),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.Dropout(0.3),
    
    keras.layers.Dense(256),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.Dropout(0.3),
    
    keras.layers.Dense(128),
    keras.layers.BatchNormalization(),
    keras.layers.Activation('relu'),
    keras.layers.Dropout(0.2),
    
    keras.layers.Dense(10, activation='softmax')
])

model.compile(
    optimizer=keras.optimizers.Adam(learning_rate=0.001),
    loss='sparse_categorical_crossentropy',
    metrics=['accuracy']
)

model.summary()

下一步 #

现在你已经掌握了正则化层,接下来学习 激活函数,为网络引入非线性!

最后更新:2026-04-04