CORE CONCEPT -----Regularization

博客介绍了机器学习中正则化的相关内容。正则化旨在避免模型过度拟合,通过在成本函数中增加额外项惩罚复杂模型。还介绍了常见的正则化方法,如岭回归和套索回归,分别适用于不同场景,帮助我们更好地处理数据建模中的过度拟合问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Regularization

Motivation

请考虑以下情形。 你正在做一个花生酱三明治,并试图调整成分,使其具有最好的味道。 您可以在决策过程中考虑面包类型,花生酱类型或花生酱与面包比例。 但是你会考虑其他因素,比如房间里的温暖程度,早餐吃的东西,或者穿着什么颜色的袜子? 你可能不会因为这些东西对三明治的味道没有那么大的影响。 对于最终使用的任何配方,您将更多地关注前几个功能,并避免过多关注其他配方。 这是正规化的基本思想。

Overview

在之前的模块中,我们已经看到在一些样本集上训练的预测模型,并根据它们与测试集的接近程度进行评分。 我们显然希望我们的模型能够做出准确的预测,但它们是否过于准确? 当我们查看一组数据时,有两个主要组成部分:基础模式和噪声。 我们只想匹配模式而不是噪音。 考虑下面代表二次数据的数字。 图1使用线性模型来近似数据。 图2使用二次模型来近似数据。 图3使用高次多项式模型来近似数据。

code:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are using a simple linear model here
model = Pipeline([('poly', PolynomialFeatures(degree=1)), \
('linear', LinearRegression(fit_intercept=False))])

# Now we train on our data
model = model.fit(x, y)
# Now we pridict
y_predictions = model.predict(x)

# Plot data
sns.set_style("darkgrid")
plt.plot(x, y_predictions, color='black')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

code:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are using a quadratic model here (polynomial with degree 2)
model = Pipeline([('poly', PolynomialFeatures(degree=2)), \
('linear', LinearRegression(fit_intercept=False))])

# Now we train on our data
model = model.fit(x, y)
# Now we pridict
# The next two lines are used to model input for our prediction graph
x_plot = np.linspace(min(x)[0], max(x)[0], 100)
x_plot = x_plot[:, np.newaxis]
y_predictions = model.predict(x_plot)

# Plot data
sns.set_style("darkgrid")
plt.plot(x_plot, y_predictions, color='black')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

code:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are using a polynomial model here (polynomial with degree 10)
model = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('linear', LinearRegression(fit_intercept=False))])

# Now we train on our data
model = model.fit(x, y)
# Now we pridict
# The next two lines are used to model input for our prediction graph
x_plot = np.linspace(min(x)[0], max(x)[0], 100)
x_plot = x_plot[:, np.newaxis]
y_predictions = model.predict(x_plot)

# Plot data
sns.set_style("darkgrid")
plt.plot(x_plot, y_predictions, color='black')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

图1不适合数据,图2看起来非常适合数据,图3非常适合数据。 在上述所有模型中,第三个模型可能是测试集中最准确的模型。 但这不一定是件好事。 如果我们添加一些更多的测试点,我们可能会发现第三个模型在预测它们时不再准确,但第二个模型仍然相当不错。 这是因为第三个模型过度拟合。 过度拟合意味着它在拟合测试数据(包括噪声)方面做得非常好,但在推广新数据方面做得不好。 第二个模型非常适合数据,并不复杂,不会泛化。

正规化的目标是通过惩罚更复杂的模型来避免过度拟合。 正规化的一般形式包括在我们的成本函数中增加一个额外的术语。 因此,如果我们使用成本函数CF,则正则化可能会导致我们将其更改为CF +λ* R,其中R是我们权重的一些函数,而λ是调整参数。 结果是具有更高权重(更复杂)的模型受到更多惩罚。 调整参数基本上可以让我们调整正则化以获得更好的结果。 λ越高,权重对总成本的影响越小。

Methods

我们可以使用许多方法进行正则化。 下面我们将介绍一些比较常见的以及何时使用它们。

Ridge Regression

岭回归是一种正则化,其中函数R涉及对权重的平方求和。 等式1示出了修改的成本函数的示例。

等式1是正则化的示例,其中w表示我们的权重。 岭回归迫使权重接近零但永远不会使它们为零。 这意味着所有特征都将在我们的模型中表示,但过度拟合将被最小化。 当我们没有大量的功能并且只是想避免过度拟合时,岭回归是一个不错的选择。 图4给出了应用和不应用岭回归的模型的比较。

code:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are comparing a standard polynomial model against one with ridge
model = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('linear', LinearRegression(fit_intercept=False))])
regModel = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('ridge', Ridge(alpha=5.0))])

# Now we train on our data
model = model.fit(x, y)
regModel = regModel.fit(x, y)
# Now we pridict
# The next four lines are used to model input for our prediction graph
x_plot = np.linspace(min(x)[0], max(x)[0], 100)
x_plot = x_plot[:, np.newaxis]
y_plot = model.predict(x_plot)
yReg_plot = regModel.predict(x_plot)

# Plot data
sns.set_style("darkgrid")
plt.plot(x_plot, y_plot, color='black')
plt.plot(x_plot, yReg_plot, color='red')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

在图4中,黑线表示未应用岭回归的模型,红线表示应用岭回归的模型。 注意红线的平滑程度。 它可能会对未来的数据做得更好。

在包含的regularization_ridge.py文件中,添加岭回归的代码是:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Ridge
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are comparing a standard polynomial model against one with ridge
model = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('linear', LinearRegression(fit_intercept=False))])
regModel = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('ridge', Ridge(alpha=5.0))])

# Now we train on our data
model = model.fit(x, y)
regModel = regModel.fit(x, y)
# Now we pridict
# The next four lines are used to model input for our prediction graph
x_plot = np.linspace(min(x)[0], max(x)[0], 100)
x_plot = x_plot[:, np.newaxis]
y_plot = model.predict(x_plot)
yReg_plot = regModel.predict(x_plot)

# Plot data
sns.set_style("darkgrid")
plt.plot(x_plot, y_plot, color='black')
plt.plot(x_plot, yReg_plot, color='red')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

添加Ridge回归就像在Pipeline调用中添加一个额外的参数一样简单。 这里,参数alpha代表我们的调整变量。 有关scikit-learn中的岭回归的更多信息,请参阅此处here

Lasso Regression

套索回归是一种正则化,其中函数R涉及对权重的绝对值求和。 公式2显示了修改后的成本函数的示例。

等式2是正则化的示例,其中w表示我们的权重。 请注意类似岭回归和套索回归的相似之处。 唯一明显的区别是权重的平方。 这恰好会对他们的工作产生重大影响。 与岭回归不同,套索回归可以强制权重为零。 这意味着我们生成的模型甚至可能不考虑某些功能! 在这种情况下,我们有一百万个功能,其中只有少量很重要,这是一个非常有用的结果。 套索回归让我们可以避免过度拟合,并专注于我们所有功能的一小部分。 在最初的情景中,我们最终会忽略那些对我们的三明治饮食体验影响不大的因素。 图5给出了应用和不应用套索回归的模型的比较。

code:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Lasso
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are comparing a standard polynomial model against one with lasso
model = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('linear', LinearRegression(fit_intercept=False))])
regModel = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('lasso', Lasso(alpha=5, max_iter=1000000))])

# Now we train on our data
model = model.fit(x, y)
regModel = regModel.fit(x, y)
# Now we pridict
x_plot = np.linspace(min(x)[0], max(x)[0], 100)
x_plot = x_plot[:, np.newaxis]
y_plot = model.predict(x_plot)
yReg_plot = regModel.predict(x_plot)

# Plot data
sns.set_style("darkgrid")
plt.plot(x_plot, y_plot, color='black')
plt.plot(x_plot, yReg_plot, color='red')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

在上图中,黑线表示未应用Lasso回归的模型,红线表示应用了Lasso回归的模型。 红线比黑线更平滑。 Lasso回归应用于10度的模型,但结果看起来它的程度要低得多! 对于未来的数据,Lasso模型可能会做得更好。

在包含的regularization_lasso.py文件中,添加Lasso回归的代码是:

import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.preprocessing import PolynomialFeatures
from sklearn.datasets import make_regression
from sklearn.linear_model import LinearRegression, Lasso
from sklearn.pipeline import Pipeline
import numpy as np

# Create a data set for analysis
x, y = make_regression(n_samples=100, n_features = 1, noise=15, random_state=0)
y = y ** 2

# Pipeline lets us set the steps for our modeling
# We are comparing a standard polynomial model against one with lasso
model = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('linear', LinearRegression(fit_intercept=False))])
regModel = Pipeline([('poly', PolynomialFeatures(degree=10)), \
('lasso', Lasso(alpha=5, max_iter=1000000))])

# Now we train on our data
model = model.fit(x, y)
regModel = regModel.fit(x, y)
# Now we pridict
x_plot = np.linspace(min(x)[0], max(x)[0], 100)
x_plot = x_plot[:, np.newaxis]
y_plot = model.predict(x_plot)
yReg_plot = regModel.predict(x_plot)

# Plot data
sns.set_style("darkgrid")
plt.plot(x_plot, y_plot, color='black')
plt.plot(x_plot, yReg_plot, color='red')
plt.scatter(x, y, marker='o')
plt.xticks(())
plt.yticks(())
plt.tight_layout()
plt.show()

添加Lasso回归就像添加Ridge回归一样简单。 这里,参数alpha表示我们的调优变量,max_iter表示要运行的最大迭代次数。 有关scikit-learn中的Lasso回归的更多信息,请参阅此处here

Summary

在本单元中,我们了解了正规化。 通过正规化,我们找到了避免过度拟合数据的好方法。 这是建模中常见但重要的问题,因此最好知道如何调解它。 我们还研究了一些我们可以在不同情况下使用的正则化方法。 有了这个,我们已经充分了解了机器学习的核心概念,以进入我们的下一个主题 - 监督学习。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

### 基于正则化的持续学习方法 基于正则化的持续学习(Regularization-Based Continual Learning)是一种通过约束模型参数的变化来缓解灾难性遗忘的方法。这种方法的核心思想是在学习新任务的同时,保护旧任务的知识不被覆盖或破坏。具体来说,这些方法通常会引入额外的损失项到目标函数中,该损失项用于衡量当前模型参数相对于之前任务最优解的距离。 #### Elastic Weight Consolidation (EWC) Elastic Weight Consolidation 是一种经典的基于正则化的持续学习方法[^1]。它假设某些神经网络权重对于先前任务的表现至关重要,因此应该受到更大的保护。为了实现这一点,EWC 使用 Fisher Information Matrix 来估计每个权重的重要性,并将其纳入优化过程中: \[ L_{\text{total}} = L_{\text{task}} + \sum_i \frac{\lambda}{2} F_i (\theta_i - \theta_i^*)^2 \] 其中 \(L_{\text{task}}\) 表示当前任务的目标函数,\(F_i\) 是第 i 个权重对应的 Fisher Information,\(\theta_i^*\) 是前一任务结束时的权重值,而 \(\lambda\) 控制着正则化强度。 #### Synaptic Intelligence (SI) Synaptic Intelligence 提供了一种替代 EWC 的方式来计算权重重要性[^4]。与 EWC 不同的是,SI 并不需要显式地估算 Fisher Information,而是利用路径积分的思想动态跟踪每轮迭代期间权重变化的影响程度。其最终形式如下所示: \[ L_{\text{total}} = L_{\text{task}} + \sum_i w_i |\Delta \theta_i| \] 这里 \(w_i\) 反映了历史累积下来关于某个特定连接改变所造成的性能影响大小。 #### Online EWC 和其他变体 除了标准版之外还有多种改进版本如在线弹性权值凝聚法(Online EWC),它可以适应更复杂的场景,在线设置下无需存储所有以前的任务数据即可工作良好。此外还有一些混合策略比如联合使用经验重放机制进一步提升效果等等。 ```python import torch from torch import nn, optim class EWCLoss(nn.Module): def __init__(self, model_params, fisher_matrix, prior_model_params, lambda_reg=0.1): super(EWCLoss, self).__init__() self.fisher_matrix = fisher_matrix self.prior_model_params = prior_model_params self.lambda_reg = lambda_reg def forward(self, current_model_params): ewc_loss = 0. for name in self.fisher_matrix.keys(): param_diff = current_model_params[name] - self.prior_model_params[name] ewc_loss += torch.sum(self.fisher_matrix[name] * param_diff ** 2) return self.lambda_reg / 2 * ewc_loss # Example usage of the loss function within a training loop model = YourModel() optimizer = optim.SGD(model.parameters(), lr=0.01) ewc_criterion = EWCLoss(...) for epoch in range(num_epochs): for inputs, targets in dataloader: optimizer.zero_grad() outputs = model(inputs) task_loss = criterion(outputs, targets) ewc_penalty = ewc_criterion(dict(model.named_parameters())) total_loss = task_loss + ewc_penalty total_loss.backward() optimizer.step() ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

九妹123

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值