【问题标题】:[Octave]Using fminunc is not always giving a consistent solution[Octave]使用 fminunc 并不总是给出一致的解决方案
【发布时间】:2016-10-23 04:15:28
【问题描述】:

我试图在方程中找到系数来模拟电机的阶跃响应,其形式为1-e^x。我用来建模的方程的形式是

a(1)*t^2 + a(2)*t^3 + a(3)*t^3 + ...

(来源于一篇用于求解电机参数的研究论文)

有时使用fminunc 来查找系数效果很好,我得到了一个很好的结果,它与训练数据匹配得很好。其他时候返回的系数是可怕的(比输出应该高得多,而且相差几个数量级)。当我开始使用高阶项时尤其会发生这种情况:使用任何使用 x^8 或更高级别(x^9x^10x^11 等)的模型总是会产生不好的结果。

由于它有时会起作用,我想不出为什么我的实现会出错。我试过fminunc,同时提供渐变,同时也没有提供渐变,但没有区别。我已经研究过使用其他函数来求解系数,例如polyfit,但在这种情况下,它必须具有从1 提升到最高阶项的项,但我使用的模型有它的2 的最低功耗。

这里是主要代码:

clear;

%Overall Constants
max_power = 7;

%Loads in data
%data = load('TestData.txt');
load testdata.mat

%Sets data into variables
indep_x = data(:,1); Y = data(:,2);

%number of data points
m = length(Y);

%X is a matrix with the independant variable
exps = [2:max_power];
X_prime = repmat(indep_x, 1, max_power-1); %Repeats columns of the indep var
X = bsxfun(@power, X_prime, exps);

%Initializes theta to rand vals
init_theta = rand(max_power-1,1);

%Sets up options for fminunc
options = optimset( 'MaxIter', 400, 'Algorithm', 'quasi-newton');

%fminunc minimizes the output of the cost function by changing the theta paramaeters
[theta, cost] = fminunc(@(t)(costFunction(t, X, Y)), init_theta, options)

%
Y_line = X * theta;

figure;
hold on; plot(indep_x, Y, 'or');
hold on; plot(indep_x, Y_line, 'bx');

这里是costFunction

function [J, Grad] = costFunction (theta, X, Y)
   %# of training examples

   m = length(Y);

    %Initialize Cost and Grad-Vector
    J = 0;
    Grad = zeros(size(theta));

    %Poduces an output based off the current values of theta
    model_output = X * theta;

    %Computes the squared error for each example then adds them to get the total error
    squared_error = (model_output - Y).^2;
    J = (1/(2*m)) * sum(squared_error);

    %Computes the gradients for each theta t
    for t = 1:size(theta, 1)
        Grad(t) = (1/m) * sum((model_output-Y) .* X(:, t));
    end

endfunction

任何帮助或建议将不胜感激。

【问题讨论】:

  • 将 t^n 用于更高和更高的幂并不是函数的良好 全局 基础,因此我希望当您尝试使用更高的幂时该方法会崩溃多项式。
  • 我会为您的近似响应使用不同的基础,如果您想使用多项式,切比雪夫多项式将是一个好的开始。
  • 高阶多项式很难处理:它们摆动很多。当我看到x^4 时,我已经很紧张了。从一个限制性更强的模型开始,如果可能的话,使用一个好的起点并对要估计的参数应用良好的界限(您需要一个求解器来处理这个界限)。

标签: matlab octave mathematical-optimization curve-fitting best-fit-curve


【解决方案1】:

尝试将正则化添加到您的 costFunction:

function [J, Grad] = costFunction (theta, X, Y, lambda)
    m = length(Y);

    %Initialize Cost and Grad-Vector
    J = 0;
    Grad = zeros(size(theta));

    %Poduces an output based off the current values of theta
    model_output = X * theta;

    %Computes the squared error for each example then adds them to get the total error
    squared_error = (model_output - Y).^2;
    J = (1/(2*m)) * sum(squared_error);
    % Regularization
    J = J + lambda*sum(theta(2:end).^2)/(2*m);


    %Computes the gradients for each theta t
    regularizator = lambda*theta/m;
    % overwrite 1st element i.e the one corresponding to theta zero
    regularizator(1) = 0;
    for t = 1:size(theta, 1)
        Grad(t) = (1/m) * sum((model_output-Y) .* X(:, t)) + regularizator(t);
    end

endfunction

正则化项lambda用于控制学习率。从 lambda=1 开始。 lambda 的值越大,学习的速度就越慢。如果您描述的行为仍然存在,请增加 lambda。如果 lambda 变高,您可能需要增加迭代次数。 您还可以考虑对数据进行规范化,以及一些用于初始化 theta 的启发式方法 - 将所有 theta 设置为 0.1 可能比随机的要好。如果不出意外,它将提供更好的从训练到训练的可重复性。

【讨论】:

  • 添加正则化确实有帮助。但在某些情况下,它仍然会失败。我打开了退出标志和输出。每当我得到结果时,它的退出代码为 1(梯度幅度小于容差)并且只运行 2/3 次迭代。我认为这可能预示着某些事情。
  • 正则采样和高阶多项式不能很好地发挥作用 - 尽管正则化可以提供帮助,但很难避免数值病态系统。插值可能与您尝试的问题不同,但它说明了问题的一部分:en.wikipedia.org/wiki/Lagrange_polynomial。我建议使用不同的采样程序(即,在尝试匹配函数时要更加小心)或使用不同的基函数集。
猜你喜欢
  • 2021-10-28
  • 1970-01-01
  • 2012-02-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多