我有多个数据集,每个数据集我都想拟合一个高斯过程回归模型。使用fitrgp
选择的默认超参数在主观上似乎产生了不太理想的模型。启用超参数优化通常会带来显著的改进,但偶尔会产生极端的过拟合值,并且这是一个计算密集的过程,实际上禁止了对每个模型进行优化。
由于fitrgp
只是简单地包装了bayesopt
来进行其超参数优化,是否可以直接调用bayesopt
来最小化多个模型的损失总和(例如,平均值),而不是一次一个模型的损失?
例如,如果每个数据集都包含在一个表格的单元数组tbls
中,我希望找到一个单一的sigma
值,可以在对每个表调用fitrgp
时使用:
gprMdls = cellfun(@(tbl) {fitrgp(tbl,'ResponseVarName', 'Sigma',sigma)}, tbls);
当numel(tbls) == 1
时,这个过程相当于:
gprMdl = fitrgp(tbls{1},'ResponseVarName', 'OptimizeHyperparameters','auto');sigma = gprMdl.Sigma;
但这种实现无法自然扩展到为多个模型优化单一的Sigma值的结果。
回答:
最后,我通过直接干预内置的优化例程实现了这一点。
通过在bayesopt
的开始处设置断点(通过edit bayesopt
),并使用单个输入数据集调用fitrgp
,我能够从函数调用堆栈中确定bayesopt
使用的目标函数是通过调用classreg.learning.paramoptim.createObjFcn
构建的。我还捕获并存储了bayesopt
的其余输入参数,以确保我的函数调用与fitrgp
构建的完全相同。
在classreg.learning.paramoptim.createObjFcn
的开始处设置断点,并重新调用fitrgp
,我能够捕获并存储此函数的输入参数,这样我就可以为不同的预测器表创建目标函数。
对于我的表格单元数组tbls
,以及在捕获的createObjFcn
作用域中命名的所有其他变量保持不变:
objFcns = cell(size(tbls));for ii = 1:numel(tbls) objFcn{ii} = classreg.learning.paramoptim.createObjFcn( ... BOInfo, FitFunctionArgs, tbls{ii}, Response, ... ValidationMethod, ValidationVal, Repartition, Verbose);end
然后可以通过取每个数据集的目标函数的平均值来构建一个总体目标函数:
objFcn = @(varargin) mean(cellfun(@(f) f(varargin{:}),objFcns));
然后我能够使用这个objFcn
以及从原始调用中捕获的其余参数调用bayesopt
。这产生了一组所需的超参数,它们似乎对所有数据集都表现良好。