文章目录
一、 简要介绍
- 因为要使用到modAL来做实验优化设计,目前正在学习不同的库包括modAL,openbox等,会挑选一些example来学习具体的细节,这里放一些学习过程中找的资料和补充,权当记录,供日后使用时快速查阅的资料。
- 首选的学习目标是modAL的example中的active_regression.py,相应的官方文档在Active regression
二、代码运行
2.1 前期准备
- 首先是导入库
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from modAL.models import ActiveLearner
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
- 其次是定义了一个查询策略,并生成带有噪声的回归任务数据,输入输出都是一维
# query strategy for regression
def GP_regression_std(regressor, X):
_, std = regressor.predict(X, return_std=True)
return np.argmax(std)
# generating the data
X = np.random.choice(np.linspace(0, 20, 10000), size=200, replace=False).reshape(-1, 1)
y = np.sin(X) + np.random.normal(scale=0.3, size=X.shape)
plt.scatter(X,y)
# assembling initial training set
n_initial = 5 #初始随机抽选5个数据用于初步训练
initial_idx = np.random.choice(range(len(X)), size=n_initial, replace=False)
X_initial, y_initial = X[initial_idx], y[initial_idx]
X_initial, y_initial
- 定义高斯过程中用到的内核,这里选择了RBF 内核 保证了模型对潜在数据结构的良好建模,使得在少量数据下依然能做出合理的预测,WhiteKernel 提供噪声建模,避免模型过拟合噪声数据,确保模型的预测精度。
# defining the kernel for the Gaussian process
kernel = RBF(length_scale=1.0, length_scale_bounds=(1e-2, 1e3)) \
+ WhiteKernel(noise_level=1, noise_level_bounds=(1e-10, 1e+1))
2.1.1 关于sklearn.gaussian_process.kernels的小展开
1. RBF Kernel (Radial Basis Function)
RBF
(Radial Basis Function),也称为高斯核,是一种常见的核函数,适用于平滑、连续变化的函数。其公式为:
[
k(x_i, x_j) = \exp\left(-\frac{||x_i - x_j||2}{2l2}\right)
]
其中,( l ) 是 length scale 参数,控制核函数的影响范围。较大的 ( l ) 值表示核函数的影响范围较大(变化平缓),而较小的 ( l ) 值表示核函数的影响范围较小(变化更敏感)。
length_scale_bounds
是这个参数的上下界,用于在优化过程中调整 ( l ) 值的大小。通过将length_scale_bounds=(1e-2, 1e3)
设置为较宽的范围,可以在训练过程中灵活调整核函数的平滑度。
作用:RBF 核具有平滑、连续的特性,因此适用于大多数非线性回归问题。在主动学习中,RBF 核可以用来很好地捕捉未知数据空间中潜在的平滑变化。
2. WhiteKernel
WhiteKernel
用于建模观测噪声,描述了每个点独立、无关的噪声影响。其公式为:
[
k(x_i, x_j) = \sigma_n^2 \cdot \delta(x_i, x_j)
]
其中,( \sigma_n^2 ) 是噪声强度,( \delta(x_i, x_j) ) 是 Kronecker delta 函数,表示当 ( x_i ) 和 ( x_j ) 相同时取 1,不同时取 0。
noise_level
表示噪声的初始值,noise_level_bounds
控制噪声水平的上下界,用于模型训练过程中自动调整噪声大小。
作用:WhiteKernel 通常与其他核函数组合使用,主要用于捕捉数据中的观测噪声。这对于高噪声数据特别有用,因为它能更好地拟合噪声较大的真实观测值。
3. 组合内核的原理
将 RBF
和 WhiteKernel
组合起来,创建了一个既能捕捉平滑变化(通过 RBF),又能处理噪声(通过 WhiteKernel)的模型。这种组合能够适应更复杂的情况,既能拟合平滑的目标函数,又能处理可能的测量噪声。公式上,这种组合内核可以表示为:
[
k(x_i, x_j) = \exp\left(-\frac{||x_i - x_j||2}{2l2}\right) + \sigma_n^2 \cdot \delta(x_i, x_j)
]
- RBF 内核 负责处理平滑的函数关系。
- WhiteKernel 处理独立噪声,避免模型过拟合。
4. 在主动学习中的优势
在主动学习中,高斯过程(GP)用来构建模型的不确定性估计,进而指导查询策略选择下一个最有价值的点。而 RBF 核的平滑特性和 WhiteKernel 的噪声处理能力,能够使 GP 模型在探索新点时更加准确地估计目标函数及其不确定性,从而提高主动学习的效率。
主动学习的好处:
- RBF 内核 保证了模型对潜在数据结构的良好建模,使得在少量数据下依然能做出合理的预测。
- WhiteKernel 提供噪声建模,避免模型过拟合噪声数据,确保模型的预测精度。
5. 其他核函数的特点
sklearn.gaussian_process.kernels
中提供了其他多种核函数,可用于不同的任务。以下是一些常见的内核及其特点:
-
Matern Kernel:
[
k(x_i, x_j) = \frac{1}{\Gamma(\nu) 2^{\nu-1}} \left( \frac{\sqrt{2\nu} |x_i - x_j|}{l} \right)^\nu K_\nu \left( \frac{\sqrt{2\nu} |x_i - x_j|}{l} \right)
]
Matern 核是 RBF 核的推广,可以通过调整参数 ( \nu ) 控制核函数的平滑性。当 ( \nu = 0.5 ) 时,它与Absolute Exponential Kernel
类似;当 ( \nu \to \infty ) 时,它与 RBF 核等价。Matern 核在数据不太平滑时表现较好。 -
RationalQuadratic Kernel:
[
k(x_i, x_j) = \left(1 + \frac{|x_i - x_j|^2}{2\alpha l2}\right){-\alpha}
]
该核是 RBF 和多项式核的混合,适合在数据呈现多尺度变化的情况下使用。\alpha
控制了不同尺度下的影响范围。 -
DotProduct Kernel (Linear Kernel):
[
k(x_i, x_j) = x_i^\top x_j
]
线性核主要用于线性回归问题。当目标函数为线性时,使用线性核的高斯过程模型将更简单且高效。 -
Periodic Kernel:
[
k(x_i, x_j) = \exp\left(-\frac{2\sin^2(\pi |x_i - x_j| / p)}{l^2}\right)
]
用于周期性函数建模,适用于对周期性数据建模的情况,比如季节性变化。
6. 如何组合使用不同的核
在处理复杂问题时,可以组合不同的核来捕捉不同的特征。例如:
- 对于具有长短期变化的非线性函数,可以组合 RationalQuadratic 和 RBF。
- 如果数据有周期性,可以使用 Periodic Kernel 与 RBF 或 Matern 核结合,以捕捉周期性和趋势变化。
- 对于含噪声数据,可以像现在一样,将 WhiteKernel 添加到任何其他核中,以处理噪声。
- 接下来是利用上述的核和优化策略函数、以及初始数据、定义优化模型ActiveLearner
regressor = ActiveLearner(
estimator=GaussianProcessRegressor(kernel=kernel),
query_strategy=GP_regression_std,
X_training=X_initial.reshape(-1, 1), y_training=y_initial.reshape(-1, 1)
)
2.1.2 关于ActiveLearner的展开
modAL
库是一个用于主动学习的Python库,而ActiveLearner
是其中最重要的模型之一。下面详细解析一下以下代码的作用:
1. ActiveLearner
类
from modAL.models import ActiveLearner
ActiveLearner
是 modAL
中的一个主动学习模型,允许用户在训练过程中不断地通过查询策略选择新的数据点,从而逐步提高模型的性能。它的核心概念是,模型通过学习已知的训练数据,并根据某种策略选取下一批最有用的数据点,极大地减少所需的标注数据量。
2. ActiveLearner
初始化参数
regressor = ActiveLearner(
estimator=GaussianProcessRegressor(kernel=kernel),
query_strategy=GP_regression_std,
X_training=X_initial.reshape(-1, 1), y_training=y_initial.reshape(-1, 1)
)
参数解释:
-
estimator=GaussianProcessRegressor(kernel=kernel)
:estimator
是主动学习模型中使用的基础学习器(也叫作“估计器”),这里用的是GaussianProcessRegressor
,即高斯过程回归器。kernel=kernel
:这是回归器中使用的核函数,在之前的代码中定义了一个组合核函数(RBF
加上WhiteKernel
),该核函数决定了模型对数据的拟合方式(捕捉平滑变化、噪声处理等)。
-
query_strategy=GP_regression_std
:query_strategy
是查询策略,决定模型如何选择下一个要标记的点。GP_regression_std
代表使用高斯过程的不确定性(标准差)作为查询策略,即选择模型当前预测不确定性最大的点进行下一次查询。这样可以有效提升模型的性能,因为不确定性高的区域往往包含对模型改进最有帮助的数据。
-
X_training=X_initial.reshape(-1, 1)
:- 初始训练数据集的输入特征
X_initial
,使用.reshape(-1, 1)
将数据变为适合高斯过程的二维数组(即每个数据点有一个特征)。
- 初始训练数据集的输入特征
-
y_training=y_initial.reshape(-1, 1)
:- 初始训练数据的标签
y_initial
,同样通过.reshape(-1, 1)
转换为适合模型输入的形状。
- 初始训练数据的标签
3. ActiveLearner
的工作原理
ActiveLearner
的工作流程如下:
- 初始化:使用初始训练数据训练一个初始模型。
- 查询策略:通过
query_strategy
(这里是GP_regression_std
),主动学习模型会评估当前模型最不确定的区域,选择这些区域的数据点进行查询。 - 更新模型:一旦用户(或标记器)提供了新数据点的标签,模型会利用这些新数据更新自己,从而变得更准确。
- 重复:不断重复选择新数据点、查询标签、更新模型的过程,直到达到所需的精度。
4. modAL.models
中的其他模型
除了 ActiveLearner
,modAL.models
中还有其他几种重要的主动学习模型:
-
Committee
:- 该模型用于组合多个学习器来进行查询决策。即,一个“委员会”中的多个模型会对数据点进行投票,选择最具不确定性的点。
- 常见的查询策略是
max disagreement
,即选择模型预测分歧最大的点进行标注。这种方法适合多模型集成的场景。
-
CommitteeRegressor
:- 和
Committee
类似,但专门用于回归任务。多个回归模型组成的“委员会”一起预测数据点,并选择预测分歧最大的点进行标注。 - 这种方法适合用于需要多个模型共同决策、并且预测数值类型输出的场景。
- 和
-
BayesianOptimizer
:- 这是一个专门用于贝叶斯优化的模型。在需要优化某些参数的情况下,它使用贝叶斯方法选择下一个最优的实验点进行标注或查询。特别适用于实验设计等需要通过主动学习不断优化目标函数的任务。
- 它可以与高斯过程结合,寻找最优参数组合。
- 初步看一下展训练获得的估计器,因为是初始随机挑选的五个点,因此训练出来的高斯函数预测效果不好
# plotting the initial estimation
with plt.style.context('classic'):
plt.figure(figsize=(14, 7))
x = np.linspace(0, 20, 1000)
pred, std = regressor.predict(x.reshape(-1,1), return_std=True)
plt.plot(x, pred)
plt.fill_between(x, pred.reshape(-1, )-std, pred.reshape(-1, )+std, alpha=0.2)
plt.scatter(X, y, c='k')
plt.title('Initial estimation based on %d points' % n_initial)
2.2 迭代优化
- 开展10次查点循环,使用query 选择模型不确定性最高的数据点(上述设置的最大不确定度策略),再使用teach 用新标记的数据点更新模型。整个过程就是通过不断选择最有价值的数据点,让模型更快收敛和提高性能。
# active learning
n_queries = 10
for idx in range(n_queries):
query_idx, query_instance = regressor.query(X)
regressor.teach(X[query_idx].reshape(1, -1), y[query_idx].reshape(1, -1))
- 对更新了10次的模型进行可视化,查看模型的拟合情况
# plotting after active learning
with plt.style.context('classic'):
plt.figure(figsize=(14, 7))
x = np.linspace(0, 20, 1000)
pred, std = regressor.predict(x.reshape(-1,1), return_std=True)
plt.plot(x, pred)
plt.fill_between(x, pred.reshape(-1, )-std, pred.reshape(-1, )+std, alpha=0.2)
plt.scatter(X, y, c='k')
plt.title('Estimation after %d queries' % n_queries)
# plt.show()
- 后续继续运行10次,20次,30次的函数准确率可视化如下:
- 完整的代码如下:
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np
from modAL.models import ActiveLearner
from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, WhiteKernel
# query strategy for regression
def GP_regression_std(regressor, X):
_, std = regressor.predict(X, return_std=True)
return np.argmax(std)
# generating the data
X = np.random.choice(np.linspace(0, 20, 10000), size=200, replace=False).reshape(-1, 1)
y = np.sin(X) + np.random.normal(scale=0.3, size=X.shape)
plt.scatter(X,y)
# assembling initial training set
n_initial = 5
initial_idx = np.random.choice(range(len(X)), size=n_initial, replace=False)
X_initial, y_initial = X[initial_idx], y[initial_idx]
X_initial, y_initial
#RBF 内核 保证了模型对潜在数据结构的良好建模,使得在少量数据下依然能做出合理的预测。
#WhiteKernel 提供噪声建模,避免模型过拟合噪声数据,确保模型的预测精度。
# defining the kernel for the Gaussian process
kernel = RBF(length_scale=1.0, length_scale_bounds=(1e-2, 1e3)) \
+ WhiteKernel(noise_level=1, noise_level_bounds=(1e-10, 1e+1))
regressor = ActiveLearner(
estimator=GaussianProcessRegressor(kernel=kernel),
query_strategy=GP_regression_std,
X_training=X_initial.reshape(-1, 1), y_training=y_initial.reshape(-1, 1)
)
# plotting the initial estimation
with plt.style.context('classic'):
plt.figure(figsize=(14, 7))
x = np.linspace(0, 20, 1000)
pred, std = regressor.predict(x.reshape(-1,1), return_std=True)
plt.plot(x, pred)
plt.fill_between(x, pred.reshape(-1, )-std, pred.reshape(-1, )+std, alpha=0.2)
plt.scatter(X, y, c='k')
plt.title('Initial estimation based on %d points' % n_initial)
# active learning
n_queries = 10
for idx in range(n_queries):
query_idx, query_instance = regressor.query(X)
regressor.teach(X[query_idx].reshape(1, -1), y[query_idx].reshape(1, -1))
# plotting after active learning
with plt.style.context('classic'):
plt.figure(figsize=(14, 7))
x = np.linspace(0, 20, 1000)
pred, std = regressor.predict(x.reshape(-1,1), return_std=True)
plt.plot(x, pred)
plt.fill_between(x, pred.reshape(-1, )-std, pred.reshape(-1, )+std, alpha=0.2)
plt.scatter(X, y, c='k')
plt.title('Estimation after %d queries' % n_queries)
# plt.show()
标签:std,plt,python,reshape,模型,initial,modAL,RBF,regression
From: https://blog.csdn.net/lqwh4666/article/details/142943207