【问题标题】:gradient descent seems to fail梯度下降似乎失败了
【发布时间】:2012-05-15 19:11:48
【问题描述】:

我实现了一种梯度下降算法来最小化成本函数,以获得用于确定图像是否具有良好质量的假设。我在八度做到了这一点。这个想法是基于 Andrew Ng 的 machine learning class 算法

因此,我有 880 个值“y”,其中包含从 0.5 到 ~12 的值。我在“X”中有 50 到 300 的 880 个值,应该可以预测图像的质量。

遗憾的是,该算法似乎失败了,经过一些迭代后,theta 的值非常小,以至于 theta0 和 theta1 变为“NaN”。而且我的线性回归曲线有奇怪的值...

这里是梯度下降算法的代码: (theta = zeros(2, 1);, alpha= 0.01, 迭代次数=1500)

function [theta, J_history] = gradientDescent(X, y, theta, alpha, num_iters)

m = length(y); % number of training examples
J_history = zeros(num_iters, 1);

for iter = 1:num_iters


    tmp_j1=0;
for i=1:m, 
    tmp_j1 = tmp_j1+ ((theta (1,1) + theta (2,1)*X(i,2)) - y(i));
end

    tmp_j2=0;
for i=1:m, 
    tmp_j2 = tmp_j2+ (((theta (1,1) + theta (2,1)*X(i,2)) - y(i)) *X(i,2)); 
end

    tmp1= theta(1,1) - (alpha *  ((1/m) * tmp_j1))  
    tmp2= theta(2,1) - (alpha *  ((1/m) * tmp_j2))  

    theta(1,1)=tmp1
    theta(2,1)=tmp2

    % ============================================================

    % Save the cost J in every iteration    
    J_history(iter) = computeCost(X, y, theta);
end
end

这里是代价函数的计算:

function J = computeCost(X, y, theta)   %

m = length(y); % number of training examples
J = 0;
tmp=0;
for i=1:m, 
    tmp = tmp+ (theta (1,1) + theta (2,1)*X(i,2) - y(i))^2; %differenzberechnung
end
J= (1/(2*m)) * tmp
end

【问题讨论】:

标签: machine-learning octave gradient-descent


【解决方案1】:

如果您想知道如何将看似复杂的for 循环矢量化 并压缩为单行表达式,请继续阅读。向量化形式为:

theta = theta - (alpha/m) * (X' * (X * theta - y))

下面是我们如何使用梯度下降算法得到这个向量化表达式的详细解释:

这是微调θ值的梯度下降算法:

假设给定以下 X、y 和 θ 的值:

  • m = 训练示例数
  • n = 特征数 + 1

这里

  • m = 5(训练示例)
  • n = 4(特征+1)
  • X = m x n 矩阵
  • y = m x 1 向量矩阵
  • θ = n x 1 向量矩阵
  • xi 是第 ith 个训练示例
  • xj 是给定训练示例中的第 jth 个特征

进一步,

  • h(x) = ([X] * [θ])(我们的训练集的预测值的 m x 1 矩阵)
  • h(x)-y = ([X] * [θ] - [y])(我们预测中的 m x 1 错误矩阵)

机器学习的整个目标是最小化预测中的错误。 基于上述推论,我们的错误矩阵是m x 1 向量矩阵,如下所示:

要计算 θj 的新值,我们必须得到所有错误的总和(m 行)乘以训练的 jth 特征值设置X。即取E中的所有值,分别与对应训练样例的jth特征相乘,再相加。这将帮助我们获得 θj 的新值(希望是更好的)。对所有 j 或特征数量重复此过程。矩阵形式可以写成:

这可以简化为:

  • [E]' x [X] 会给我们一个行向量矩阵,因为 E' 是 1 x m 矩阵,X 是 m x n 矩阵。但是我们有兴趣得到一个列矩阵,因此我们转置了结果矩阵。

更简洁,可以写成:

由于(A * B)' = (B' * A')A'' = A,我们也可以把上面写成

这是我们开始时的原始表达式:

theta = theta - (alpha/m) * (X' * (X * theta - y))

【讨论】:

  • 这非常有帮助 - 矩阵数学的冗长对我来说完全不同。
【解决方案2】:

我对 theta 事物进行了矢量化... 可能可以帮助某人

theta = theta - (alpha/m *  (X * theta-y)' * X)';

【讨论】:

  • 这个是正确答案。另一种写法:theta = theta - alpha / m * (X' * (X * theta - y));尽可能使用vectoriaztion。
  • 啊太棒了,我知道必须有办法,但我无法在纸上正确计算;)
  • 对于那些复制和粘贴:这是正确的更新,仅适用于 linear 激活函数,不适用于 sigmoid 和所有其他东西。
  • 为什么不是这样:theta = theta - (alpha/m) * sum(((X * theta) - y)' * X);?梯度下降方程包含一个求和。
  • 您只想对每个 theta 的值求和,而不是所有的 theta 结果。 X' * (x * theta -y) 需要以 1X2 向量结尾。使用 sum 函数会产生一个 1X1 向量,这会破坏矩阵代数。
【解决方案3】:

我认为你的computeCost 函数是错误的。 我去年参加了 NG 的课程,我有以下实现(矢量化):

m = length(y);
J = 0;
predictions = X * theta;
sqrErrors = (predictions-y).^2;

J = 1/(2*m) * sum(sqrErrors);

其余的实现对我来说似乎很好,尽管您也可以将它们矢量化。

theta_1 = theta(1) - alpha * (1/m) * sum((X*theta-y).*X(:,1));
theta_2 = theta(2) - alpha * (1/m) * sum((X*theta-y).*X(:,2));

之后,您将临时 theta(此处称为 theta_1 和 theta_2)正确设置回“真实”theta。

一般来说,向量化比循环更有用,阅读和调试也不那么烦人。

【讨论】:

  • 谢谢 ;)(我去年也参加了该课程,并想针对当前问题制定解决方案;),所以您的答案应该没问题 ;))
  • 顺便说一句,也许我忘记了,但第一个不应该吗? theta_1 = theta(1) - alpha * (1/m) * sum(X*theta - y)
  • 谢谢,我使用循环而不是矢量化并且遇到了同样的问题,真是救命啊!同意看起来更聪明
  • 并且矢量化形式也可以跨多个功能进行扩展
【解决方案4】:

如果您可以使用最小二乘成本函数,那么您可以尝试使用正规方程而不是梯度下降。它更简单——只有一行——而且计算速度更快。

下面是正规方程: http://mathworld.wolfram.com/NormalEquation.html

八度音阶形式:

theta = (pinv(X' * X )) * X' * y

这里有一个解释如何使用正规方程的教程:http://www.lauradhamilton.com/tutorial-linear-regression-with-octave

【讨论】:

  • 问题是关于梯度下降。也可以使用正规方程。
【解决方案5】:

虽然不像矢量化版本那样可扩展,但基于循环的梯度下降计算应该会产生相同的结果。在上面的示例中,梯度下降最有可能无法计算出正确的 theta 的情况是 alpha 的值。

使用一组经过验证的成本和梯度下降函数以及一组与问题中描述的数据相似的数据,如果alpha = 0.01,则在几次迭代后,theta 最终会得到 NaN 值。但是,当设置为 alpha = 0.000001 时,梯度下降会按预期工作,即使经过 100 次迭代。

【讨论】:

    【解决方案6】:

    这里只使用向量是在 Mathematica 中使用梯度下降的 LR 的紧凑实现:

    Theta = {0, 0}
    alpha = 0.0001;
    iteration = 1500;
    Jhist = Table[0, {i, iteration}];
    Table[  
      Theta = Theta - 
      alpha * Dot[Transpose[X], (Dot[X, Theta] - Y)]/m; 
      Jhist[[k]] = 
      Total[ (Dot[X, Theta] - Y[[All]])^2]/(2*m); Theta, {k, iteration}]
    

    注意:当然假设 X 是一个 n * 2 矩阵,其中 X[[,1]] 只包含 1s'

    【讨论】:

      【解决方案7】:

      这应该可行:-

      theta(1,1) = theta(1,1) - (alpha*(1/m))*((X*theta - y)'* X(:,1) ); 
      
      theta(2,1) = theta(2,1) - (alpha*(1/m))*((X*theta - y)'* X(:,2) ); 
      

      【讨论】:

        【解决方案8】:

        这样更干净,而且矢量化了

        predictions = X * theta;
        errorsVector = predictions - y;
        theta = theta - (alpha/m) * (X' * errorsVector);
        

        【讨论】:

          【解决方案9】:

          如果您还记得梯度下降形式机器学习课程的第一个 Pdf 文件,您会注意学习率。这是来自上述pdf的注释。

          实现说明:如果你的学习率太大,J(theta) 可以 边缘和blow up', resulting in values which are too large for computer calculations. In these situations, Octave/MATLAB will tend to return NaNs. NaN stands fornot a number' 并且通常是由 unened 涉及-infinity 和+infinity 的操作。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-06-13
            • 2018-09-17
            • 1970-01-01
            • 1970-01-01
            • 2016-09-25
            • 2018-12-22
            • 2012-08-17
            • 2021-12-18
            相关资源
            最近更新 更多