正则化层 #
为什么需要正则化? #
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