在多维优化中动态选择要最小化的变量
Dynamically choose variables to be minimized in multidimensional optimization
在 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
认为第三个变量不敏感,因为它在 objective 函数内部被覆盖,因此不会影响输出值。
将第三个值定义为单独的变量(即在 parameters
之外)不是一种选择,因为每次我选择要优化的不同变量时都需要大量的重新编码。
一定有更好的解决办法。有什么想法吗?
您可以使用一种优化方法,您可以在其中指定参数的下限和上限,然后将界限设置为彼此相等。
这样参数是固定的,你的优化器不会尝试改变它。
此方法假设您知道参数的值,但不想优化。如果更改此值,优化结果可能会发生变化。
我用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
虽然可以使用 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
在 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
认为第三个变量不敏感,因为它在 objective 函数内部被覆盖,因此不会影响输出值。
将第三个值定义为单独的变量(即在 parameters
之外)不是一种选择,因为每次我选择要优化的不同变量时都需要大量的重新编码。
一定有更好的解决办法。有什么想法吗?
您可以使用一种优化方法,您可以在其中指定参数的下限和上限,然后将界限设置为彼此相等。 这样参数是固定的,你的优化器不会尝试改变它。
此方法假设您知道参数的值,但不想优化。如果更改此值,优化结果可能会发生变化。
我用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
虽然可以使用 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