今天是1024程序员节。
这是李宏毅老师的2021春季机器学习课程笔记。现在开始第一节 Introduction 的学习,让我们开始吧。
目录
Regression
Different types of Functions
Case Study
Step 1. Function with Unknown Parameters
Step 2. Define Loss from Training Data
Step 3. Optimization
Linear Model
第一堂课是要简单跟大家介绍一下machine learning还有deep learning的基本概念,等一下会讲一个跟宝可梦完全没有关系的故事。什么是机器学习呢?
想必大家在报章杂志上其实往往都已经听过机器学习这一个词汇,那你可能也知道说机器学习就是跟今天很热门的AI好像有那么一点关联。
那所谓的机器学习到底是什么呢?顾名思义,机器他具备有学习的能力,那些科普文章往往把机器学习这个东西吹得玄之又玄,好像机器会学习以后,我们就有了人工智慧,有了人工智慧以后机器接下来就要统治人类了。那机器学习到底是什么呢?事实上,机器学习概括来说可以用一句话来描述机器学习这件事,机器学习就是让机器具备找一个函式的能力。
那机器具备找函式的能力以后,他确实可以做很多事。举例来说(如上图)
随着我们要找的函式不同,机器学习有不同的类别,那这边介绍几个专有名词给大家认识一下。 第一个专有名词叫作Regression。Regression的意思是说,假设我们今天要找的函式,他的输出是一个数值,他的输出是一个 scalar,那这样子的机器学习的任务,我们称之为Regression。
那这边举一个Regression的例子,假设我们今天要机器做的事情,是预测未来某一个时间的PM2.5的数值,机器做的事情是找一个函式,这个我们用f来表示,这个函式的输出是明天中午的PM2.5的数值,他的输入可能是种种跟预测PM2.5有关的指数,包括今天的PM2.5的数值,今天的平均温度,今天平均的臭氧浓度等等,这一个函式可以拿这些数值当作输入,输出明天中午的PM2.5的数值,那这一个找这个函式的任务,叫作Regression。
除了Regression以外,另外一个大家耳熟能详的任务,叫作Classification,那Classification这个任务,要机器做的是选择题。我们先准备好一些选项,那这些选项,又叫作类别(classes),我们现在要找的函式的输出,就是从我们设定好的选项里面,选择一个当作输出那这个问题,这个任务就叫作Classification。
举例来说,现在每个人都有gmail account,那gmail account里有一个函式,这个函式可以帮我们侦测一封邮件,是不是垃圾邮件,这个函式的输入是一封电子邮件,那他的输出是什么呢,你要先准备好你要机器选的选项,在侦测垃圾邮件这个问题里面,可能的选项就是两个,是垃圾邮件或不是垃圾邮件,Yes或者是No,那机器要从Yes跟No里面,选一个选项出来,这个问题叫作Classification,那Classification不一定只有两个选项,也可以有多个选项。
举例来说,如上图,alpha go本身也是一个Classification的问题,那只是这个Classification的选项是比较多的,那如果要叫机器下围棋,你想做一个 alpha go的话,我们要给机器多少的选项呢,你就想想看棋盘上有多少个位置,那我们知道棋盘上有19乘19个位置,其实,就是一个有19乘19个选项的选择题,机器做的就是找一个函式,这个函式的输入是棋盘上,黑子跟白子的位置,输出就是从19乘19个选项里面,选出一个正确的选项,从19乘19个可以落子的位置里面,选出下一步应该要落子的位置,那这个问题也是一个分类的问题。
其实很多教科书在讲机器学习的不同类型的任务的时候,往往就讲到这边。机器学习两大类任务,一个叫作Regression,一个叫作Classification,然后就结束了,但是假设你对机器学习的认知,只停留在机器学习就是两大类任务,Regression跟Classification,那就好像说,这个世界只有五大洲一样(这是远远不够的)。
你知道这个世界不是只有五大洲,这个世界外面是有一个黑暗大陆。这鬼灭之刃连载之前,我们就已经出发前往黑暗大陆了,鬼灭之刃连载以后,我们居然都还没有到,可见这个黑暗大陆距离那么远,那在机器学习这个领域里面,所谓的黑暗大陆是什么呢,在于Regression跟Classification以外,大家往往害怕碰触的问题,叫作Structured Learning,也就是机器今天不只是要做选择题,不只是输出一个数字,还要产生一个有结构的物件。举例来说,机器画一张图写一篇文章,这种叫机器产生有结构的东西的问题,就叫作Structured Learning,那如果要讲得比较拟人化,就是要叫机器学会创造这件事情。那到目前为止,我们就是讲了三个机器学习的任务,Regression、Classification跟Structured Learning。
机器学习就是要找一个函式,那机器怎么找一个函式呢,那这边要用个例子跟大家说明说。在讲这个例子之前,先跟大家说一下,说这一门课有一个youtube的频道https://www.youtube.com/c/HungyiLeeNTU,然后这个我会把上课的录影,放到这个youtube的频道上面,感谢过去修过这门课的同学不嫌弃,其实也蛮多人订阅,所以我算是一个三流的youtuber,是没有什么太多流量,但是这边也是有7万多订阅(李宏毅老师很谦虚呀!)。
那为什么突然提到,这个youtube的频道呢,因为我们等一下要举的例子,跟youtube是有关系的,youtuber在意的,就是这个频道的流量。假设有一个youtuber,是靠着youtube维生的,他会在意频道有没有流量,这样他才会知道他可以获利多少,假设你自己有youtube频道的话,你会知道说在youtube后台,你可以看到很多相关的资讯,你可以看到很多相关的资讯,比如说每一天按赞的人数有多少,每一天订阅的人数有多少,每一天观看的次数有多少,我们能不能够根据,一个频道过往所有的资讯去预测,它明天有可能的观看的次数是多少呢,我们能不能够找一个函式,这个函式的输入是youtube上面,youtube后台是我的资讯,输出就是某一天这个频道会有的总观看的次数。
机器学习找这个函式的过程,分成三个步骤,那我们就用Youtube频道,点阅人数预测这件事情,来跟大家说明这三个步骤,是怎么运作的。
第一个步骤是我们要写出一个,带有未知参数的函式,简单来说就是我们先猜测一下,我们打算找的这个函式F,它的数学式到底长什么样子。举例来说,我们这边先做一个最初步的猜测,我们写成这个样子 y=b+w*xₗ 这边的每一个数值是什么呢,这个y就假设是今天吧,不过今天还没有过完,所以我还不知道,今天总共的点阅次数是多少,所以这件事情是我们未知的。
这个猜测往往就来自于,你对这个问题本质上的了解,也就是Domain knowledge,所以才会听到有人说,这个做机器学习啊,就需要一些Domain knowledge,所以我们这个能够预测未来点阅次数的函式F,它就一定是前一天的点阅次数乘上w再加上b呢,我们先不知道这是一个猜测,也许我们觉得说,这个今天的点阅次数,总是会跟昨天的点阅次数有点关联,所以我们把昨天的点阅次数,乘上一个数值,但是总是不会一模一样,所以再加上一个b做修正,当作是对于2月26号,点阅次数的预测,这是一个猜测,它不一定是对的,我们之后会再来修正这个猜测。
那现在总之,我们就猜测y=b+wxₗ,而b跟w是未知的参数(Parameter),这个带有Unknown的Parameter的Function 叫做模型(Model)。这个xₗ是这个Function里面我们已知的东西,它是来自于Youtube后台的资讯,已知2月25号点阅的总人数是多少,这个东西叫做特征(Feature)。那这边我们也给w跟b一个名字,这个w我们叫它weight,b我们叫它Bias,那这个只是一些名词的定义而已,在讲解起来更为方便,这个是第一个步骤。
第二个步骤,是我们要定义Loss Function,那这个Function它的输入是Parameter,即Model里面的参数b跟w,这是我们准备要找出来的;输出的值代表说,现在如果我们把这一组未知的参数,设定某一个数值的时候,这笔数值好还是不好。
那这样讲可能你觉得有点抽象,看一个具体的例子。假设现在未知的参数是b等于0.5k,w等于1,那这个Loss怎么计算呢?
我们从训练资料来进行计算。在这个问题里面是这个频道过去的点阅次数,例如,2017年1月1号到2020年12月31号的点阅数字(这边是假的数字),接下来我们就可以计算Loss。
我们把2017年1月1号的点阅次数,代入这一个函式里面,此时xₗ=4.8k,得到5.3k的点阅次数。那隔天实际上的点阅次数,我们知道为4.9k,所以我们可以比对一下,函式预估的结果跟真正的结果(这个真实的值叫做Label),它的差距有多大。这边估测的值用y来表示,真实的值用ŷ来表示,你可以计算y跟ŷ之间的差距eₗ。那计算差距其实不只一种方式,这边把y跟ŷ相减,直接取绝对值,算出来的值是0.4k。
那我们不是只能用1月1号,来预测1月2号的值,同理,我们可以用1月2号的值,来预测1月3号的值,以xₗ代4.9k进去,乘1在加0.5k 等于5.4k,接下来计算e₂(y跟ŷ之间的差距),算出来是2.1k。同样可以算过这三年每一天的预测的误差,每一天的误差都可以给我们一个e。
接下来我们把每一天的误差加起来然后取得平均,N代表我们的训验资料的个数,就是365乘以3,我们算出一个L,是每一笔训练资料的误差,就是我们的Loss。L越大,代表我们现在这一组参数越不好,L越小,代表现在这一组参数越好。
估测的值跟实际的值之间的差距,其实有不同的计算方法,在我们刚才的例子里面,我们是算y跟ŷ之间,绝对值的差距,这一种计算差距的方法,得到的这个大L,得到的Loss叫 mean absolute error(MAE)。如果你今天的e是用,相减y平方算出来的,这个叫mean square error(MSE)。那MSE跟MAE,他们其实有非常微妙的差别。我们就是选择MAE和MSE都是可以的。如果y和ŷ它都是机率分布的话,你可能会选择Cross-entropy,这个我们都之后再说。我们这边就是选择了MAE。
这里再补充一个概念Error Surface:
对于真实的例子,这个频道真实的后台的数据所计算出来的结果,那我们可以调整不同的w,我们可以调整不同的b,组合起来以后,都去计算它的Loss,然后就可以画出下面的这个等高线图。
如上图所示,越偏红色系,代表计算出来的Loss越大,就代表这一组w跟b越差,如果越偏蓝色系,就代表Loss越小,就代表这一组w跟b越好。假设w在负0.25,这个b在负500,就代表说这个频道每天看的人越来越少,而且Loss这么大,跟真实的状况不太合;如果w在0.75、b在500,那这个估测会比较精准。那估测最精准的地方看起来应该是在这里啦,w代一个很接近1的值,b带一个小小的值,比如说100多,那这个时候估测是最精准的,那这跟大家的预期可能是比较接近的,就是你拿前一天的点阅的总次数,去预测隔天的点阅的总次数,那可能前一天跟隔天的点阅的总次数,其实是差不多的,所以w设1,然后b设一个小一点的数值,也许你的估测就会蛮精准的,那像这样子的一个等高线图,就是你试着试了不同的参数,然后计算它的Loss,画出来的这个等高线图,叫做Error Surface,那这个是机器学习的第二步。
接下来我们进入机器学习的第三步,解一个最佳化的问题。把未知的参数w跟b,找一个数值出来,代入L,让我们的Loss的值最小,那个就是我们要找的w跟b。
在这一门课里面我们唯一会用到的Optimization的方法,叫做梯度下降法(Gradient Descent)。为了要简化起见,先假设未知的参数只有一个,只有w这个未知的参数。
那当我们w代不同的数值的时候,我们就会得到不同的Loss,这一条曲线就是error surface,只是刚才在前一个例子我们看到的error surface是二维的是2D的,那这边只有一个参数,所以我们看到的这个error surface,是1D的。
那怎么样找一个w,去让这个loss的值最小呢?
有同学问说,为什么loss可以是负的呢?
Loss这个函数是自己定义的,所以在刚才我们的定义里面,我们说loss就是估测的值,跟正确的值,它的绝对值,那如果根据刚才loss的定义,那它不可能是负的,但是loss的这一个function,是你自己决定的,你可以说,我今天要决定一个loss function,就是绝对值再减100,那你可能就有负的,所以我这边这一个curve并不是一个真实的loss,它是我随便乱举的一个例子,因为在今天,我想要举一个比较general 的case,它并不是一个真实任务的,Error surface,所以这个loss的这个curve,这个error surface,它可以是任何形状,这边没有预设立场说,它一定要是什么形状,但是在刚才这一个如果loss的定义是绝对值,那它就不可能是负值,但这个loss,这个function是你自己决定的,所以它有可能是负的。
那我们说我们要把w⁰往右移一步,那这个新的位置就叫做w¹,这一步的步伐是η乘上微分的结果,那如果你要用数学式来表示它的话,就是把w⁰减掉η乘上微分的结果,那接下来你就是反复进行刚才的操作,你就计算一下w¹微分的结果,然后再决定现在要把w¹移动多少,然后再移动到w²,然后你再继续反覆做同样的操作,不断的把w移动位置,最后你会停下来。
什么时候会停下来呢?往往有两种状况:
你可能会马上发现说,Gradient Descent 这个方法,有一个巨大的问题,我们没有找到真正最好的解,在这个例子里面,从W^0当作随机初始的位置,很有可能走到W^T这里,你的训练就停住了,你就没有办法再移动w的位置。那右侧红点这一个位置,这个真的可以让loss最小的地方,叫做全局最小值(global minima),而W^T这个地方叫做局部最小值(local minima),它的左右两边,都比这个地方的loss还要高一点,但是它不是整个error surface上面的最低点。
所以常常可能会听到有人讲到,Gradient Descent不是个好方法,这个方法会有local minima的问题,没有办法真的找到global minima,但这个其实只是幻觉而已。事实上,假设你有做过深度学习相关的事情,自己训练过network,自己做过Gradient Descent 经验的话,其实local minima是一个假问题。我们在做Gradient Descent 的时候,真正面对的难题不是local minima,之后会讲到底是什么。在这边你就先接受,先相信多数人的讲法说,Gradient Descent有local minima的问题。在这个图上在这个例子里面,显然有local minima的问题,但之后会再告诉你说,Gradient Descent真正的痛点,到底是什么。
刚才举的例子,是只有一个参数的例子而已。那实际上我们刚才的模型有两个参数有w跟b,那有两个参数的情况下,怎么用Gradient Descent呢?如上图所示,其实跟刚才一个参数没有什么不同,若一个参数你没有问题的话,你可以很快的推广到两个参数。
如果你不会算微分的话,不用紧张,在pytorch里面,算微分都是程序帮你算的,写一行程序,自动就把微分的值就算出来了。这个等一下之后在做AE的时候,大家可以自己体验看看,那就是反覆同样的步骤,就不断的更新w跟b,然后期待最后可以找到一个最好的w跟最好的b。
接下来看看它操作起来是什么样子。
假设你随便选一个初始的值在这个地方(上图小圆点),先计算一下w对L的微分和b对L的微分,然后接下来更新w跟b,更新的方向就是w对L的微分乘以η再乘以一个负号,你就可以决定w要怎么更新,b也同理,然后把w跟b更新的方向结合起来,得到一个矢量(上图这个红色的箭头),我们就从这个位置移到这个位置。
然后再计算一次微分,决定要走什么样的方向,把这个微分的值乘上learning rate,再乘上负号,你就知道红色的箭头要指向那里,结合w跟b的移动位置,一直移动一直移动一直移动,期待最后可以找出一组不错的w跟b。
那实际上真的用Gradient Descent,进行一番计算以后,这个是真正的数据,我们算出来的最好的w是0.97,最好的b是0.1k,跟我们的猜测蛮接近的,因为x₁的值可能跟y很接近,所以这个w就设一个接近1的值,b就设一个比较偏小的值。那loss多大呢,loss算一下是0.48k,即在2017到2020年的资料上,如果使用这一个函式,b=0.1k,w=0.97,那平均的误差是0.48k,也就是它的预测的观看人数误差,大概是500人次左右。
那w跟b的值刚才已经找出来的,那这组w跟b可以让loss小到0.48k,但是这样是一个让人满意或值得称道的结果吗?
也许不是,如上图,这三个步骤合起来叫做训练。我们现在是在知道答案的资料上去计算loss。所以其实我们现在其实只是在自high而已,就是假装我们不知道隔天的观看次数,然后拿这一个函式来进行预测,发现误差是0.48k。
但是我们真正要在意的是未来的观看的次数是多少,所以接下来拿这个函式来真的预测一下未来的观看次数。
那这边,我们已知2017年到2020年的值,接下来从2021年开始每一天,我们都拿这个函式,去预测隔天的观看人次,我们就拿2020年的12月31号的观看人次,去预测2021年元旦的观看人次;用2021年元旦的观看人次预测一下2021年1月2号的观看人次;用1月2号的观看人次去预测1月3号的观看人次......每天都做这件事,一直做到2月14号情人节,然后得到平均的误差值。在2021年没有看过的资料上,用L prime来表示,它是0.58k,看起来误差值是比较大的,那我们每一天的平均误差,有580人左右,600人左右。
能不能够做得更好呢,在做得更好之前,我们先来分析一下结果,如上图所示:
你有发现很明显的,这蓝色的线没什么神奇的地方,它几乎就是红色的线往右平移一天而已,因为这很合理,因为我们觉得,可以拿前一天的观看人次去预测隔天的观看人次,前一天观看人次乘以0.97,加上0.1。但是如果你仔细观察这个图,你就会发现,这个真实的资料有一个很神奇的现象,它是有周期性的,它每隔七天就会有两天特别低,两天观看的人特别少,那两天是什么日子呢,是礼拜五跟礼拜六,可能大家出去玩,那不知道为什么,礼拜天大家去学机器学习,这个我还没有参透为什么是这个样子。也许跟youtube背后,神奇的算法有关系,比如说youtube都会推频道的影片,也许youtube在推频道的影片的时候,它都选择礼拜五礼拜六不推,只推礼拜天到礼拜四,可是为什么推礼拜天到礼拜四呢,这个我也不了解,但是反正看出来的结果,我们看真实的数据,每隔七天一个循环,每个礼拜五礼拜六,看的人就是特别少。所以既然我们已经知道每隔七天是一个循环,那这一个model显然很烂,因为它只能够看前一天。
每隔七天它一个循环,如果我们一个模型,它是参考前七天的资料,把七天前的资料,直接复制到拿来当作预测的结果,也许预测的会更准也说不定,所以我们就要修改一下我们的模型。通常一个模型的修改,往往来自于你对这个问题的理解,就是Domain Knowledge。
所以一开始,我们对问题完全不理解的时候,我们就胡乱写一个 y=b+wx_1 ,效果并没有特别好。接下来我们观察了真实的数据以后,得到一个结论是,每隔七天有一个循环,所以我们应该要把,前七天的观看人次都列入考虑,所以写了一个新的模型。
xⱼ的下标j代表是几天前,然后这个j等于1到7,也就是从一天前一直考虑到七天前,那七天前的资料,通通乘上不同的weight,乘上不同的wⱼ,加起来,再加上bias,得到预测的结果。如果这个是我们的model,那我们得到的结果是怎么样呢,我们在训练资料上的loss是0.38k,那因为这边只考虑一天,这边考虑七天,所以在训练资料上,你会得到比较低的loss,这边考虑了比较多的资讯,这边算出来是0.38k,在没有看到的资料上,有比较好,是0.49k。
那这边每一个w跟b,我们都会用Gradient Descent,算出它的最佳值,它的最佳值长什么样子呢,这边show出来。当然机器的逻辑我是有点没有办法了解,我本来以为它会选七天前的数据,七天前的观看人数,直接复制过来,我看来它没有这样选就是了。
它的逻辑是前一天,跟你要预测的隔天的数值的关系很大,所以w₁是0.79,前三天是0.12,然后前六天是0.3,前七天是0.18,不过它知道说,如果是前两天前四天前五天,它的值会跟未来我们要预测的,隔天的值是成反比的,所以w₂ w₄跟w₅它们最佳的值是负的,但是w₁ w₃ w₆跟w₇是正的。我们考虑前七天的值,那你可能会问说,能不能够考虑更多天呢,可以,那这个轻易的改考虑更多天,本来是考虑前七天,然后考虑28天会怎么样呢,28天就一个月,考虑前一个月每一天的观看人次,去预测隔天的观看人次,预测出来结果怎样呢,训练资料上是0.33k,那在2021年的资料上,在没有看过的资料上是0.46k,看起来又更好一点。那接下来考虑56天会怎么样呢?在训练资料上是稍微再好一点,是0.32k,在没看过的资料上还是0.46k,看起来,考虑更多天没有办法再更进步了,也许已经到了一个极限。这边这些模型输入x(feature),把feature乘上一个weight,再加上一个bias就得到预测的结果,这样的模型有一个共同的名字,叫做Linear model,那我们接下来会看,怎么把Linear model做得更好。
说明:记录学习笔记,如果错误欢迎指正!写文章不易,转载请联系我。