动态选择要在多维优化中最小化的变量

时间:2018-01-18 08:35:26

标签: matlab optimization fminsearch

在Matlab中,我知道如何编写多维优化。但我想动态选择要优化的变量子集。

假设我有一个三维变量向量,但我希望Matlab只优化第一个和第二个变量。如何实现这一目标?

x1 = 0:5; p_true = [1 2 3];             % True parameters
y1 = polyval(p_true, x1);               % True data
yn = y1 + sin(x1);                      % Noisy data

optimizationOptions = optimset('Display', 'final', 'TolFun', 1e-7, 'MaxFunEvals', 1e5,...
    'MaxIter', 1e4);
p0 = [0.5 0.75 1];                      % Initial guess
[p1, ~, ~, optOut] = fminsearch(@(parameters) objFunB(parameters, x1, yn), p0,...
    optimizationOptions);

plot(x1, yn, 'rx');
hold on
plot(x1, polyval([p1(1:2) 3], x1), 'b');

function rmse = objFunB(parameters, x1, yn)
    % Manipulate third component to be fixed; still, fminsearch tries adjusting it
    parameters(3) = 3;
    rmse = sum((yn - polyval(parameters, x1)).^2);
end

这个笨拙的解决方案欺骗fminsearch将第三个变量视为不敏感,因为它被覆盖在目标函数内部,因此不会影响输出值。

将第三个值定义为单独的变量(即,在parameters之外)不是一个选项,因为每次选择要优化的不同变量时,这都需要大量的重新编码。

必须有更好的解决方案。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

您可以使用优化方法,您可以在其中指定参数的下限和上限,并将设置的边界设置为彼此相等。 这样参数就固定了,优化器也不会尝试更改它。

此方法假设您不知道要优化的参数值。如果更改此值,优化结果可能会更改。

我用fmincon来解决你的例子:

x1 = 0:5; p_true = [1 2 3];             % True parameters
y1 = polyval(p_true, x1);               % True data
yn = y1 + sin(x1);                      % Noisy data


p0 = [0.5 0.75 1];                      % Initial guess

lb = [-Inf, -Inf, 3];
ub = [Inf, Inf, 3];

[x,~,~,optOut] = fmincon(@(parameters) objFunB(parameters, x1, yn),p0,[],[],[],[], lb, ub);

plot(x1, yn, 'rx');
hold on
plot(x1, polyval([p1(1:2) 3], x1), 'b');


function rmse = objFunB(parameters, x1, yn)
    rmse = sum((yn - polyval(parameters, x1)).^2);
end

答案 1 :(得分:0)

虽然可以使用lb == ub进行有界优化,但它将可用算法限制为接受约束的算法(并且还可能具有性能影响,我还没有测试)。 内置的fminsearch不支持有界多维优化(尽管fminsearchbnd确实如此)。

我从原始脚本的第4行开始提出以下解决方案。它使用逻辑索引。

all_parameters = p_true';
logOfPar2Opt = [1 0 1]';
p0 = nonzeros(all_parameters.*logOfPar2Opt); % Initial guess
optimizationOptions = optimset('Display', 'final', 'TolFun', 1e-7, 'MaxFunEvals', 1e5,...
    'MaxIter', 1e4);
[p1, fval, ~, optInfo] = fminsearch(@(parameters) objFunB(parameters, logOfPar2Opt,...
        all_parameters, x1, yn), p0, optimizationOptions);
indOfPar2Opt = find(logOfPar2Opt);
p_opt = all_parameters;
p_opt(indOfPar2Opt) = p1;

plot(x1, yn, 'rx');
hold on
plot(x1, polyval(p_opt, x1), 'b');

%% Separate objective functions
function rmse = objFunB(par2opt, logOfPar2Opt, all_parameters, x1, yn)
    indOfPar2Opt = find(logOfPar2Opt);
    prms = all_parameters;
    prms(indOfPar2Opt) = par2opt;
    rmse = sum((yn - polyval(prms, x1)).^2);
end