00:00
那现在就来创建一个新的notebook程序,来把我们梯度下降法这一部分代码实现一下。第一步大家会想到是不是还是引入依赖啊,应该没什么区别对不对,甚至大家都会想到是不是,第二步应该也是一样的吧,就是导入数据是不是也是接下来需要做的一件事情啊,所以我这个就快速过啊,没有什么难度的东西。好,那么导入数据,我不光导进来,也把它画一下吧,呃,既然是同样的这个程序嘛,Copy过来不费什么事儿。接下来损失函数大家想想一样不一样,最小二乘法和梯度下降法,我们损失函数是不是都可以用平方损失函数作为我们的损失函数啊啊,对,所以这步也一样,哎,有大家看到这个就太轻松了,大家写代码是不是最喜欢复制粘贴啊啊,这个快对吧,而且直接就能看到它到底长什么样,我这里边直接复制粘贴是因为我们都已经完整的实现过了,而且这个确实是一些预处理的一些一些工作,对不对?或者说一些损失函数的定义,这个是完全一样的。第三步这里定义算法拟合函数,大家说这个还能照抄吗?这肯定就不一样了,对不对?大家会发现我们现在的公式是得看这个。
01:24
那这里边我们会发现它是不是里边还得有,我要去做迭代时候才去算当前的这个梯度对不对,我要迭代是不是迭代这个公式里边首先得有一个初始点啊,这是不是比较重要的东西啊,然后是不是还得有一个阿尔法,这是这也是我必须提前定义好的一些东西啊,另外既然是迭代法,我们是不是往往还应该有一个参数。就是迭代到多少次之后我就完成了,不要无限循环下去对不对啊,所以这其实是我们预先应该想到的一些参数,这可以认为是我们这个模型里边的,大家会发现这不是具体模型里边,我们那个线性方程里边的参数阿尔法,还有我们的这个迭代次数啊,还有我们初始的这个,呃,初始点它的选取这些应该叫什么参数呢?应该叫超参数了,对不对,呃,属于模型的超参数了。所以我们接下来的第三。
02:27
是定义模型的超参数。好,那大家会想到我们需要定义哪些东西呢?是不是?诶,首先应该有那个步长阿尔法对不对啊,我们在这里定义一个叫做阿尔法的这样一个变量,我这里就直接给一个经验值吧,大家可以根据自己的需要可以去调,对吧,调一调看看效果怎么样,要不然大家可能不知道为什么我直接给这么一个值,大家看这个阿尔法我给的还是比较小的,对吧,0.0001,所以我们的这个步子是不是每一步其实迈的比较小啊?好,那接下来除了阿尔法之外,我们应该还有一个初始的W跟B,对不对,那初始值我们就叫initial吧。
03:20
Initial w给什么呢?这里边其实上午的时候也也有同学想到,也有同学问到了,一般情况我们这里可以去任意给,也可以,就是有一个随机生成的一个方式,对不对啊,我们可以找一,甚至可以找一堆初始点,随机生成一堆初始点,然后我们先带到损失函数里边,看看哪个最小,我们拿哪个作为真正的初始点来算对不对啊,这都是可以的,我们这里就简单去去给了啊,比方说我直接给一个零可不可以啊,那零也是可以的,对吧?因为如果这个线性拟和的话,都等于零,是不是就是Y等于零那条直线啊,这是不是也代表一条直线?哎,所以我们完全可以这么去去给啊,当然了,有以你手的W还有引手的B对不对?我们也给一个零吧,都给零,另外还有一个,呃,我们就叫number吧,Terration是迭代的意思,对不对,也就是迭代次数。
04:20
这个我给一个先少一点吧,给十次,大家看到我前面给的这个步子比较小,后面好像就是次数比较少,应该就可以,对不对啊,大家看等一下,看一下效果就知道,这是我们的第三步定义模型超超参数,然后接下来就应该到了我们核心的步骤了,对不对啊,就应该定义核心。梯度下降算法函数。我们这里边定义一个叫做叫做呃,梯度,下降梯度,大家还记得那个词叫gradient对吧,我们就叫grade吧,Gradeid下降decent DEC对不对?我们定义这样的一个函数,它应该有什么参数,大家想想。
05:12
梯度下降,也就是说我们用梯度下降算法去求解这个过程的时候,我们需要输入哪些东西呢?哎,首先大家会看到这个我们是不是得把点输进去啊,对吧?所有的数据点是不是也需要啊,那首先points是需要的,然后还需要什么,我们是不是既然是迭代,是不是一开始的这个初始值都得给进去啊,对,所以我们传进initial w和initial b。那这个阿尔法是不是也需要啊,其实就是前面我们定义好的超参数阿尔法,还有这个迭代次数是不是都应该传进去,哎,所以我们就统一都传进来阿尔法。
06:00
Number eer,好,那么在里边我们来定义一个,呃,大家会想到既然是迭代,那其实是W跟B,每一次都要去做更新,对不对啊,那每一次去做更新,一开始的时候,我们的初始值是不是就是定义好的initial手W和initial手B啊,先定义好啊,接下来我们就不是去改这个initial w initial手B了,是不是就改这个W跟B啊。好,这里定义好,然后这里我多定义一个东西啊,定义一个什么呢?因为我们在梯度下降的过程当中,是不是应该能够看到梯度下降,随着我们这个算法的迭代,不停的运行,它的损失函数是不是应该一点一点减减小,我们应该能够看到这个误差逐渐去降低,对不对,所以我这里边定义一个一个列表list,保存什么呢?保存所有的损失函数值,那它其实就是说呃,要去用来,用来什么呢?用来显示。
07:17
下降的过程对不对,对吧?好,那么一开始大家会想到这个就什么都不需要,我们定义一个空的例子是不是就可以了,好,先放在这里,接下来我们是不是就应该要开始真正迭代了,迭代的过程是不是应该是一个for循环,For I in range range什么呢?这是不是应该把迭代次数放进来啊,对,Number iter,接下来大家会想到你既然当前已经有一个W跟B,我们当时计算这个损失函数的时候,是不是有W跟B,还有point次直接就能算损失函数啊,哎,所以呢,我当前是不是就可以先算一下损失函数到底多少啊,每一次进来之后先算一下,所以。
08:05
那大家会想到我们算的话,掉这里的这个compute cost,最后得到一个数,这个数放在哪里呢?是不是要放到cost list里边啊,所以大家应该记得这个list有什么方法啊?它是不是后边有一个end的方法,大家讲过吗?之前呃,或者大家忘记的话,就重新用一下就就可以,就是相当于这个方法是干什么,是不是把里边的这个值直接追加到我们这个例子里边来啊,啊多了一个值就是对吧?所以这个没什么难度啊,好,当然它就是按照顺序一个一个来添加进去的,它的序号就是从零开始增长的,那么这里边里边应该是什么呢?就应该调用compute cost这个函数。里面又要传传参了,传什么WB,还有什么对points,把这些传进去,先把这个损失函数计算出来,写进去,然后接下来大家会想到我是不是相当于有一个迭代啊,对吧?这个迭代应该把这个W跟B是不是就做了一个更新啊?所以我把这一个每一步的迭代过程还是把它提取出来吧,所以提取出一个函数,那就是WB等于迭代,比方说我这个迭代就叫每一步吧,Step。
09:29
Grand descent,这是不是就代表每一步的梯度下降,所以我定义这样的一个函数,然后把什么东西要传进去呢?那还是我们这里边是不是大家会想到W跟B要不要先传进去?我既然要迭代,那现在本来的那个W跟B是不是也需要啊,啊,所以W跟B先要传进去,然后是不是还有阿尔法对阿尔法,另外还有什么大家想想。
10:03
其实这一步每一步的迭代用什么呢?是不是就是我们这里这个公式啊,是不是就是这个前面这个这里的西塔,其实系数嘛,就是我们的W跟B对不对,阿尔法也传进去了,那后边是不是要算的,其实就是后边这个梯度啊,算梯度需要什么东西呢?我们看一下下边这个一一元线性回归需要什么东西呢?是不是需要每一个X和Y啊。哎,所以那我们是不是还应该把points也传进去,好,这就是我们通过公式能够看到的一堆东西啊,好,那么调调用这个函数这个方法,我们直接就把W跟B更新了,对不对?更新完成之后,这一轮一轮更新,这个for循环做完之后,是不是就代表我们的迭代结束,就应该能够返回当前得到的最优的那个W跟B了,对吧?所以我们可以return return一个什么呢?我们return一个这样的一个list的吧,是不是要把WB要返回啊,另外还有一个东西,我们也要返回什么东西,是不是还有这个cos list啊啊,这些都是我们想要的东西。
11:24
所以我们把这三项作为结果返回。大家看这个过程还是很好理解的,对吧,其实就是你定义了这么一个,然后做一个迭代嘛,做一波迭代,关键的算法核心是不是还在这个函数里啊,所以我们接下来DeFine,一个叫step gra descent,呃,那么当然了,这里边大家会想到啊,这里边的W跟B其实就不应该是以你手了,对不对,我们这里边是不是应该叫当前的W跟B啊,所以我这里定义一个叫current w,大家看的会明显一点,Current b是不是这样两个值,还有阿尔法和points。
12:14
把这几项都传入,那我们要做的事情是什么呢?接下来是不是就是照着公式去做迭代,呃,这个在这个过程当中,大家会看到这个公式里边,那其实就是W相当于我们这里的西塔一,呃,B相当于这里的西塔零,对不对?那么W带进去的话,大家会看到是不是每一个都得有一个求和啊,一看到这个求和,那我们其实就知道肯定又是for循环,然后去一步一步要叠加了,对不对?所以我们先把它那个求和的那个变量先定义出来吧,比方说我们这里定义的这个这个和的这个形式,我们就叫做呃,Some some grade w吧,对吧,这是一个初始,是不是应该是零,Grade b,还有一个B初始是不是也是零啊?除了这两个求和之外啊,另外大家会想到我要求。
13:15
是不是所有的M各要求和啊,M是怎么算来着?个数对LS对point一次放进去就可以,好,这是我们一开始需要的东西,接下来是不是就是放循环啊,对每个点代入公式求和对吧?好呃,接下来是一个for循环,I in range这个是不是就是M了啊?遍历所有的点,那同样大家会想到遍历所有点的时候跟我们之前的招数是不是一样啊?哎,我们这里变利的时候,是不是都是一上来先这样啊,X跟Y是不是先拿到呃,当前的第个点对吧?所以我把X跟Y先拿到,接下来是不是就要计算梯度把它加到这个里边了,累加了对不对?照着公式去累加some grade w,加等于,大家想一下加等于什么呢?
14:20
是不是要按照我们这里边的这个内容来做加等于啊,那大家想一下,这里边是H西塔XHC塔X是什么?是不是本就是我们的这个函数表达式啊,所以这里边其实就应该是W乘以X再加上B对不对?哎,所以大家其实想象这里边就是W乘以X加上B,好,那我们这里边放一个括号吧啊,W,呃,W这里不叫W,叫current w对不对啊,大家注意一下啊,这是当然大家如果简写的话,也可以把这个定义成W乘以当前的X,是不是就叫X,然后再加上BB,叫current b,然后是不是要再减去当前的Y啊,呃,那Yi这里就是Y对不对?外面还要再做一件事情,是不是还要乘以X所有的这一项,然后最后做求和对不对?所以我们。
15:20
那里边的每一项就是这么算,是不是就是这这样的一个表达式啊,同样some grade b加等于哎,我们照着看它是不是就是前面这一项没有后面这个就完事了呀,所以我们是不是就照着把里边这部分拿出来就完事啊,不乘X就没事了,是不是就是这样,呃,就照着公式把它写下来就可以,那我们这样一个for循环结束之后是不是就拿到了。这个西格玛里边的这一项和这个西格玛里边这一项啊,然后是不是乘以一个M分之二,直接就是我们当前这个梯度啊啊,所以这个大家一看这个就是很简单对不对,还是比较简单的啊,所以呃,用公式求当前梯度,那梯度是一个向量,其实它就是西一西塔二或者说W跟B组成的这个向量对不对,那我们分别求出W跟B,其实就已经把它就是可以搞定了啊,那么当前的梯度。
16:32
Grade ww应该等于什么呢?是不是二除以M再乘以后边我们的这个some grade w啊,啊,当然就是前面大家会看到前面你如果直接把这个像数乘进去,是不是我们就省得下面这一步了啊,这样分开做可能大家会看的稍微清楚一点啊好,接下来grade b等于二除以M乘以some gradeb啊,这就已经求出了当前的梯度。
17:07
有了梯度,这是有了哪一项啊,是不是就是这两项都求出来了呀,前面我们这这两项都求出来了,对不对?接下来就是梯度下降,是不是用我们这个迭代公式来做计算,所以我们现在的迭代公式是原来的参数W和B是不是要减掉阿尔法乘以后边刚刚算出来的那个。刚刚算出来的那个梯度值啊,所以接下来啊,梯度下降,梯度下降,更新当前的W和B,那么大家看一下这个应该更新之后,那就叫updated w吧。Updated w应该等于什么呢?是不是应该是啊,当然大家也可以用那个,呃,Current w减等于对不对啊,我这里就专门给一个另外的名字叫做updated的W,它是不是就应该等于当前的W减掉,对阿尔法乘以什么?是不是乘以梯度啊,前面我们算出来的,其实前面我们算梯度的时候,就相当于是对它的求求出来的偏偏导对不对啊,所以这其实应该说是它的偏导啊,我们是不是直接乘以这个GRW啊,这是不是就是我们公式里面要的这一部分,前边这里算出来,然后这里用阿尔法乘以一减是不是就更新了,按照负梯度方向更新,那同样W这样更新,我们的B是不是也是这样去做更新啊,Current b减阿尔法。
18:50
乘以grade b啊,大家会看到这样就把这个更新的过程完成了,更新完成之后我们是不是return啊,Return updatedd w和updated b对吧?来把这个返回就可以了,好,这是我们的核心算法,就这样已经实现了,接下来当然了,还有一些后续,我们到第几步了,第五步了,接下来是不是应该做测试了,好,测试运行呃,梯度下降算法,呃,计算最优的W和B啊。
19:45
这里大家会会想到,就是其实就是我们直接调这个定义好的函数是不是就可以了,就是这里定义好的grade design这个函数对不对,它的返回是三项,那还有一个cos list,我们也把它拿出来吧,等于grade descent,它里边的参数是什么呢?
20:09
Points对吧?Points,然后initial w initial b,阿尔法,呃,Number,大家会发现这几个是不是就是我们我们定义的名字都一样对吧?超参数是不是都已经定义好了,所以我直接把它抄过来就可以了。好好当当,当然这里不应该有冒号对吧,这只是一条这个执行的一一行一行代码,那这个算完之后大家会想到是不是这个就直接可以print了呀,这三项都可以拿到了,好,我们直接抄着这边的来print就可以。首先把这个W跟B先打印出来,然后大家会想到还有一个cost list,这是一组对不对,一组cost list,那我这里边用一个什么东西来画呢?我我是不是可以画一个图啊,画一个它下降的曲线对不对?大家是不是可以想到用plt可以去画图,那么这里边我们要用plot去做画图,传进什么东西去呢?就用list。
21:15
诶,大家会记得之前我们不是得传一个X传一个Y吗?这里你只传一个,这算什么呢?这是一个list,那么它默认就会以它的。下标也就是我们的那个索引值对吧,坐为X,然后它本身的这个值作为Y来画一个图啊,所以这个是不是就是随着我们迭代次数,它的下边是不是相当于迭代次数啊啊012对不对,就是按照这个来去迭代的,所以就可以直接把这个图像画出来了,呃,当然我们这里边plt点售对吧,好执行一下好。哦,大家看一眼啊,我们现在算出来的WW跟B跟之前一样吗?好像不一样对吧,我们之前算出来这个W跟BW是1.322对不对,然后B是799对不对,呃,然后大家会看到这里它的这个。
22:13
这个算出来的W跟B其实是呃,不太一样的对吧?W是1.47,这W还接近B,是不是差别比较大啊,这个大家其实也可以理解,W代表的是什么?是不是对直线的斜率,这个不能偏差太大对不对?但是B代表的是在对在Y轴上的这个截距对不对?斜率这里稍微偏一点点,是不是这里的这个截距有可能差很大啊啊,所以这个还是有可能的。好,那么我们呃,那大家可能关心的就是不仅仅是这两个,是不是还想知道它的那个损失函数啊,当前的损失函数对不对?那我们还是定义一个cost,就是这个,我们是不是直接可以从这去copy啊,大家想到最后得到的W跟B带进去,是不是算出来就是最后的那个cost啊啊,我们把这两行也copy过来。
23:12
大家可以预测一下,觉得这个costs比之前应该大还是小?大家看一下这个cos的最后,但其实看到这个迭代几次之后,这个大概可能是第四次四次还没有啊,可能第五次第六次之后是不是就已经区域不变了呀,然后大家会发现最后得到的cost是112.6558,那跟之前比对这个一百一是不是要比这个要大一些啊,嗯,大家知道为什么对不对,梯度下降它是不是一个迭代法,是做了一个近似啊呃,那大家知道为什么最后他有可能达不到最后的呃,这样的一个最小值嘛,对,有可能次数不够,也有可能是不是到了最近的那一段之后,我们的步长就不够小,就有可能开始震荡了呀,有可能就永远到不了那个最小点,对不对啊,所以这都是有可能的,因为大家发现这个收敛其实收敛的还很快,对吧,很快就下降下来了,但是之后它一直达不到更小的地方了,所以呃,大家可以去。
24:18
试着调一调我们前面给的这调这些参数是不是有可能啊,就会做的更好啊啊这些大家可以去尝试着做一些改进啊,呃,当然了,就是最后我们是不是还可以再做一步第六步对吧?是不是可以画出你和曲线啊,那么这一步当然我们就还是用这里面的代码直接copy过来是不是就可以了。完全一样对吧,大家看一下现在这一个,诶大家大家看这个跟这个一样吗?其实其实还是不一样对吧?大家如果细心的去看的话,其实还是不一样的,比如说这里是不是好像就完全经过这一点了呀,那这里是不是看起来好像就偏差了一点,对不对,所以它的斜率还是略微不同的对吧?这里边大家看这个好像高一点,这个截距要高一点对不对,那这里我们是不是这这里就低一些啊,但是整体看起来好像好像也还确实是那么回事儿,对不对啊,看起来还是比较呃比较接近的啊,所以这就是我们用不同的方法,最小二乘和梯度下降分别实现这样的一个线性回归的一个拟合,好。
我来说两句