正则化
正则化主要解决的问题
为了解决模型过拟合、欠拟合问题,引入正则化提升模型表现。
两者基础知识和区别
1、L1正则化约束公式:
Loss with L1 = Loss + λ ∑ i = 1 n ∣ w i ∣ λ 是正则化参数,用来控制正则化项对总损失的影响程度 w i 表示模型中的第 i 个权重参数 \text{Loss with L1} = \text{Loss} + \lambda \sum_{i=1}^{n} |w_i| \\ \lambda 是正则化参数,用来控制正则化项对总损失的影响程度 \\ w_i 表示模型中的第i个权重参数 Loss with L1=Loss+λi=1∑n∣wi∣λ是正则化参数,用来控制正则化项对总损失的影响程度wi表示模型中的第i个权重参数
2、L2正则化约束公式:
Loss with L2 = Loss + λ ∑ i = 1 n w i 2 λ 是正则化参数,用来控制正则化项对总损失的影响程度 w i 表示模型中的第 i 个权重参数 \text{Loss with L2} = \text{Loss} + \lambda \sum_{i=1}^{n} w_i^2 \\ \lambda 是正则化参数,用来控制正则化项对总损失的影响程度 \\ w_i 表示模型中的第i个权重参数 \\ Loss with L2=Loss+λi=1∑nwi2λ是正则化参数,用来控制正则化项对总损失的影响程度wi表示模型中的第i个权重参数
L1正则化和L2正则化的主要区别在于它们对模型参数的约束方式不同 L1是参数的绝对值之和,L2为参数的平方和的开方值(有时直接使用平方和,方便求导)
最主要的区别:稀疏性
- L1正则化:倾向于产生稀疏的权重矩阵,即很多参数会被设置为0。这是因为L1正则化使用参数的绝对值作为正则化项,使得优化过程中更容易出现部分参数被精确地推至0的情况。这种稀疏性对于特征选择是有利的,因为它可以帮助模型忽略不重要的特征。
- L2正则化:倾向于使所有参数都尽可能小,但不是严格等于0。L2正则化通过参数的平方和来惩罚大的权重值,这导致参数值趋向于0但不会真正达到0。这种方式有助于控制模型复杂度,防止过拟合,但不会产生稀疏的参数矩阵。
其他区别
两者都能帮助减轻过拟合,但L1正则化通过减少模型中特征的数量来简化模型,而L2正则化则是通过减小参数的大小来降低模型复杂度。
如何选择
希望模型具有较好的解释性并且特征选择很重要,L1可能是更好的选择;如果关注的是模型的整体性能和泛化能力,L2通常更为适用。
代码演示
实现一个简单的线性回归模型,并使用梯度下降法进行参数优化。
损失函数均采用均方误差,计算公式如下:
MSE = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 y i 是第 i 个样本的真实值 y ^ i 是第 i 个样本的预测值 \text{MSE} = \frac{1}{n} \sum_{i=1}^{n} (y_i - \hat{y}_i)^2 \\ \\ y_i是第i个样本的真实值 \\ \hat{y}_i是第i个样本的预测值 \\ MSE=n1i=1∑n(yi−y^i)2yi是第i个样本的真实值y^i是第i个样本的预测值
L1正则化代码如下:
import numpy as np# 设置输出精度和随机种子
np.set_printoptions(precision=5, suppress=True)
np.random.seed(42)# 伪造测试数据
X = np.random.rand(100, 5)
# y = X\cdot(W) + b
y = np.dot(X, np.random.rand(5, 5)) + np.random.randn(100, 5) * 2# random init weights
W = np.random.randn(5, 5)
learning_rate = 0.05
lambd = 0.05for epoch in range(100000):y_pred = np.dot(X, W)# 使用均方误差损失函数 + L1正则化loss = np.mean((y_pred - y) ** 2) + lambd * np.sum(np.abs(W))# 反向求导dW = 2 * np.dot(X.T, (y_pred - y)) / len(X) + lambd * np.sign(W)W -= learning_rate * dWprint("L1正则化后的权重:")
print(W)
L2正则化代码如下:
import numpy as npnp.set_printoptions(precision=5, suppress=True)
np.random.seed(42)X = np.random.rand(100, 5)
y = np.dot(X, np.random.rand(5, 5)) + np.random.randn(100, 5) * 2W = np.random.randn(5, 5)
learning_rate = 0.05
lambd = 0.05for epoch in range(100000):y_pred = np.dot(X, W)loss = np.mean((y_pred - y) ** 2) + lambd * np.sum(W**2)dW = 2 * np.dot(X.T, (y_pred - y)) / len(X) + 2 * lambd * WW -= learning_rate * dWprint("L2正则化后的权重:")
print(W)
L1正则化后的权重:
[[ 0.74203 0.48284 0.48443 1.6181 0.86425]
[ 0.07272 0.42039 0.50347 1.51582 0.4436 ]
[ 0.20152 0.00107 1.10334 0.31734 0.58031]
[-0.00022 0.13223 0.5605 0.50442 -0.08625]
[ 0.90964 1.43715 0.53282 0.00218 0.44432]]
L2正则化后的权重:
[[ 0.62949 0.49969 0.5205 1.34822 0.79897]
[ 0.16748 0.46122 0.57207 1.26157 0.51506]
[ 0.26397 -0.00868 0.9287 0.51675 0.57909]
[ 0.12994 0.35091 0.56835 0.65079 -0.19285]
[ 0.72838 1.11006 0.56346 0.13049 0.52692]]
仔细观察可知,L1正则化后,权重向量中的某些元素几乎接近0,而L2正则化后,权重向量中的某些元素几乎不变
其他一些正则化技术
- dropout技术:随机失活部分神经元
- 早停:(early stopping)观察可视化训练的损失变化,及时停止模型的训练
- 数据增广:对数据进行一些变换,增加数据集合大小