【问题标题】:Regularized logistic regression code in matlabmatlab中的正则化逻辑回归代码
【发布时间】:2013-11-18 09:51:42
【问题描述】:

我正在尝试正则化 LR,在 matlab 中使用以下公式很简单:

成本函数:

J(theta) = 1/m*sum((-y_i)*log(h(x_i)-(1-y_i)*log(1-h(x_i))))+(lambda/2*m)*sum(theta_j)

渐变:

∂J(theta)/∂theta_0 = [(1/m)*(sum((h(x_i)-y_i)*x_j)] if j=0

∂j(theta)/∂theta_n = [(1/m)*(sum((h(x_i)-y_i)*x_j)]+(lambda/m)*(theta_j) if j>1

这不是matlab代码,只是公式。

到目前为止,我已经这样做了:

function [J, grad] = costFunctionReg(theta, X, y, lambda)

J = 0;
grad = zeros(size(theta));

temp_theta = [];

%cost function

%get the regularization term

for jj = 2:length(theta)

    temp_theta(jj) = theta(jj)^2;
end

theta_reg = lambda/(2*m)*sum(temp_theta);

temp_sum =[];

%for the sum in the cost function

for ii =1:m

   temp_sum(ii) = -y(ii)*log(sigmoid(theta'*X(ii,:)'))-(1-y(ii))*log(1-sigmoid(theta'*X(ii,:)'));

end

tempo = sum(temp_sum);

J = (1/m)*tempo+theta_reg;

%regulatization
%theta 0

reg_theta0 = 0;

for jj=1:m
 reg_theta0(jj) = (sigmoid(theta'*X(m,:)') -y(jj))*X(jj,1)
end    

reg_theta0 = (1/m)*sum(reg_theta0)

grad_temp(1) = reg_theta0

%for the rest of thetas

reg_theta  = [];
thetas_sum = 0;

for ii=2:size(theta)
    for kk =1:m
        reg_theta(kk) = (sigmoid(theta'*X(m,:)') - y(kk))*X(kk,ii)
    end
    thetas_sum(ii) = (1/m)*sum(reg_theta)+(lambda/m)*theta(ii)
    reg_theta = []
end

for i=1:size(theta)

    if i == 1
        grad(i) = grad_temp(i)
    else
        grad(i) = thetas_sum(i)
    end
end
end

成本函数给出了正确的结果,但我不知道为什么梯度(一步)不是,成本给出的 J = 0.6931 是正确的,而梯度 grad = 0.3603 -0.1476 0.0320 是不正确的,成本从 2 开始,因为参数 theta(1) 不必正则化,有什么帮助吗?我猜代码有问题,但4天后我看不到它。谢谢

【问题讨论】:

    标签: matlab machine-learning logistic-regression regularized


    【解决方案1】:

    矢量化:

    function [J, grad] = costFunctionReg(theta, X, y, lambda)
    
    hx = sigmoid(X * theta);
    m = length(X);
    
    J = (sum(-y' * log(hx) - (1 - y')*log(1 - hx)) / m) + lambda * sum(theta(2:end).^2) / (2*m);
    grad =((hx - y)' * X / m)' + lambda .* theta .* [0; ones(length(theta)-1, 1)] ./ m ;
    
    end
    

    【讨论】:

    • 您能否解释一下在J 中添加正则化项+lambda * sum(theta(2:end).^2) / (2*m) 的意义是什么,因为我们正在传递initial_theta = zeros(size(X, 2), 1);,乘以该项时的值是0 那么,有什么意义呢,因为成本功能将保持不变...
    • @Inceptor361 theta 第一次调用costFunctionReg 时为0,但在第一次迭代后它们将被更改。
    • 只是指出 J = (sum(... 这里首先 sum 是多余的,因为它的参数已经有维度 {1x1},这只是一个数字。
    • 我认为在 [ ((hx - y)' * X / m)' + lambda .* theta .* [0; one(length(theta)-1, 1)] ./ m ] 运算符 .* 只需要在 theta 和 [0,ones(... )] 之间,否则,简单的 * 就足够了吗?
    • @FranckDernoncourt 仅供参考,有人有 asked a new question 关于这个答案。
    【解决方案2】:

    我使用了更多的变量,所以你可以清楚地看到什么来自正则公式,什么来自“增加的正则化成本”。此外,在 Matlab/Octave 中使用“矢量化”而不是循环是一个很好的做法。通过这样做,您可以保证得到更优化的解决方案。

     function [J, grad] = costFunctionReg(theta, X, y, lambda)
    
        %Hypotheses
        hx = sigmoid(X * theta);
    
        %%The cost without regularization
        J_partial = (-y' * log(hx) - (1 - y)' * log(1 - hx)) ./ m;
    
    
        %%Regularization Cost Added
        J_regularization = (lambda/(2*m)) * sum(theta(2:end).^2);
    
        %%Cost when we add regularization
        J = J_partial + J_regularization;
    
        %Grad without regularization
        grad_partial = (1/m) * (X' * (hx -y));
    
        %%Grad Cost Added
        grad_regularization = (lambda/m) .* theta(2:end);
    
        grad_regularization = [0; grad_regularization];
    
        grad = grad_partial + grad_regularization;
    

    【讨论】:

    • 嗯,不错的答案,虽然应该是regularization, :)
    • 你能说出你为什么要这么做grad_regularization = [0; grad_regularization];吗?
    【解决方案3】:

    终于搞定了,第四次重写后,这是正确的代码:

    function [J, grad] = costFunctionReg(theta, X, y, lambda)
    J = 0;
    grad = zeros(size(theta));
    
    temp_theta = [];
    
    for jj = 2:length(theta)
    
        temp_theta(jj) = theta(jj)^2;
    end
    
    theta_reg = lambda/(2*m)*sum(temp_theta);
    
    temp_sum =[];
    
    for ii =1:m
    
       temp_sum(ii) = -y(ii)*log(sigmoid(theta'*X(ii,:)'))-(1-y(ii))*log(1-sigmoid(theta'*X(ii,:)'));
    
    end
    
    tempo = sum(temp_sum);
    
    J = (1/m)*tempo+theta_reg;
    
    %regulatization
    %theta 0
    
    reg_theta0 = 0;
    
    for i=1:m
        reg_theta0(i) = ((sigmoid(theta'*X(i,:)'))-y(i))*X(i,1)
    end
    
    theta_temp(1) = (1/m)*sum(reg_theta0)
    
    grad(1) = theta_temp
    
    sum_thetas = []
    thetas_sum = []
    
    for j = 2:size(theta)
        for i = 1:m
    
            sum_thetas(i) = ((sigmoid(theta'*X(i,:)'))-y(i))*X(i,j)
        end
    
        thetas_sum(j) = (1/m)*sum(sum_thetas)+((lambda/m)*theta(j))
        sum_thetas = []
    end
    
    for z=2:size(theta)
        grad(z) = thetas_sum(z)
    end
    
    
    % =============================================================
    
    end
    

    如果它对任何人有帮助,或者任何人对我如何做得更好有任何帮助。 :)

    【讨论】:

    • 谢谢,你能解释一下吗? 1. 为什么我们在这里为成本 J 跳过 theta(1)? 2. 为什么我们忽略 grad(1) 的 lambda/m*theta?
    • 如果我通过查看代码 theta(1) 没有被跳过,而是单独计算,我没记错的话,我认为这更容易。第二个问题我不确定我想在那里完成什么。
    • 我相信 grad(1) 已从正则化中跳过,因为它对应于您要添加到数据中的 1s 列的权重
    【解决方案4】:

    这是一个消除循环的答案

    m = length(y); % number of training examples
    
    predictions = sigmoid(X*theta);
    reg_term = (lambda/(2*m)) * sum(theta(2:end).^2);
    calcErrors = -y.*log(predictions) - (1 -y).*log(1-predictions);
    J = (1/m)*sum(calcErrors)+reg_term;
    
    % prepend a 0 column to our reg_term matrix so we can use simple matrix addition
    reg_term = [0 (lambda*theta(2:end)/m)'];
    grad = sum(X.*(predictions - y)) / m + reg_term;
    

    【讨论】:

      猜你喜欢
      • 2013-03-15
      • 1970-01-01
      • 2020-10-11
      • 2012-03-11
      • 2016-12-15
      • 1970-01-01
      • 1970-01-01
      • 2018-04-25
      • 2021-11-10
      相关资源
      最近更新 更多