1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > 吴恩达机器学习 监督学习线性回归与梯度下降(MATLAB实现)

吴恩达机器学习 监督学习线性回归与梯度下降(MATLAB实现)

时间:2018-11-12 23:02:31

相关推荐

吴恩达机器学习 监督学习线性回归与梯度下降(MATLAB实现)

监督学习模型描述

学习算法通过训练集得到一个假设函数h,h接收输入可以得到一个输出。

列如:

已知房子大小与对应的价格,通过学习算法驯良可以得到一个假设函数 h h h:

h = θ 0 + θ 1 x h=\theta_0+\theta_1x h=θ0​+θ1​x

设x为房子大小, h h h所得到值即为房价。通过训练集的学习确定假设h的两个系数。

代价函数

对于我们的假设函数h,需要定义一个标准来表明假设所得值与真实值之间的误差,通常我们用平方误差来表明误差,这个我们记为代价函数 J J J

代价函数是所有样本误差的平均。

J ( θ 0 , θ 1 ) = 1 2 m ∑ i = 1 m ( h ( x i ) − y i ) 2 J(\theta_0,\theta_1)=\cfrac{1}{2m}\sum_{i=1}^m(h(x^i)-y^i)^2 J(θ0​,θ1​)=2m1​i=1∑m​(h(xi)−yi)2

综上,我们要找到一对系数 θ 0 , θ 1 \theta_0,\theta_1 θ0​,θ1​来使得代价函数 J J J最小

梯度下降(Bath梯度下降)

给定 θ 0 , θ 1 \theta_0,\theta_1 θ0​,θ1​初始值,一般都直接设为0更改 θ 0 , θ 1 \theta_0,\theta_1 θ0​,θ1​以减小 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0​,θ1​)

(注意:梯度下降可能会使得代价函数位于局部最低值,而不是最小值)

更改系数的方法是利用偏导数来进行。

重复直至收敛{θ j = θ j − α ∂ ∂ θ j J ( θ 0 , θ 1 ) \theta_j=\theta_j-\alpha\cfrac{\partial}{\partial\theta_j}J(\theta_0,\theta_1) θj​=θj​−α∂θj​∂​J(θ0​,θ1​)}

其中 θ j \theta_j θj​为各个系数,这个问题中的 j = 0 , 1 j=0,1 j=0,1, α \alpha α为学习率,控制梯度下降的速度,如果 α \alpha α过小,会导致迭代速度慢, α \alpha α过大会导致无法收敛,因为学习率太大,每次都会越过最低点。

如上图,横坐标相当是系数 θ 0 , θ 1 \theta_0,\theta_1 θ0​,θ1​的综合效应,纵坐标为代价函数 J ( θ 0 , θ 1 ) J(\theta_0,\theta_1) J(θ0​,θ1​)。当前为A点,原本应该会被下降到B点,可是由于学习率过大导致越过了B点到达了C点。

学习率适当不是说取0.5(刚开始时我选择了0.5)正常情况下为0.1,0.03,0.01,0.003,0.001…

数据拟合

我们先将老师提供的数据画出来

clear;clc;data=load('ex1data1.txt');size=data(:,1)';price=data(:,2)';figure(1);plot(size,price,'o');title('训练集');xlabel('房子大小');ylabel('房价')

通过拟合获取函数

clear;clc;%%%画出原始图像data=load('ex1data1.txt');size=data(:,1)';price=data(:,2)';figure(1);plot(size,price,'o');title('训练集');xlabel('房子大小');ylabel('房价')%%%拟合函数syms h J k0 k1 f0 f1;%定义变量h=k0+k1*size;%定义假设函数hJ=sum((h-price).^2)/(2*length(size));%定义代价函数Jf0=diff(J,k0);%求得代价函数对k0的偏导f1=diff(J,k1);%求得代价函数对k1的偏导%初始化k0,k1k0=0;k1=0;nowJ=subs(J);%记录当前代价lastJ=2*nowJ;%记录之前代价a=0.01;%学习率while (lastJ-nowJ)/lastJ>=0.00001%当代价变动不大时即为收敛,退出循环%获取新的k0,k1值temp0=vpa(subs(k0-a*f0));temp1=vpa(subs(k1-a*f1));k0=temp0;k1=temp1;lastJ=nowJ;nowJ=subs(J);%计算新的代价函数 enddisp([k0,k1])x=(5:0.1:25);y=k0+k1*x;hold on;plot(x,y,'-');

其中需要注意的是 θ 0 , θ 1 \theta_0,\theta_1 θ0​,θ1​要同时改变,所以先用temp变量记录变换后的值,等到计算结束之后一起更改系数。

特征缩放

在多变量线性回归中,由于不同特征之间的数量级差别可能很大(比如说房子的大小和房间数)会导致代价函数h收敛较慢,所以需要对特征进行处理后使用

方法一 除以最大值

所有特征都除以他的最大值,这个方法在特征数据都是同号的时候能够将所有数据都缩放到[0,1]之间,方便收敛。方法二 均值归一化

对于特征向量 x i x_i xi​,由于有 θ 0 \theta_0 θ0​的原因, x 0 x_0 x0​要永远为1,而对于其他特征:

x i = x i − μ i s i x_i=\frac{x_i-\mu_i}{s_i} xi​=si​xi​−μi​​

其中, μ i \mu_i μi​是特征向量 x i x_i xi​的平均值, s i s_i si​是 x i x_i xi​的范围, s i = m a x ( x i ) − m i n ( x i ) s_i=max(x_i)-min(x_i) si​=max(xi​)−min(xi​)

学习率的选择与代价函数收敛的判断

学习率的选择

虽然学习率可以选择0.01,0.003,0.001…但是他们之间的差距任然很大,就上述数据而言,我选择的学习率为0.012,通过观察代价函数值与迭代次数的关系,我们可以选择学习率。

clear;clc;%%data=load('ex1data1.txt');size=data(:,1)';price=data(:,2)';%%%拟合函数syms h J k0 k1 f0 f1;%定义变量h=k0+k1*size;%定义假设函数hJ=sum((h-price).^2)/(2*length(size));%定义代价函数Jf0=diff(J,k0);%求得代价函数对k0的偏导f1=diff(J,k1);%求得代价函数对k1的偏导%初始化k0,k1k0=0;k1=0;nowJ=subs(J);%记录当前代价lastJ=2*nowJ;%记录之前代价a=0.012;%学习率number=0;J_va=zeros(1,1500);while number~=1500%当代价变动不大时即为收敛,退出循环%获取新的k0,k1值temp0=vpa(subs(k0-a*f0));temp1=vpa(subs(k1-a*f1));k0=temp0;k1=temp1;lastJ=nowJ;nowJ=subs(J);%计算新的代价函数 number=number+1;J_va(number)=nowJ;endfigure(2);plot(1:number,J_va);xlabel('迭代次数')ylabel('代价')title('代价随迭代次数而减小')

可以看出曲线非常平滑,这是一个比较好的学习率的结果,如果我们选择一个稍微小一点的,比如0.01

这个曲线很畸形,所以这个学习率并不是太好

代价函数收敛判断

方法一 代价函数变化率小

我们可以记录前一次代价函数的值,然后当前代价进行比较,当变化率小于某个值时退出循环

nowJ=subs(J);lastJ=2*nowJ+1;while (lastJ-nowJ)/lastJ>=0.0001%当变化率小于0.0001时退出循环temp0=subs(k0-a*f0);temp1=subs(k1-a*f1);k0=temp0;k1=temp1;%更改记录的代价函数值lastJ=nowJ;nowJ=subs(J);end

这种方法容易实现,但是却不一定准确。收到学习率的影响,变化率可能会一直大于某个数,这个阙值很难找到。

方法二

在上述我们确定学习率的时候,我们得到了学习率和迭代次数的关系图:

我们可以从这个图中可以得到代价函数在迭代多少次之后趋于收敛。如上图我们可以得知,当迭代次数大于约1200次时,函数趋于收敛。我们可以事先确定好迭代次数来进行数据分析。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。