看了神经网络的梯度下降(Gradient Descent)逼近的方法之后就写了一个拟合散点(y= kx+b)的程序,原理是使方差最小(对拟合直线来说这样的算法肯定不算是好算法)。
x=(1:10)';
y=[2;3;3;4;5;6;4;6;6;7];
拟合这样一组散点,并且将拟合结果和polyfit函数的结果进行对比。顺便画出了cost函数随迭代次数变化的曲线
x=(1:10)';
y=[2;3;3;4;5;6;4;6;6;7];
k=rand(1);
b=0; %初始化k,b
m=length(x);
learningrate=0.05;
costs=[];
for l=1:500
yhat=k*x+b;%相当于正向传播
cost=1/m*sum(1/2*(y-yhat).^2);
costs=[costs,cost];
dk=-1/m*x'*(y-yhat);
db=-1/m*sum(y-yhat);%求梯度
k=k-learningrate*dk;
b=b-learningrate*db;%更新参数
end
subplot(2,1,1);
scatter(x,y);
hold on;
plot(x,k*x+b);
p=polyfit(x,y,1);
plot(x,polyval(p,x));
subplot(2,1,2);
plot(costs);
迭代500次,步长0.05,得到k=0.4983,b=1.8571
polyfit拟合的结果是0.496969696969697 1.86666666666667
两条曲线直线画在一个坐标轴基本重合,看到cost函数也下降的很快。当迭代次数为1500时,k=0.496969731305184,b=1.866666427629106。
在三维坐标轴中将k,b,cost画出来能直观看见梯度下降的过程。循环中添加以下代码
axis([0,1.5,0,2,0,.6]);%固定坐标轴
scatter3(k,b,cost,'r','*');
hold on ;
drawnow;pause(0.02);