【问题标题】:Precision accuracy in MatlabMatlab 中的精度精度
【发布时间】:2015-09-25 17:11:35
【问题描述】:

我正在尝试实现一个Logistic Regression算法,部分Matlab代码如下。

for i = 1 : MAX_ITR
    % Calculate mu
    mu = 1.0 ./ (1.0 + exp(-(X * w)));

    % Calculate h to check for convergence
    h(i) = sum(-y .* log(mu) - (1 - y) .* log(1 - mu)) + (lambda / 2) * norm(w([2:end]))^2;

    % Calculate gradient and hessian.
    G = lambda .* w; 
    G(1) = 0;       % Set extra term for gradient to 0
    L = lambda .* eye(D + 1); 
    L(1) = 0;       % Set extra term for Hessian to 0
    grad = (X' * (mu - y)) + G;
    S = diag((mu .* (1 - mu)));
    H = (X' * S * X) + L;

    % Update w
    w = w - H\grad;
end

显然mu 的值不能为 1,因为指数不能为 0。但是,在某些值中,指数的计算结果非常小,例如 1.6629e-05。这会导致该实例的 mu 值非常接近 1,即 0.999983371689452。

我已经逐次运行代码迭代,前 4 次迭代很好,因为 mu 不包含任何这样的“接近 1”值。但是,第五次迭代确实如此,因此,我的h 得到了一个NaN,算法不会收敛。

我已经运行了digits 命令,它的值是32,所以我不知道是什么导致了这个问题。

预计到达时间: 在@rayryeng 的建议之后更新了代码: DX中的特征个数,m是训练样本个数X

   for i = 1 : MAX_ITR
        % Initialize arrays
        grad = zeros(D+1,1);
        h(i) = 0;
        H = zeros(D+1,D+1);

        for j = 1 : m
            % Calculate mu
            mu = sigmoid(X(j,:) * w);

            % Calculate h (to check for convergence)
            h(i) = h(i) - (1/m)*(y(j) * log(mu) + (1 - y(j)) * log(1 - mu)) + (lambda / (2 * m)) * norm(w(2:end))^2;

            % Calculate gradient and Hessian
            G = lambda * w; 
            G(1) = 0;       % Set extra term for gradient to 0
            L = lambda * eye(numFeatures + 1); 
            L(1) = 0;       % Set extra term for Hessian to 0
            grad = grad - (1/m) * ((X(j,:)' * (mu - y(j))) + G);
            S = diag((mu .* (1 - mu)));
            H = H - (1/m) * ((X(j,:)' * S * X(j,:)) + L);
        end
        %fprintf('h(%d) = %0.5f\n', i, h(i));

        % Update w
        w = w - H\grad;
    end

我不再收到NaN 错误,并且h 值似乎在几次迭代后收敛。

【问题讨论】:

  • 我假设w(1) 是偏置项....但是在计算 sigmoid 时,您又将它包含在 X*w 中?
  • 我猜NaN 是因为(1-y).*log(1-mu) 类似于0*inf。不能把mu的表达式写成log(1-mu)并化简,避免精度损失问题吗?
  • 您可以尝试使用log1p 处理较小的mu 值:... -(1-y).*log1p(-mu) ...。您还应该查看y 的变化情况。 digits 用于可变精度算术 - 如果您以标准双精度执行此操作,则无关紧要。
  • @rayryeng 是的,w(1) 是偏差项。我已经删除了。
  • @Rayne - 我稍后会调试你的代码,但与此同时,看看这个:dropbox.com/s/sitgpmu6oe2cfyt/ps1sol.pdf?dl=1 - 这是 Andrew Ng 从 2014 年秋季开始的 CS 229 课程的第一个问题分配,第 2-4 页显示了如何为 LR 实现牛顿法的代码。将其与您的实现进行比较,看看是否匹配。

标签: matlab precision logistic-regression


【解决方案1】:

在我的实现中,

  • X是输入数据m x n(一列1s被添加到 初始数据X = [ones(m, 1) X];)

  • y是输出数据。

  • theta 的初始值为 0

sigmoid函数定义如下:

function g = sigmoid(z)
    g = 1./(1+exp(-z));
end

代价函数定义如下:

function [J, grad] = costFunction(theta, X, y)
    m = length(y);
    J = (1/m)*sum(-y .* log(sigmoid(X*theta)) - (1-y) .* log(1-sigmoid(X*theta)));
    grad = (X'*(sigmoid(X*theta)-y))/m;
end

在主代码中,我使用fminunc 函数来寻找最优theta。

options = optimset('GradObj', 'on', 'MaxIter', 400);
[theta, cost] = fminunc(@(t)(costFunction(t, X, y)), initial_theta, options);

最后,它与您的实现不同,但找出问题的解决方案可能会很有用。

【讨论】:

  • 谢谢!是(1/m)因子归一化 J 和 grad 吗?我想知道为什么我的 h(你的 J)值这么大。
  • 是的,它是为了规范化,因为你 sum 然后你需要让它规范化。
  • @Rayne - 如果您查看您引用我的文档,它们也会通过1/m 标准化。
  • @NKN - 我也是 :)... 我在 3 年前服用了它... 最近又一次刷新了我的记忆。我喜欢机器学习......只是从来没有时间进入它。
  • 不错!我每天都在使用它。在机器人上!
猜你喜欢
  • 2011-07-30
  • 2021-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-06
  • 2016-12-09
相关资源
最近更新 更多