错误很简单.您的delta声明应该在第一个for循环中.每次累积训练样本和输出之间的加权差异时,都应该从头开始累积.
如果不这样做,你所做的就是累积上一次迭代的错误,这会将先前学习的theta版本的错误考虑在内,这是不正确的.你必须把它放在第一个for循环的开头.
此外,您似乎有一个无关的computeCost调用.我假设这在给定当前参数的每次迭代中计算成本函数,因此我将创建一个名为cost的新输出数组,在每次迭代时向您显示.我也将调用此函数并将其分配给此数组中的相应元素:
function [theta, costs] = gradientDescent(X, y, theta, alpha, iterations)
m = length(y);
costs = zeros(m,1); %// New
% delta=zeros(2,1); %// Remove
for iter =1:1:iterations
delta=zeros(2,1); %// Place here
for i=1:1:m
delta(1,1)= delta(1,1)+( X(i,:)*theta - y(i,1)) ;
delta(2,1)=delta(2,1)+ (( X(i,:)*theta - y(i,1))*X(i,2)) ;
end
theta= theta-( delta*(alpha/m) );
costs(iter) = computeCost(X,y,theta); %// New
end
end
关于适当矢量化的说明
FWIW,我不认为这个实现是完全矢量化的.您可以使用向量化操作消除第二个for循环.在我们这样做之前,让我介绍一些理论,以便我们在同一页面上.您在线性回归方面使用梯度下降.我们希望寻找最佳参数θ,它们是我们的线性回归系数,旨在最小化此成本函数:
m对应于我们可用的训练样本的数量,并且x ^ {i}对应于第i个训练示例. y ^ {i}对应于我们与第i个训练样本相关联的基础事实值. h是我们的假设,它给出如下:
请注意,在2D中的线性回归的上下文中,我们在要计算的θ中只有两个值 – 截距项和斜率.
我们可以最小化成本函数J以确定最佳回归系数,这些回归系数可以为我们提供最小化训练集误差的最佳预测.具体来说,从一些初始theta参数开始…通常是一个零向量,我们迭代迭代从1到我们认为合适的数量,并且在每次迭代时,我们通过这种关系更新我们的theta参数:
对于我们想要更新的每个参数,您需要确定与每个变量相关的成本函数的梯度,并评估当前状态为θ的那个.如果你使用微积分来解决这个问题,我们得到:
如果您不清楚这种推导是如何发生的,那么我建议您参考这个讨论它的好的数学堆栈交换帖子:
现在……我们如何将其应用于当前的问题?具体来说,您可以一次性计算三角洲的条目,非常容易地分析所有样本.我的意思是你可以这样做:
function [theta, costs] = gradientDescent(X, y, theta, alpha, iterations)
m = length(y);
costs = zeros(m,1);
for iter = 1 : iterations
delta1 = theta(1) - (alpha/m)*(sum((theta(1)*X(:,1) + theta(2)*X(:,2) - y).*X(:,1)));
delta2 = theta(2) - (alpha/m)*(sum((theta(1)*X(:,1) + theta(2)*X(:,2) - y).*X(:,2)));
theta = [delta1; delta2];
costs(iter) = computeCost(X,y,theta);
end
end
delta(1)和delta(2)上的操作可以完全在两个语句中进行矢量化.你正在做什么theta ^ {T} * X ^ {i}对于每个样本我来自1,2,…,m.您可以方便地将其放入单个sum语句中.
我们可以更进一步,用纯矩阵运算代替它.首先,你可以做的是使用矩阵乘法很快地为每个输入样本X ^ {i}计算theta ^ {T} * X ^ {i}.假设:
这里,X是我们的数据矩阵,其由对应于m个训练样本的m行和对应于n个特征的n列组成.类似地,theta是我们从梯度下降得到的权重向量,其中n 1个特征占截距项.
如果我们计算X * theta,我们得到:
正如您在此处所看到的,我们已经计算了每个样本的假设,并将每个样本放入一个向量中.该向量的每个元素都是第i个训练样本的假设.现在,回想一下梯度下降中每个参数的梯度项:
我们希望一次性实现学习向量中的所有参数,因此将其放入向量中可以为我们提供:
最后:
因此,我们知道y已经是长度为m的向量,因此我们可以通过以下方式非常紧凑地计算每次迭代时的梯度下降:
theta = theta - (alpha/m)*X'*(X*theta - y);
….所以你的代码现在只是:
function [theta, costs] = gradientDescent(X, y, theta, alpha, iterations)
m = length(y);
costs = zeros(m, 1);
for iter = 1 : iterations
theta = theta - (alpha/m)*X'*(X*theta - y);
costs(iter) = computeCost(X,y,theta);
end
end