正则化概述
正则化是防止机器学习模型过拟合的核心技术,通过在损失函数中添加惩罚项来约束模型复杂度:
偏差-方差分解
概述
理解正则化需先掌握偏差-方差分解:
总误差=偏差2+方差+不可约误差\text{总误差} = \text{偏差}^2 + \text{方差} + \text{不可约误差}总误差=偏差2+方差+不可约误差
- 偏差:模型预测值与真实值的系统性差距
- 方差:模型对训练数据微小变化的敏感度
- 正则化目标:在偏差和方差间取得平衡
所以方差一般指的是数据模型得出来后,能不能对未知数据的扰动预测准确。而偏差说明在训练集当中就已经误差较大了,基本上在测试集中没有好的效果。
解决方法
对于高方差,有以下几种方式:
- 获取更多的数据,使得训练数据能够包含所以可能的情况
- 正则化
- 寻找更合适的网络结构
对于高偏差,有以下几种方式:
- 扩大网络规模
- 寻找合适的网络结构
- 训练时间更长一些
逻辑回归中的L1/L2正则化
L2正则化(岭回归)
原理:添加权重平方和作为惩罚项
损失函数:
J(w)=−1m∑i=1m[y(i)log(y^(i))+(1−y(i))log(1−y^(i))]+λ2m∑j=1nwj2J(w) = -\frac{1}{m}\sum_{i=1}^m [y^{(i)}\log(\hat{y}^{(i)}) + (1-y^{(i)})\log(1-\hat{y}^{(i)})] + \frac{\lambda}{2m}\sum_{j=1}^n w_j^2J(w)=−m1i=1∑m[y(i)log(y^(i))+(1−y(i))log(1−y^(i))]+2mλj=1∑nwj2
特点:
- 使权重趋近于0但不为0
- 提高模型泛化能力
- 适用于特征选择不重要的场景
L1正则化(Lasso回归)
原理:添加权重绝对值之和作为惩罚项
损失函数:
J(w)=−1m∑i=1m[y(i)log(y^(i))+(1−y(i))log(1−y^(i))]+λm∑j=1n∣wj∣J(w) = -\frac{1}{m}\sum_{i=1}^m [y^{(i)}\log(\hat{y}^{(i)}) + (1-y^{(i)})\log(1-\hat{y}^{(i)})] + \frac{\lambda}{m}\sum_{j=1}^n |w_j|J(w)=−m1i=1∑m[y(i)log(y^(i))+(1−y(i))log(1−y^(i))]+mλj=1∑n∣wj∣
特点:
- 产生稀疏权重矩阵(部分权重为0)
- 自动执行特征选择
- 适用于高维数据集
其中,λ\lambdaλ为正则化因子,是超参数。由于 L1 正则化最后得到 w 向量中将存在稀疏,因此L2正则化更加常用。
Python实现
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification
class RegularizedLogisticRegression:
def __init__(self, learning_rate=0.01, n_iters=1000,
lambda_=0.1, regularization='l2'):
self.lr = learning_rate
self.n_iters = n_iters
self.lambda_ = lambda_
self.regularization = regularization
self.weights = None
self.bias = None
def _sigmoid(self, z):
return 1 / (1 + np.exp(-z))
def fit(self, X, y):
m, n = X.shape
self.weights = np.zeros(n)
self.bias = 0
for _ in range(self.n_iters):
# 前向传播
linear_model = np.dot(X, self.weights) + self.bias
y_pred = self._sigmoid(linear_model)
# 计算梯度
dw = (1/m) * np.dot(X.T, (y_pred - y))
db = (1/m) * np.sum(y_pred - y)
# 添加正则化项
if self.regularization == 'l2':
dw += (self.lambda_/m) * self.weights
elif self.regularization == 'l1':
dw += (self.lambda_/m) * np.sign(self.weights)
# 更新参数
self.weights -= self.lr * dw
self.bias -= self.lr * db
def predict(self, X, threshold=0.5):
linear_model = np.dot(X, self.weights) + self.bias
y_pred = self._sigmoid(linear_model)
return (y_pred >= threshold).astype(int)
# 比较L1和L2正则化效果
X, y = make_classification(n_samples=1000, n_features=20,
n_informative=5, random_state=42)
# 训练不同正则化模型
model_l2 = RegularizedLogisticRegression(lambda_=0.5, regularization='l2')
model_l2.fit(X, y)
model_l1 = RegularizedLogisticRegression(lambda_=0.5, regularization='l1')
model_l1.fit(X, y)
# 可视化权重分布
plt.figure(figsize=(14, 6))
plt.subplot(1, 2, 1)
plt.stem(model_l2.weights)
plt.title("L2 Regularization Weights")
plt.xlabel("Feature Index")
plt.ylabel("Weight Value")
plt.subplot(1, 2, 2)
plt.stem(model_l1.weights)
plt.title("L1 Regularization Weights")
plt.xlabel("Feature Index")
plt.ylabel("Weight Value")
plt.show()
- 典型输出
输出示例图
神经网络中的正则化
L2正则化(权重衰减)
原理:对所有权重添加平方惩罚项
损失函数:
J(w)=原始损失+λ2m∑l=1L∥W[l]∥F2J(w) = \text{原始损失} + \frac{\lambda}{2m}\sum_{l=1}^L \|W^{[l]}\|_F^2J(w)=原始损失+2mλl=1∑L∥W[l]∥F2
梯度更新:
∂J∂W[l]=原始梯度+λmW[l]\frac{\partial J}{\partial W^{[l]}} = \text{原始梯度} + \frac{\lambda}{m} W^{[l]}∂W[l]∂J=原始梯度+mλW[l]
Dropout正则化

原理:训练时随机丢弃部分神经元
实现步骤:
- 设置保留概率 keep_probkeep\_probkeep_prob
- 对每层生成随机掩码 d[l]∼Bernoulli(keep_prob)d^{[l]} \sim \text{Bernoulli}(keep\_prob)d[l]∼Bernoulli(keep_prob)
- 激活值 a[l]=a[l]∗d[l]a^{[l]} = a^{[l]} * d^{[l]}a[l]=a[l]∗d[l]
- 缩放激活值 a[l]=a[l]/keep_proba^{[l]} = a^{[l]} / keep\_proba[l]=a[l]/keep_prob
Python实现:
def dropout_forward(A, keep_prob):
D = np.random.rand(*A.shape) < keep_prob
A = A * D
A = A / keep_prob
return A, D
def dropout_backward(dA, D, keep_prob):
dA = dA * D
dA = dA / keep_prob
return dA
其他正则化技术
1. 早停止法 (Early Stopping)

- 通常不断训练后,损失越来越小。但是到了一定之后,模型学到的过于复杂,造成测试集开始损失较小,后来又变大。模型的w参数会越来越大,那么可以在测试集损失减小一定程度之后停止训练。
Python实现:
def early_stopping(train_loss, val_loss, patience=5):
if len(val_loss) < patience + 1:
return False
# 检查最近patience次迭代是否无改善
min_loss = min(val_loss)
recent_losses = val_loss[-patience-1:-1]
if all(loss >= min_loss for loss in recent_losses):
return True
return False
2. 数据增强 (Data Augmentation)
原理:通过对训练数据应用随机变换来增加数据多样性
常用技术:
图像:旋转、翻转、缩放、裁剪、颜色变换
文本:同义词替换、随机插入、随机删除
音频:时移、变速、添加噪声
图像数据增强示意图
Python实现(图像增强):
from tensorflow.keras.preprocessing.image import ImageDataGenerator
datagen = ImageDataGenerator(
rotation_range=20,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True,
fill_mode='nearest'
)
# 应用数据增强
augmented_images = []
for img in original_images:
img = img.reshape((1,) + img.shape) # 添加批次维度
for batch in datagen.flow(img, batch_size=1):
augmented_images.append(batch[0])
break # 每个原始图像生成一个增强版本
3. 批归一化 (Batch Normalization)
原理:标准化每层的输入
公式:
x^=x−μσ2+ϵ\hat{x} = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}}x^=σ2+ϵx−μ
y=γx^+βy = \gamma \hat{x} + \betay=γx^+β
效果:
- 允许使用更高学习率
- 减少对初始化的依赖
- 具有轻微正则化效果
正则化技术对比
技术 | 优点 | 缺点 | 适用场景 |
---|---|---|---|
L2正则化 | 简单有效,防止过拟合 | 不产生稀疏解 | 大多数神经网络 |
L1正则化 | 产生稀疏解,特征选择 | 不适合深度学习 | 高维线性模型 |
Dropout | 高效,近似模型集成 | 训练时间增加 | 全连接网络 |
早停止法 | 无需额外计算 | 需要验证集 | 所有模型 |
数据增强 | 不增加模型复杂度 | 领域特定 | 计算机视觉 |
批归一化 | 加速训练,允许高学习率 | 实现复杂 | 深层网络 |
正则化选择指南
实际应用建议
- 基础策略:始终使用L2正则化(λ=0.001-0.1)
- 全连接层:添加Dropout(keep_prob=0.5-0.8)
- 计算机视觉:优先使用数据增强
- 训练监控:实施早停止法(patience=5-20)
- 深层网络:结合批归一化
- 超参数调优:使用交叉验证确定最佳λ
总结
正则化是深度学习模型成功的关键:
- 核心目标:平衡偏差与方差,提高泛化能力
- 基础技术:L1/L2正则化适用于简单模型
- 深度网络:Dropout、批归一化更有效
- 通用策略:早停止法、数据增强几乎无成本
- 最佳实践:组合多种正则化技术
理解不同正则化技术的原理和适用场景,对于构建鲁棒、高效的深度学习模型至关重要。