梯度下降只能找到局部最优,找不到全局最优,大海捞针,针确实在海里,但是没有办法找到。
模型在测试集上错误率很高,不能说一定是过拟合,需要看模型在训练集上的错误率。
如果在测试集上错误率高,但是在训练集上模型的错误率低,说明是过拟合问题。
如果在测试集和训练集上模型的错误率都高,说明是优化问题不是过拟合问题。
例如上图中,在测试集上56层的模型错误率比20层的模型错误率高,并且在训练集上56层的模型错误率比20层的模型错误率也高,这就不能说56层的模型过拟合,而是56层的模型优化没有做好。
看到一个从来没有做过的问题,也许可以先跑一些比较小的,比较浅的network,或甚至用一些,不是deep learning的方法,比如说 linear model,比如说support vector machine,support vector machine不知道是什么也没有关系,它们可能是比较容易做Optimize的,它们比较不会有optimization失败的问题。也就是这些model它会竭尽全力的,在它们的能力范围之内,找出一组最好的参数,它们比较不会有失败的问题,所以你可以先train一些,比较浅的model,或者是一些比较简单的model,先知道这些简单的model,到底可以得到什么样的loss。
If deeper networks do not obtain smaller loss on training data, then there is optimization issue.
举例来说,上次看到的观看人数预测的例子,在训练集上面,2017年到2020年的资料是训练集,一层的network,它的loss是0.28k,2层就降到0.18k,3层就降到0.14k,4层就降到0.10k。但是我测5层的时候结果变成0.34k,这是什么问题?
5层loss很大但4层loss很小,这显然不是model bias的问题,因为4层都可以做到0.10k了,5层应该可以做得更低(前4层一样,最后一层什么都不做),这个是optimization的problem,这个是optimization的时候做得不好,才造成这样子的问题。
那如果optimization做得不好的话,怎么办呢,这个下一节课,就会告诉大家要怎么办,你现在就知道怎么判断,现在如果你的training的loss大,到底是model bias还是optimization,如果model bias 那就把model变大,如果是optimization失败了,那就看等一下的课程怎么解这个问题。
问题:Optimization Issue 应该如何解决?
It is correct that the loss is small on both the test set and the training set.
假设根据训练集和某一个很废的machine learning的方法,它找出了一个一无是处的function。这个function说,如果今天x当做输入的时候,我们就去比对这个x,有没有出现在训练集里面,如果x有出现在训练集里面,就把它对应的ŷ当做输出,如果x没有出现在训练集里面,就输出一个随机的值。那你可以想象这个function啥事也没有干,但虽然它是一个一无是处的function,它在training的data上,它的loss可是0呢。
把training的data,通通丢进这个function里面,它的输出跟训练集的level,是一模一样的,所以在training data上面,这个一无是处的function,它的loss可是0呢,可是在testing data上面,它的loss会变得很大,因为它其实什么都没有预测,这是一个比较极端的例子,在一般的状况下,也有可能发生类似的事情。
只给模型这三个点进行训练,在这三个点上面要让loss低,所以model的这个曲线会通过这三个点,但是其他没有训练集做为限制的地方,它就会有freestyle,所以model可以变成各式各样的function。
testing data 和 training data 不会一模一样,它们可能是从同一个distribution sample出来的。测试data是上图橙色的这些点,训练data是蓝色的这些点。用蓝色的这些点找出一个function以后,橘色的这些点上测试不一定会好,如果model它的自由度很大的话,它可以产生非常奇怪的曲线,导致训练集上的结果好,但是测试集上的loss很大。
问题:为什么这个比较有弹性的model就可能overfitting背后的数学原理是什么?
Data augmentation就是用一些自己对于这个问题的理解,自己创造出新的资料。举例来说在做影像辨识的时候,非常常做的一个招式是,假设训练集里面有某一张图片,把它左右翻转,或者是把它其中一块截出来放大等等,做左右翻转,资料就变成两倍。但是要注意一下data augmentation,不能够随便乱做,这个augment 要augment得有道理,在影像辨识里面很少看到有人把影像上下颠倒当作augmentation,因为这些图片都是合理的图片,把一张照片左右翻转,并不会影响到里面是什么样的东西,但把它颠倒那就很奇怪了,这可能不是一个训练集里面,可能不是真实世界会出现的影像。那如果给机器看这种奇怪的影像的话,它可能就会学到奇怪的东西,所以data augmentation要根据对资料的特性,对现在要处理的问题的理解,来选择合适的方式。
另外一个解法就是不要让你的模型,有那么大的弹性,给它一些限制。
举例来说,假设我们猜测出x跟y背后的关系,直接限制说model其实就是一条二次曲线,只是我们不明确的知道这二次曲线,里面的每一个参数长什么样。那你说你怎么会猜测出这样子的结果,你怎么会知道说,要用多constrain的model才会好呢?那这就取决于你对这个问题的理解,因为这种model是你自己设计的,到底model要多constrain多flexible结果才会好,那要看这个设计出不同的模型,你就会得出不同的结果。
那现在假设我们已经知道说,模型就是二次曲线,那你就会在选择function的时候有很大的限制,因为二次曲线来来去去就是那几个形状而已。所以当我们的训练集有限的时候,虽然说只给了三个点,但是因为我们能选择的function有限,你可能就会正好选到跟真正的distribution比较接近的function,然后在测试集上得到比较好的结果。
给它比较少的参数。如果是deep learning的话,就给它比较少的神经元的数目,本来每层一千个神经元,改成一百个神经元之类的,或者是你可以让model共享参数,你可以让一些参数有一样的数值,那这个部分如果你没有很清楚的话,也没有关系,我们之后在讲CNN的时候会讲到这个部分,就是我们之前讲的network的架构,叫做fully-connected network,这其实是一个比较有弹性的架构,而CNN是一个比较有限制的架构。你可能会说CNN不是比较厉害吗,大家都说做影像就是要CNN,比较厉害的model,难道它比较没有弹性吗?没错,它是一种比较没有弹性的model,它厉害的地方在于它是针对影像的特性来限制模型的弹性,所以你今天fully-connected的network,可以找出来的function所形成的集合,其实是比较大的,CNN这个model所找出来的function,它形成的集合其实是比较小的,其实包含在fully-connected的network里面的。但是因为CNN给了比较大的限制,所以CNN在影像上,反而会做得比较好,那这个之后都还会再提到。
另外一个就是用比较少的features。本来给三天的资料,改成用给两天的资料,其实结果就好了一些,那这个是一个招数。
但是也不能给模型太多的限制。
问题:为什么不能给模型太多的限制呢?
假设我们现在给模型更大的限制说,我们假设我们的模型,一定是Linear的Model,一定是写成y=a+bx,那你的model它能够产生的function,就一定是一条直线。
今天给三个点(上图蓝色圆圈),没有任何一条直线可以同时通过这三个点,但是你只能找到一条直线,这条直线跟这些点比起来,它们的距离是比较近的,但是你没有办法找到任何一条直线同时通过这三个点,这个时候你的模型的限制就太大了,你在测试集上就不会得到好的结果。
但是这个不是overfitting,你又回到了model bias的问题,所以在这个情况下,这个投影片的case上你结果不好,并不是因为overfitting了,而是因为你给你模型太大的限制,大到你有了model bias的问题。所以你就会发现说,这边产生了一个矛盾的状况,今天你的模型的复杂程度越来越大,或让你的模型的弹性越来越大,但是什么叫做复杂的程度,什么叫做弹性,在今天这堂课里面,我们其实都没有给明确的定义,只给你一个概念上的叙述。那在下下周的课程里面,你会真的认识到什么叫做一个模型很复杂,什么叫做一个模型有弹性,怎么真的衡量一个模型的弹性,复杂的程度有多大,那今天我们先用直观的来了解。
问题:什么是模型的复杂度?如何衡量模型的复杂度?
问题:什么是模型的弹性?如何衡量模型的弹性?
所谓比较复杂是,它可以包含的function比较多,它的参数比较多,这个就是一个比较复杂的model。那一个比较复杂的model,如果你看它的training的loss,随着model越来越复杂,Training的loss可以越来越低,但是testing的时候呢,当model越来越复杂的时候,刚开始testing的loss会跟着下降,但是当复杂的程度,超过某一个程度以后,Testing的loss就会突然暴增了。
当你的model越来越复杂的时候,复杂到某一个程度,overfitting的状况就会出现,所以你在training的loss上面,可以得到比较好的结果,那在Testing的loss上面,你会得到比较大的loss,那我们当然期待说,我们可以选一个中庸的模型,不是太复杂的,也不是太简单的,刚刚好可以在训练集上,给我们最好的结果,给我们最低的loss,同时给我们最低的testing loss,怎么选出这样的model呢?
如上图,假设我们有三个模型,它们的复杂的程度不太一样,我不知道要选哪一个模型才会刚刚好,在测试集上得到最好的结果,因为你选太复杂的就overfitting,选太简单的有model bias的问题,那怎么选一个不偏不倚的,不知道怎么办?把这三个模型的结果都跑出来,然后上传到kaggle上面,你及时的知道了你的分数,看看哪个分数最低,那个模型显然就是最好的模型。但是并不建议你这么做,为什么不建议你这么做呢?
我们再把刚才那个极端的例子拿出来,假设现在有一群model都非常废,它们每一个model产生出来的都是一无是处的function,我们有一到一兆个model,它们会做的事情就是:训练集里面有的资料就把它记下来,训练集没看过的,就直接output随机的结果。那你现在有一兆个模型,把这些模型的结果通通上传到kaggle上面,得到一兆个分数,然后看这一兆的分数里面哪一个结果最好,你就觉得那个模型是最好的。那虽然说每一个模型在这个Testing data上面输出的结果都是随机的,但是你不断的随机,你总是会找到一个好的结果,所以也许编号五六七八九的那个模型,它找出来的function,正好在testing data上面就给你一个好的结果,那你就会很高兴觉得说,这个model编号五六七八九是个好model,这个好model得到一个好function。虽然它其实是随机的,但你不知道于是就选了这一个model,当作我们最后上传的结果,当作我最后要用在private testing set上的结果。但是如果你这样做,往往就会得到非常糟的结果,因为这个model毕竟是随机的,它恰好在public的testing set data上面得到一个好结果,但是它在private的testing set上可能仍然是随机的,并不代表在private set上 有一个好的结果。
我们这个testing set分成public的set跟private的set,你在看分数的时候只看得到public的分数,private的分数要deadline以后才知道,但假设你在挑模型的时候,你完全看你在public set上面的(leaderboard上的分数)来选择你的模型的话,你可能碰到这个情况:你在public的leaderboard上面排前十,但是deadline一结束,你就心态就崩了这样,你就掉到三百名之外,而且我们这修课的人这么多,你搞不好会掉到一千名之外,也说不定。
问题:为什么要把testing的set分成public跟private呢?
假设所有的data都是public,就算是一个一无是处的Model,得到了一无是处的function,它也有可能在public的data上面,得到好的结果,如果只有public的testing set,没有private的testing set,那写一个程序,不断random产生输出就好,然后不断把random的输出,上传到kaggle,然后看什么时候,可以random出一个好的结果,那这个作业就结束了。这个显然没有意义,显然不是希望得到的。
要把Training的资料分成两半,一部分叫作Training Set,一部分是Validation Set。
有90%的资料放在Training Set里面,有10%的资料被拿来做Validation Set,你在Training Set上训练出来的模型,在Validation Set上面去衡量它们的分数,根据这个分数去挑选结果,再把这个结果上传到Kaggle上面,去看看你得到的public的分数,那因为你在挑分数的时候,是用Validation Set来挑你的model,所以你的public的Testing Set的分数,就可以反应你的private Testing Set的分数,就比较不容易出现“在public上面结果很好,但是在private上面结果很差”的状况。
当你看到public的结果以后,你就会去想要调它,你看到你现在弄了一堆模型,然后用Validation Set检查一下,找了一个模型放到public set上以后,发现结果不好,你其实不太可能不根据这一个结果,去调整你的模型,但是假设这一个route做太多次,你根据public Testing Set上的结果去调整你的model太多次,你就又有可能fit在你的public Testing Set上面,然后在private Testing Set上面,得到差的结果,不过还好反正我们有限制上传的次数,所以这个route,你也没有办法走太多次,可以避免你太过fit在public的Testing Set上面的结果。
其实最好的做法就是直接挑Validation loss最小的model,就是你暂时不要对其进行优化,防止overfitting。那实际上你不太可能这么做,因为public set的结果你有看到,所以它对你的模型的选择可能还是会有些影响的,但是你要越少去看那个public Testing Set的结果越好。
mismatch的原因跟overfitting其实不一样,一般的overfitting,你可以用搜集更多的资料来克服,但是mismatch意思是说,你今天的训练集跟测试集的分布是不一样的。
在训练集跟测试集分布是不一样的时候,你训练集增加其实也没有帮助了,那其实在多数的作业里面,我们不会遇到这种mismatch的问题,我们都有把题目设计好了,所以资料跟测试集它的分布差不多。
举例来说,以作业一的Covid19为例的话,假设我们今天资料在分训练集跟测试集的时候,我们说2020年的资料是训练集,2021年的资料是测试集,那mismatch的问题可能就很严重了,这个我们其实有试过了,做不起来,训练什么模型都会惨掉。因为2020年的资料跟2021年的资料,它们的背后的分布其实都是不一样,所以你拿2020年的资料来训练,在2021年的作业一的资料上,不可能预测正确。
在作业11会遇到mismatch的问题,作业十一就是针对mismatch的问题来设计的。
问题:如何判断是否mismatch?
要看自己对这个资料本身的理解了,你可能要对你的训练集跟测试集的产生方式有一些理解,你才能判断说,它是不是遇到了mismatch的状况。