李宏毅 机器学习 2016 秋:4、bias vs variance

2023-10-26

四、Where does the error come from

我们上一次有看到说,如果你选择不同的 function set,你就是选择不同的 model,你在 testing data 上也会得到不同的 error,而且越复杂的 model 不见得会给你越低的 error,你会发现说,做 linear regression 的时候,我们考虑的 input 是 1 次、1 次 2 次、 1 次 2 次 3 次一直到 1 次到 5 次,那你发现,最复杂的 model, 其实它的 performance 是最差的,今天我们要讨论的问题就是,这个 error 来自什么地方。

其实 error 有两个来源,一个是来自于 bias,一个是来自于 variance。了解这个 error 的来源其实是重要的,因为你常常做一下 machine learning,然后做完就发现说,得到一个 error rate,比如说 60% 的 error rate,接下来你要怎么 improve 你的 model 呢?如果你没有什么方向的话,毫无头绪的乱做,你就没有效率,如果你今天可以诊断你的 error 的来源,比如说 error 可以分成两种, 一种是来自 bias,一种是来自 variance,如果你可以诊断你的 error 的来源,你就可以挑选适当的方法来 improve 你的 model。

在上次的时候,我们举的例子是这样,我们要做宝可梦进化后的 CP 值的估测,也就是说我们要找一个 function,这个 function input 一只宝可梦,output 就是他进化以后的 CP 值,那这个 function,理论上,有一个最佳的 function,这个理论上最佳的 function,我们写成 f ^ \hat f f^,那这个理论上最佳的 function 我们是不知道的,只有 Niantic 知道,Niantic 大家知道是什么吗?就是做宝可梦的那个公司,因为他一定是用那个程式写出来的,所以如果你知道那个程式的话,你就可以知道 input 一个宝可梦,照理说, output 他的进化后的 CP 值应该是什么,但是问题就是这个 function, f ^ \hat f f^ 是你不知道的,那你能够做的事情是,你有一些 training data,你实际去抓一些宝可梦,然后去找一个,根据你的 training data 所学出来、所找到的,最好的 function f f f,那这个 f f f 并不会真的等于 f ^ \hat f f^,因为根本不知道真的 f ^ \hat f f^ 是什么样子。那个 f ∗ f^* f 可能不等于 f ^ \hat f f^,这个 f ∗ f^* f 呢,它就好像是一个 f ^ \hat f f^ 的估测值一样,它的 estimator 一样,所以就想成说现在是在打靶, f ^ \hat f f^ 是靶的中心点,你今天收集到一些 data 做 training 以后,你找到一个你觉得最好的 function f f f,这个 f f f 它不等于 f ^ \hat f f^,它是在把纸上的另外一个位置,这个 f ∗ f^* f 跟这个 f ^ \hat f f^,它们中间有一段距离,这个距离来自于两件事,它可能来自于 bias,也有可能来自于 variance,那一个 estimator 的 bias 和 variance 指的是什么呢?

我们先举一个你在机率里面看过的例子,这个地方在机率,我想应该是机率与统计,你应该是学过的,所以你可以很快地看过去,假设我们现在有一个 variable x x x,我想要估测它的 mean,怎么做呢?假设这个 variable x x x 它的 mean 是 μ \mu μ,它的 variance 是 σ 2 \sigma^2 σ2,那我要估测 mean 的话,我怎么做呢?

我就先 sample N N N 个点,我就对这个 variable sample N N N 个点, x 1 , x 2 , ⋯   , x N x^1, x^2, \cdots, x^N x1,x2,,xN,我们再把这 N N N 个点算平均值得到 m m m,这个 N N N 个点算出来的平均值会跟 μ \mu μ 一样吗?其实不会,对不对?除非你 sample 无穷多个点,不然如果你只 sample 比如说 5 个点、10 个点, n = 5 n = 5 n=5 跟 10,这个 μ \mu μ m m m 它们不见得是一样的,所以,假设这个是 μ \mu μ 的 value,现在你做一次 sample,你 sample n n n 个点算出来的 m m m 可能不会跟 μ \mu μ 一样。

做第一次实验做出 m 1 m_1 m1,有可能跟 μ \mu μ 不一样,再做一次实验 m 2 m_2 m2,也跟 μ \mu μ 不一样, m 3 m_3 m3 也跟 μ \mu μ 不一样, m 4 m_4 m4 也跟 μ \mu μ 不一样, m 5 m_5 m5 不一样, m 6 m_6 m6 也不一样,等等,你没有办法找到一个 m m m 正好 exactly 等于 μ \mu μ,但是如果你今天把你的 m m m 的期望值算出来的话,假如你算 E [ m ] E[m] E[m],然后你就得到 x n x^n xn 的期望值 summation over n n n,取 1 / N 1/N 1/N,反正得到的值,就是 μ \mu μ 这样。

所以今天每一个 m m m 虽然都不一定跟 μ \mu μ exactly 一样,但是如果你找很多 m m m,它们的期望值会正好等于 μ \mu μ,所以用 m m m 来 estimate μ \mu μ m m m 这个 estimator,它是 unbiased,因为他的期望值会正好等于 μ \mu μ,就好像是说,如果你在打靶的时候,他的准心是瞄准 μ \mu μ 的,但是因为种种比如说机械故障,或者受到其他各种风速的干扰等等,你会散落在你本来瞄准的位置的周围。

那这个散布在周围,会散的多开呢?取决于, m m m 的 variance,那这个 Var [ m ] \text{Var}[m] Var[m] 就是 σ 2 / N \sigma^2/N σ2/N,所以你就不要问怎么来的,这个机率课本都有写,那这个 variance 的值呢,它 depend on,你今天取了多少的 sample,如果你有比较多的 N N N 的话,它的散布就会比较集中,如果你只取比较少的 N N N 的话,你那个 m m m 就会分散的比较开,如果你要估测 variance 怎么办呢?

你就先用刚才的办法估测 m m m,估测 m m m 以后,你再计算 ( x n − m ) 2 (x^n-m)^2 (xnm)2,再取它们的平均值,你得到另外的值是 s 2 s^2 s2,这个 s 2 s^2 s2 可以拿来估测 σ 2 \sigma^2 σ2,这个 s 2 s^2 s2 它估测的怎么样呢?当然每一次你算一个 s s s 出来,它们跟 σ \sigma σ,这边我应该要把它取平方才对,因为 s 2 s^2 s2 才是 σ 2 \sigma^2 σ2 的估测值,假设我这边有取平方好了,我们每一次取出来的 s s s,它会散布在,它不会跟 σ \sigma σ 正好一样,它散布在 σ \sigma σ 的周围,但是这个 estimator 它是 biased,也就是说如果你取 s 2 s^2 s2 的期望值的话,它算出来并不是正好等于 σ 2 \sigma^2 σ2,它是 ( N − 1 ) / N (N-1)/N (N1)/N,所以你会发现普遍而言, s 2 s^2 s2 是比 σ 2 \sigma^2 σ2 还要小的,就是小的次数比较多,但因为有 variance 所以也有可能比较大,但是平均而言小的次数是比较多的,如果你 increase N N N 的话,如果 N N N 比较大的话,那 σ 2 \sigma^2 σ2 s 2 s^2 s2 估测之间的差距就会变小。

好,那说了这些,我们回到 regression 这个问题来,比如说我们现在要估测的是,靶的中心,也就是 f ^ \hat f f^,这个是我们的目标,那你 collect 一些 data,做一次实验,你找出来的 f ∗ f^* f 可能是在这个位置,这个位置跟这个红心之间,它们其实有发生了两件事,它们这个 error 取决于两件事,第一件事情是你瞄准的位置在哪里,就是你这个 estimator 是不是 bias,怎么知道 estimator 是不是 bias 呢?你把这个estimator f f f,假设你可以做很多次实验,那你把这个 f f f 的期望值算出来,我们这边写成 f ˉ \bar f fˉ,bar 就是平均的意思, f ∗ f^* f 的期望值算出来就是 f ˉ \bar f fˉ,那你会发现说,假设我们用右下角这个例子来看,你做了很多次实验,找了很多不同的 f ˉ \bar f fˉ,你会发现它们的散布是这些蓝色的点,这个时候你的 f ∗ f^* f 呢,可能是在这个地方,那也就是说你的这个 estimator,跟你的靶心中间是有一个 bias 的,也就是说你瞄的时候就没有瞄准,你以为正中心在这边,你瞄这个点,那实际上呢,靶心是在这个地方,你瞄的时候就没有瞄准,但这还有另外一个 error,这个 error 来自于你瞄准的这个位置,但是你把子弹射出去以后呢,还是会有偏移的,所以你每次找出来的 f ∗ f^* f 是不一样的,而这个 f ∗ f^* f 跟你瞄准的位置,也就是 f ∗ f^* f 期望值 f ˉ \bar f fˉ 中间的距离呢,就是 variance,所以你的错误来自于两件事,一件事情是,你的 bias 有多大,另外一件事情呢,是你的 variance 有多大,所以最理想的状况是,我们期待的是,你同时没有 bias,variance 又小,这样你每次做实验,你找出来的每个 f ∗ f^* f 都是好的。

那如果说今天,你有可能遇到一个状况是,你的 bias 很大,但 variance 很小,那你每一次找的 f ∗ f^* f 都很像,但是都集中在这个错的位置,那你总是有错,那也有可能是,你今天找出来的 f ˉ \bar f fˉ 呢,是没有 bias 的,你瞄的位置是对的,但是你那个枪性能很差,所以它每次射出去以后呢,是散布在这个靶心的周围的,那你也会得到一些 error,所以,error 来自于两个地方,一个是你瞄准的位置在哪里,另外一个是你今天的这个 variance 有多大,可是有的人会问一个问题,你不就只能做一次实验吗?你不就 collect 了十笔 data,然后就找一个 f f f,然后就结束了吗?你怎么找很多个 f f f 呢?你怎么知道它的 variance 跟 bias 有多大呢?你怎么找很多个 f ∗ f^* f 呢?

所以,这个怎么想,你就假设说这个世界上是有很多的平行的宇宙的,在每一个宇宙里都不一样,但是我们都在抓宝可梦这样子,在每一个平行宇宙里面,我们都想 estimate 进化后的 CP 值,所以在每个平行宇宙里面呢,我都去抓了 10 个宝可梦然后来算 f ∗ f^* f,在不同宇宙里面,抓到的 10 只宝可梦是不一样的,这个是第一个宇宙中的我这样子,然后抓到的是这 10 只,这个是第二个宇宙中的我, 其实只是衣服换一个顏色而已,你抓到的是这 10 只,这个是第三个宇宙中的我,这时候性别也换了,然后抓到的是这 10 只,好那因为抓到的宝可梦是不一样的,如果你拿不同的宝可梦来找你的最好的 function,就算你用同一个 model,假设我们现在都用 y = b + w × x c p y = b + w \times x_{cp} y=b+w×xcp 这个 model,我们用同样的 model,但你给它的 data 不一样,那你找出来的最好的 function f ∗ f^* f 就是不一样的。

所以在宇宙编号 123 号,我们抓到的这 10 只宝可梦,用这个 model,我们找出来的 f ∗ f^* f 是这样,在宇宙编号 345 号里面,我们找到另外 10 只宝可梦,我们找到的 model 是这个样子,这两个 model 是不一样的,在不同宇宙里面我们找到的 f ∗ f^* f 是不一样的,好现在我们的问题就是,每一个宇宙找出来的 f ∗ f^* f 就像对着靶子开一枪一样,那我们现在就是要知道说,它的散布是什么样子的,好,所以我们就把 100 个不同宇宙裡面的 f ∗ f^* f 都找出来,当然世界上并没有真的平行宇宙。所以做这件事情其实就是,你就做 100 次实验,然后每次都抓 10 只不同的宝可梦就是了,你了解我的意思,在 100 个平行宇宙里面,我们都抓了 10 只不同的宝可梦,然后,都去找一个 f ∗ f^* f,那今天如果我的 model 是 y = b + w × x c p y = b + w \times x_{cp} y=b+w×xcp,那这 100 个 f ∗ f^* f 它们的分布长什么样子呢?

如果我们把这 100 个 f ∗ f^* f,这 100 个 y = b + w × x c p y = b + w \times x_{cp} y=b+w×xcp 画出来,会长这样,所以有 100 个不同的 w w w,100 个不同的 b b b,你把这 100 条直线都画出来,它会长成这个样子,这边有 100 条直线,那如果我今天换另外一个 model,你换一个 model,这个 model 是考虑了 x c p , ( x c p ) 2 , ( x c p ) 3 x_{cp}, (x_{cp})^2, (x_{cp})^3 xcp,(xcp)2,(xcp)3,你做 100 次实验,在 100 个宇宙里面找出了不同的 b , w 1 , w 2 , w 3 b, w_1, w_2, w_3 b,w1,w2,w3,那你的这 100 条线长这个样子,那你就会发现说有点像是散开了,像花一样地散开了,好,那如果今天是,换一个最复杂的 model,例如:5 次的 model,那你就会发现说,做 100 次实验以后,你把那 100 条虚线都画出来,你就会发现是这样子的,崩溃的,在 100 个宇宙里面,每一件事情都是有可能会发生的。

所以呢,如果我们看这个 model 之间的 variance 的话,如果你看你做 100 次的射击以后,你的结果的散布的话,你会发现说,简单的 model,就是只有考虑一次的 model,它是比较集中的,如果你考虑 5 次的话,它散布就非常的广,所以如果你用一个比较简单的 model 的时候,它的 variance 是比较小的,就好像说,你在射击的时候每次射击的位置是差不多的,你每次找出来的直线呢,你每次找出来的最好的 function f ∗ f^* f 呢,都是差不多的,但是如果你今天换一个比较复杂的 model,它的散布就很开,就像这边蓝色的点一样,它的 variance 很大,散布就很开,这边的每一条直线呢,都长得很不像,各种怪怪的线,都长得不一样, 它的散布呢,就非常的开,今天你可能会问一个问题, 为什么比较复杂的 model,它的散布就比较开呢?为什么比较简单的 model,它就散布的比较紧呢?

因为,你可以这样想,简单的 model 它比较不会受你的 data 的影响,在每个宇宙里面,我们 sample 出来的,我们抓到的宝可梦都不一样, 所以找出来的 model 都不一样,那比较简单的 model,它受到不同 data 的影响是比较小的,举例来说,我们举一个极端的例子,这个极端的例子是,我们的整个 model set 里面呢,就我们整个 function set 里面呢,就一个 function f ( x ) f(x) f(x),output 就是 c c c,你不管抓怎么样的 training data,这个 function output 就是给你 c c c 这样,给你一个 constant,这时候你就会发现说,你在不同的宇宙里面,你找出来的 model 都是一模一样的,因为你根本就没找,它的 variance 是 0,所以如果给你一个最简单的 model,它的 variance 是 0,当你给的这个 model 它的复杂度越来越高的时候呢,它的 variance 呢,就会越来越大,好,接下来呢,我们来看 bias,那 bias 是什么呢?

bias 的意思是说,我们有很多很多的 f ∗ f^* f,假设我们把所有的 f ∗ f^* f 平均起来,找它的期望值,也就是 f ˉ \bar f fˉ 的话,这个 f ˉ \bar f fˉ 跟我们的靶心 f ^ \hat f f^ 它有多接近呢?如果是一个大的 bias 的话,意思是说,你今天把所有的 f ∗ f^* f 平均起来,你得到的 f ˉ \bar f fˉ,它跟靶心是有一段距离的,如果是小的 bias 的话,意思是说你的 f ∗ f^* f 可能分散得很开,它分散得多开我们不管,你要找它的平均值,它的平均值呢,跟靶心是接近的,不管它散的多开,它的平均值跟靶心是接近的,这样叫 small bias,说到这边的时候,我就卡住啦,我为什么卡住了呢?

因为我想要量:不同 function 间的 bias 有多大,那仔细想想根本没有办法量这件事情,因为我根本不知道那个 f ^ \hat f f^ 长什么样子啊,所以我就卡住了这样子,所以我只好,胡乱自己假设一个 f ^ \hat f f^,假设说 f ^ \hat f f^ 就是长这条线这样子,所以我们的宝可梦 data 呢,宝可梦呢,就是从这条线 sample 出来的,那每次我们就 sample 10 个点出来,那你就可以找一个 f ∗ f^* f

好那这个呢,是实验的结果,黑色的线代表的是我们刚才在前一页投影片看到的,真正的 f ^ \hat f f^,就是你的靶心的位置是这条黑色的直线,红色的呢,代表了我们做 5000 次实验,所以假设是一次的 model,最简单的 model ,它长得有很多,有 5000 条直线在这边,你这边画出来就是红红的一大块,好,如果是蓝色的呢,蓝色代表说我们这个是 f ˉ \bar f fˉ,就是我们把 5000 个 f ∗ f^* f 平均起来变成 f ˉ \bar f fˉ, 就是蓝色的这条线,好,如果我们只考虑一次的话,你会发现说那 5000 条直线都差不多在这个地方,那他们的平均就是这条蓝色的线,那它跟黑色这个 f ^ \hat f f^,跟靶心是有一段差距的,如果你用 3 次式,它的头跟尾是很散的,但是如果你说平均找 f ˉ \bar f fˉ,也就是说蓝色这条线的话,你会发现说平均起来这个蓝色的线,跟黑色这个 f ^ \hat f f^,其实相对于这边,它是比较接近的,如果我们用 5 次式,那你就发现说 5000 条线画出来是这样, 你要不要干脆把整个图都涂红色这样,你会发现说这时候一切都有可能,那虽然这个地方你完全看不出来说,哇,到底有什么直线,通通涂成红色的,但是如果你把它平均起来,5 次式的曲线平均起来, 你会发现说,它得到的是这条蓝色的 f ˉ \bar f fˉ,它的 f ˉ \bar f fˉ 是这条蓝色的,它跟我们真正的 f ^ \hat f f^ 是接近的,虽然它每次都差很多,但平均起来以后,是接近的,所以呢,我们看到说,如果是一个比较简单的 model,它有比较大的 bias,如果是一个比较复杂的 model,每一次找出来的 f ∗ f^* f 都不一样,但它有比较小的 bias。

所以今天左边这个简单的 model 它的 case,就像是这个样子,每一次 f ∗ f^* f 都差不多,它的分布比较小,但是它跟靶心是有差距的,那这个 case,就像是这边这样子,每一次找出来的 f ∗ f^* f 都不太一样,但平均而言,是在靶心附近,为什么会这样子,我试着直观的解释给大家听,我们说,我们的 model 就是一个 function set 对不对,那我们就用一个范围呢,来表示这个 function set,当你定一个 model 的时候,你就已经设定好说,你最好的 function 就只能从那个 function set 里面挑出来,如果是一个简单的 model,它的 space 是比较小,所以这个比较小的 space, 它可能根本就没有包含你的 target,如果再没有包含 target 的情况下,你从这里面,不管怎么 sample,你平均起来都不会是这个 target 啊,因为你的这个 function set 里面根本就没有包含那个 target 啊,但是如果今天你的 model 呢,是比较复杂的,你的 model 所代表的这个 function space,我们上次有讲过说你从 1 次、2 次、3 次一直到 5 次,你的 function 是越来越复杂的,那简单的 function 是包含在复杂的 function 里面,所以如果你用 5 次的时候,这个时候呢,你的 function 的 space 是比较大,它可能有包含这个 target,只是它没有办法找出这个 target 在哪里,因为你给的 training data 不够,你给的 training data 每一次都不一样,所以它每次找出来的 f ∗ f^* f 都不一样,但如果它们是散布在这个 target 附近的,那平均起来呢,你就可以得到 f ˉ \bar f fˉ

好,所以我们回到我们上次看的那个 model,对这个 testing data, error 所画出来的线,我们刚才有讲说比较简单的 model,它就是 bias 比较大,但是 variance 比较小,比较复杂的 model,就是 bias 比较小,但 variance 比较大,所以今天这个图,由左到右,一方面呢,model 的 bias 是逐渐地下降,这是 bias 所造成的 error 是逐渐下降,也就是你瞄的越来越准,但是同时呢,这个 variance 是越来越大的,现在,虽然你每次瞄的越来越准,但是你每次射出去以后,你的误差是越来越大,所以当这两项同时被考虑的时候,你得到的就是蓝色这条线,蓝色这条线,也就是说,在某个地方,你可以找到一个平衡的点,让你同时考虑 bias 和 variance 的时候,你得到的 error 是越小,但是当你的 model 越来越复杂的时候,你的 variance 增长的比较快,所以你的 model 的 error 就变得很大,所以今天如果是一个 variance 大的情形,如果你的 error 来自于 variance 很大,这个状况呢,就是 Overfittng,如果今天你的 error 来自于 bias 很大,这个状况呢,叫做 Underfitting,所以今天假设你遇到一个 error 的时候,你自己做一些 implement,比如说你硕士论文用到 machine learning 的技术,你做完得到一个结果,然后你后面写了一些 future work,然后我都会问一个问题,如果你找我去考硕士、博士的话, 我都问这个问题,就是说,你觉得你现在的问题是 bias 大、还是 variance 大,你应该先知道这件事情,你才知道你的 future work,你要 improve 你的 model 的时候, 你应该要走哪一个方向,那怎么知道现在是 bias 大还是 variance 大呢?

好,什么时候 bias 大?如果今天你的 model 没有办法 fit 你的 training 的 examples,那代表说呢,你的 bias 是大的,就是如果我们只 sample 这几个蓝色的点,而你的 model even 没有 fit 这少数几个蓝色的点,代表说你的 model 跟正确的 model 是有一段差距的,所以这个时候是 Underfitting,这个时候是 bias 大的状况,如果今天是你在 training data 上,你可以 fit 你的 training data,你在 training data 上得到小的 error,但是在 testing data 上,你却得到一个大的 error,这意味著你的 model 可能是 variance 比较大,这个时候呢,代表的是 Overfitting,那遇到 bias 大跟 variance 大的时候,你其实是要用不同的方式来处理它们。

比如说,如果今天是 bias 大,那你要做的事情是什么呢?你应该去 redesign 你的 model,bias 大代表说,你现在这个 model 里面可能根本没有包含你的 target,你的 f ^ \hat f f^,它根本就不在你的 model set 里面,那你要怎么办呢?你要做的事情是:redesign 你的 model,比如说,你可能重写你 model 的式子,把更多的 feature 加进去,比如说只考虑 CP 值可能不够,你可能还要考虑 hp 值啊,或其他什么东西,或者是,你让你的 model 更复杂,本来只考虑 1 次不够,你可能要考虑 2 次、3 次等等,在这个状况下,因为是你的 model 不好,没有包含 f ^ \hat f f^,所以如果你今天你 error 差是来自 bias,那你不要说我去 collect 更多 data, collect 更多 data 是没有用的,今天这个状况下,collect 更多 data,你也不会有帮助,因为你的 model、你的 function set 本来就不好,再找更多的 data 下来,也不会有帮助。

好今天如果是另外一个 case,如果是 variance 大的话,那你应该怎么办呢?一个方法就是增加你的 data,那我们看刚才的例子,如果是 5 次式,找 100 个 f ^ \hat f f^,每次如果们只抓 10 只宝可梦的话,那我们找出来的式子,是这个样子的,找出来的 100 个 f ∗ f^* f 的散布是这个样子,但如果每次抓 100 只宝可梦的话,那 100 个 f ∗ f^* f,你会发现说他们非常的集中,他们几乎都集中在这个地方,所以增加 data 是一个很有效控制 variance 的方法,假如你 variance 太大的话,这个时候你要做的事情,collect data 几乎是一个,像是万能丹一样的东西,它不会伤害你的 bias,但是它有可造成你的问题就是,你在实际上你没有办法 collect 更多 data,对不对,在 practical,collect data 很麻烦啊, 你不见得能 collect 更多 data,不只在学校实验室没有办法,你可能以为在业界就可以说你要 collect 多少 data,其实你也不见得可以,比如说,有些人在业界想要做一些 AI 的东西,然后他就跟老板说,我要 collect 一万笔 labeled data,然后就被 reject,因为老板说这个,机器会自己学习,所以你不需要 labeled data,不是机器会自己学习吗?为甚么要 labeled data,就把他否决了这样子,所以在业界,不是你想要 collect data 就可以的,会有各种 review,尤其是你的高层又不知道 machine learning 是什么的时候,你就会很卡,所以有时候你根本就没有办法 collect data,所以你不见得能够这么做。

那如果你不能这么做,其实有一招,这招就是 generate 假的 training data,根据你对这个问题的理解,自己去制造更多 data,比如说,在做手写数字辨识的时候,有人会说,因为每个人手写的这个角度不一样,所以我把所有 training data 里面的数字都左转 15 度、右转 15 度,这样是可以,或者是做影像辨识,你只有一个从左边开过来的火车,没有从右边开过来的火车,怎么办?把整个图片翻转你就有从有右边开过来的火车啦,对不对,你可以把你的每张图片都左右颠倒,这样你就多一倍的 data 出来,或者是在语音辨识的时候,你说,你只有男生说你好,没有女生说大家好,那你就把那个男生的声音,用一个变声器把它转一下这样,就变女生的声音,女生的声音用变声器转, 就变男生的声音,你这 data 就多出来,而且是真的有人这么做的,或者是说,你说我只有这个 clean speech,你在录音室录的声音,可是我是要做真正的 detection,那是要让你在公车上用的,那怎么办?你就去公车上面,录一些杂讯,然后呢,加到你在录音室录的声音里面,你马上就有公车上面的杂讯了,所以你有各种方法可以用啦,比如说,还有人说,我今天要做 language understanding 的 task,那我今天要做 support 各种不同国家的 language understanding 的 task 的时候,我要做 10 种国家、我 10 种语言都要,那老板只给你英文的 data,它自己会学这样子,只给你英文的 data,它中文自己学就会学的会,那怎么办呢?你就可以做 translation,把英文通通硬翻成中文,结果还是跟你 trained 一样,所以有各种不同的做法。

好,那如果你没有办法 collect 更多data 的话,你还有这另外一招,叫 Regularization,这我们上次也有看到,就是我们在一个 loss function 后面呢,再加一个 term,这个 term 会希望你的参数,越少越好,也就是说希望你今天找出来的曲线呢,越平滑越好,然后那个新加的 term 前面可以有一个 weight,代表你希望你的曲线有多平滑,左边这个图是,没有加 Regularization 的 test,这个图跟这个图是一样的,如果你今天加了 Regularization 以后,因为你的所有曲线都会变平滑,本来这种怪怪的、很不平滑的曲线就不会再出现了,所有曲线呢,都集中在比较平滑的区域,都变成比较平滑的曲线,如果你再增加它的 weight 的话,再考虑要让你的曲线更平滑的话,那你得到的结果就是这样,所以如果你加了 Regularization 以后,你强迫所有的曲线都要比较平滑,所以这个时候呢,也会让你的 variance 变小,那这个时候,你会得到的一个可能的伤害就是,你有可能会伤害你的 bias,对不对,你调整了你的 function space,变成它只包含那些比较平滑的曲线,那你可能就没有办法包含你的 f ^ \hat f f^,那你可能就没有办法包含你的那个目标的 function,你就可能伤害了你的 bias,所以当你做 Regularization 的时候, 你要调整一下 Regularization 的 weight,在 variance 和 bias 之间呢,取得平衡。

好,所以我们现在会遇到的问题往往是这样,我们有很多个 model 可以选择,那在这还有很多的参数可以调, 比如说,Regularization 的 weight,那通常我们是在 bias 跟 variance 之间呢, 做一些 trade-off,做一些平衡,我们希望找一个 model,variance 够小、bias 也够小,这两个合起来,给我们最小的 testing data 的 error,我们通常需要选择一个最好的 model,但是以下这件事情,是你不该做的,或是你最好、就是你不要这么做,这个事情是怎样呢?

就是你手上有 training set 、有 testing set,然后接下来你想要知道说:model 1、2、3 里面,你应该选哪一个 model?你就分别用 model 1、2、3 呢,分别去找一个 best function,我们 train 出一个 model,train 出一个 function,好接下来你把它 apply 到 testing set 上面,model 1给你 error 0.9、model 2给你 error 0.7, model 3 给你 error 0.5,那很直觉的就是 model 3 最好这样子,但是,你现在可能的问题是,这 testing set 是你自己手上的 testing set,是你自己拿来衡量 model 好坏的 testing set,真正的 testing set 是你没有的,真正的 testing set 的时候呢,假设我们,今天把我做的宝可梦的预测,放到网路上这样,然后看看有没有人要用,那新进来的 data 我是从来没有看过的,那因为你在挑 model的时候,你考虑了你自己手上的这一笔 testing set,而你自己手上的这笔 testing set,它有一笔 bias,就是你手上这笔 testing set,它有自己的一个 bias,那现在讲的这个 bias 跟之前讲的 bias 是有一点难解释,是有关系,但意思略有不同,这个 testing set 有自己的 bias,所以你今天拿这个 testing set 来选这最好的 model 的时候,它在真正的 testing set 上,不见得是最好的 model,通常都是比较差的,所以你可能会得到的 error 是大于你在自己的 testing set 估测的 0.5。

这样讲什么自己的 testing set,你可能有一点困惑,那我们就直接拿我们的作业来举例,你手上有 training set,那你有 testing set,那 testing set 其实有两组,一组是 public set,一组是 private set,你今天上传你的结果到 Kaggle 的 leaderboard 的时候,你只能看到 public set 的分数, 你没有办法看到 private set 的分数,private 的分数要等到作业 deadline, 你没有办法再上传以后,你才会在一瞬间看到你 private set 的分数,你那个本来 ranking 上面秀的是 public 的分数,它一瞬间翻过来变成那个 private 的分数,然后,如果你今天做的是下面这个状况,我用我的 training data,train 了这三个 model,我想知道哪一个结果是最好的, 所以我把 3 个 model 的结果通通传到 Kaggle 上面,在 Leaderboard 上,它告诉我说, model 3 给我的 error 是最好的,你可能就觉得说,我做完了,我 beat the baseline !,但是,private set 你是看不到的啊,而 private set 的 error 通常是大于 public set 的 error 啊,所以你可能并没有 beat baseline,所以这是有可能发生的,在下周五,那个作业 deadline 的时候,你可能就这样,这个是有可能发生的,先跟大家讲一下, 你不要太沮丧这样子,比如说,第 3 名的搞不好现在排第 100,因为你知道,我是看得到 private set 的啦,我举个例子,搞不好前 5 名的可能是在 100 名也说不定,然后也有比较励志的故事,比如说现在第一名的, 他其实可在 40 几名这样,这个是真正的 example,这样你 40 几名的,你是不是就高兴了呢这样子,所以这个 public set 的结果,是不可靠的,所以,怎么做才是比较可靠的呢?

你要做的事,你要这样做就是 你要把你的 training set 分成两组,这两组呢,一组是真正拿来 train model,我们把它叫做 training set,另外一组,你不拿它来 train model,你拿它来选 model,你在这个 training set 上找出最好的 function f ∗ f^* f,然后才用 validation set 来选择你的 model,也就是你的做法应该是这样子,你决定说,我到底应该用 model 1, model 2, 还是 model 3,然后你把这 3 个 model, 用你的 training set 去 train 好以后,接着看一下,它们在 validation set 上的 performance,假设现在 model 3 的 performance 是最好的,那你可以直接把这个 model 3 的结果拿来 apply在 testing data 上,那如果你担心说,现在我把 training set 分成 training 跟 validation,感觉 training data 变少的话,那你可以这么做,已经决定 model 3 是最好的 model,你就定住用 model 3,但是用全部的 data 在 model 3 上面再 train 一次,这样你就可以使用全部的 training data,这个时候,如果你把这个 model,apply 到 public set 上面,你可能会得到一个大于 0.5 的 error,虽然这么做,你得到的 error 表面上看起来是比较大的,但是这个时候,你在 public set 上面的 error,才能够真正反映你在 private set 上的 error,这样大家了解我的意思吗?

当然我可以了解有一种状况是,几乎没有办法,就是在你的心情上,基本上没有办法避免,不建议你这么做就是,因为通常你看到你的,public set 上的结果太差, 你就会想说回头再去找些什么东西,那基本上是不建议你这么做,因为如果你回头再去搞点什么东西的话,你就变成又把这个 public testing set 的 bias 考虑进去了,这样会变成说,你在这个 public testing set 上,所看到的 performance 没有办法反映,你在 private set 上看到的 performance,但我知道说在心情上,你几乎没有办法把持得住不这么做,你可能看到说小毛 ranking 在前面,所以你就会想到说我再弄一个结果,摆在它前面这样子,那其实你可以等 private set 真正出来的时候,你搞不好就 rank 它前面这样子,所以 public set 并不是最终的结果,那比如说,你看你在发 paper 的时候,有时候你会 propose 一个方法,那你要 attach 在 benchmark 的 corpus,当你要 attach 在 benchmark 的 corpus 上面的时候,如果你在 testing set 得到一个差的结果,你也几乎没有办法把持自己,不回头去调整一下你的 model 这样子,你不会说,我在 testing set 上得到一个差的结果,只是写一个 paper 告诉他说这个方法不 work 这样子,你就会回头去,因为搞点东、搞点西,然后硬是在 testing set 上把结果做起来,你几乎没有办法避免做这件事情啦,那所以我想你能够做的事情就是,你要 keep in mind,如果在那个 benchmark corpus 上面,所看到的 testing 的 performance,它的 error,你可以说是假的,或者是它大于在 real 的 application 上应该有的值,比如说你现在常常听到说,在 imagenet 的那个 corpus 上面,error rate 都降到 3%,那个是超越人类,但是,真的是这样子吗?已经有这么多人玩过这个 corpus,它已经有这么多人试过告诉你说,前面那些方法都不 work,他们都帮你挑过 model 了,你已经用 testing set 调过参数了,所以,如果你把那些 model 真的 apply 到现实生活中,它的 error rate 应该会是大于 3%,好,那有人会担心说,我这个分,如果分坏了怎么办?分坏了,就是说如果这个 validation set 其实也有怪怪的 bias,怎么办呢?那你可以做下面这件事啦,这件事情是:N-fold Cross Validation。

也就是说,如果你不相信某一次分,train 跟 test 的结果的话,那你就分很多种不同的样子,比如说,如果你做 3-fold 的 validation,意思就是,你把你的 training set 分成 3 份,你每一次拿其中一份当做 validation set,另外两份做 training,你拿某一份当 validation set,另外两份当 training,接下来呢,如果你要知道 model 1, 2, 3 哪一份比较好的话,你就把这 3 个 model 通通在这一个情境下,由这两个 set 做 training ,这个做 validation 的情境下,算一下它的 error,你在这个情境下,算一下它的 error,然后你算一下它的 average error,然后你会发现说,在这 3 个情况下的 average,是 model 1 最好,然后接下来呢, 你就把 model 1再 train 在你完整的 training set 上面,然后,再去 test 在你的 testing set 上面,那原则上就是,如果你少去太在意你在 public set,就是少去根据它调整你的 model 的话,你往往会在 private set上面,得到的差距和 testing set 是比较小的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

李宏毅 机器学习 2016 秋:4、bias vs variance 的相关文章

随机推荐