Datawhale X 李宏毅苹果书 AI夏令营task1-3笔记

2024-08-24 10:12

本文主要是介绍Datawhale X 李宏毅苹果书 AI夏令营task1-3笔记,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.1 通过案例了解机器学习

机器学习基础

  首先简单介绍一下机器学习(Machine Learning,ML)和深度学习(Deep Learning,DL)的基本概念。机器学习,顾名思义,机器具备有学习的能力。具体来讲,机器学习就是让机器具备找一个函数的能力。机器具备找函数的能力以后,它可以做很多事。比如语音识别,机器听一段声音,产生这段声音对应的文字。我们需要的是一个函数,该函数的输入是声音信号,输出是这段声音信号的内容。这个函数显然非常复杂,人类难以把它写出来,因此想通过机器的力量把这个函数自动找出来。还有好多的任务需要找一个很复杂的函数,以图像识别为例,图像识别函数的输入是一张图片,输出是这个图片里面的内容。AlphaGo 也可以看作是一个函数,机器下围棋需要的就是一个函数,该函数的输入是棋盘上黑子跟白子的位置,输出是机器下一步应该落子的位置。

  随着要找的函数不同,机器学习有不同的类别。假设要找的函数的输出是一个数值,一个标量(scalar),这种机器学习的任务称为回归。举个回归的例子,假设机器要预测未来某一个时间的 PM2.5 的数值。机器要找一个函数 f,其输入是可能是种种跟预测 PM2.5 有关的指数,包括今天的 PM2.5 的数值、平均温度、平均的臭氧浓度等等,输出是明天中午的 PM2.5的数值,找这个函数的任务称为回归(regression)。

  除了回归以外,另一个常见的任务是分类(classification,)。分类任务要让机器做选择题。人类先准备好一些选项,这些选项称为类别(class),现在要找的函数的输出就是从设定好的选项里面选择一个当作输出,该任务称为分类。举个例子,每个人都有邮箱账户,邮箱账户里面有一个函数,该函数可以检测一封邮件是否为垃圾邮件。分类不一定只有两个选项,也可以有多个选项。

  AlphaGo 也是一个分类的问题,如果让机器下围棋,做一个 AlphaGo,给出的选项与棋盘的位置有关。棋盘上有 19 × 19 个位置,机器下围棋其实是一个有 19 × 19 个选项的选择题。机器找一个函数,该函数的输入是棋盘上黑子跟白子的位置,输出就是从 19×19 个选项里面,选出一个正确的选项,从 19 × 19 个可以落子的位置里面,选出下一步应该要落子的位置。在机器学习领域里面,除了回归跟分类以外,还有结构化学习(structured learning)。机器不只是要做选择题或输出一个数字,而是产生一个有结构的物体,比如让机器画一张图,写一篇文章。这种叫机器产生有结构的东西的问题称为结构化学习。

1.1 案例学习

  以视频的点击次数预测为例介绍下机器学习的运作过程。假设有人想要通过视频平台赚钱,他会在意频道有没有流量,这样他才会知道他的获利。假设后台可以看到很多相关的信息,比如:每天点赞的人数、订阅人数、观看次数。根据一个频道过往所有的信息可以预测明天的观看次数。找一个函数,该函数的输入是后台的信息,输出是隔天这个频道会有的总观看的次数.

  机器学习找函数的过程,分成 3 个步骤。第一个步骤是写出一个带有未知参数的函数 f,其能预测未来观看次数。比如将函数写成

y = b + wx1                                                                   (1.1)

  其中,y 是准备要预测的东西,要预测的是今天(2 月 26 日)这个频道总共观看的人,y 就假设是今天总共的观看次数。x1 是这个频道,前一天(2 月 25 日)总共的观看次数,y 跟 x1 都是数值,b 跟 w 是未知的参数,它是准备要通过数据去找出来的,w 跟 b 是未知的,只是隐约地猜测。猜测往往来自于对这个问题本质上的了解,即领域知识(domain knowledge)。机器学习就需要一些领域知识。这是一个猜测,也许今天的观看次数,总是会跟昨天的观看次数有点关联,所以把昨天的观看次数,乘上一个数值,但是总是不会一模一样,所以再加上一个 b 做修正,当作是对于 2 月 26 日,观看次数的预测,这是一个猜测,它不一定是对的,等一下回头会再来修正这个猜测。总之,y = b + w ∗ x1,而 b 跟 w 是未知的。带有未知的参数(parameter)的函数称为模型(model)。模型在机器学习里面,就是一个带有未知的参数的函数,特征(feature) x1 是这个函数里面已知的,它是来自于后台的信息,2 月 25 日点击的总次数是已知的,而 w 跟 b 是未知的参数。w 称为权重(weight),b 称为偏置(bias)。这个是第一个步骤。

  第 2 个步骤是定义损失(loss),损失也是一个函数。这个函数的输入是模型里面的参数,模型是 y = b + w ∗ x1,而 b 跟 w 是未知的,损失是函数 L(b, w),其输入是模型参数 b 跟w。损失函数输出的值代表,现在如果把这一组未知的参数,设定某一个数值的时候,这笔数值好还是不好。举一个具体的例子,假设未知的参数的设定是 b = 500,w = 1,预测未来的观看次数的函数就变成 y = 500 + x1。要从训练数据来进行计算损失,在这个问题里面,训练数据是这一个频道过去的观看次数。举个例子,从 2017 年 1 月 1 日到 2020 年 12 月 31 日的观看次数(此处的数字是随意生成的)如图 1.1 所示,接下来就可以计算损失。

把 2017 年 1 月 1 日的观看次数,代入这一个函数里面

yˆ = 500 + 1x1                                                           (1.2)

可以判断 b = 500,w = 1 的时候,这个函数有多棒。x1 代入 4800,预测隔天实际上的观看次数结果为 yˆ = 5300,真正的结果是 4900,真实的值称为标签(label),它高估了这个频道可能的点击次数,可以计算一下估测的值 yˆ 跟真实值 y 的差距 e。计算差距其实不只一种方式,比如取绝对值:

e1 = |y − yˆ| = 400                                                       (1.3)

我们不是只能用 1 月 1 日,来预测 1 月 2 日的值,可以用 1 月 2 日的值,来预测 1 月 3日的值。根据 1 月 2 日的观看次数,预测的 1 月 3 日的观看次数的,值是 5400。接下来计算5400 跟跟标签(7500)之间的差距,低估了这个频道。在 1 月 3 日的时候的观看次数,才可以算出:

e2 = |y − yˆ| = 2100                                                      (1.4)

我们可以算过这 3 年来,每一天的预测的误差,这 3 年来每一天的误差,通通都可以算出来,每一天的误差都可以得到 e。接下来把每一天的误差,通通加起来取得平均,得到损失L

其中,N 代表训验数据的个数,即 3 年来的训练数据,就 365 乘以 3,计算出一个 L,,L 是每一笔训练数据的误差 e 相加以后的结果。L 越大,代表现在这一组参数越不好,L 越小,代表现在这一组参数越好。估测的值跟实际的值之间的差距,其实有不同的计算方法,计算 y 与 yˆ 之间绝对值的差距,如式 (1.6) 所示,称为平均绝对误差(Mean Absolute Error,MAE)。

e = |yˆ − y|                                                              (1.6)

如果算 y 与 yˆ 之间平方的差距,如式 (1.7) 所示,则称为均方误差(Mean SquaredError,MSE)。

e = (ˆy − y)2                                                                    (1.7)

  有一些任务中 y 和 yˆ 都是概率分布,这个时候可能会选择交叉熵(cross entropy),这个是机器学习的第 2 步。刚才举的那些数字不是真正的例子,以下的数字是真实的例子,是这个频道真实的后台的数据,所计算出来的结果。可以调整不同的 w 和不同的 b,求取各种w 和各种 b,组合起来以后,我们可以为不同的 w 跟 b 的组合,都去计算它的损失,就可以画出图 1.2 所示的等高线图。在这个等高线图上面,越偏红色系,代表计算出来的损失越大,就代表这一组 w 跟 b 越差。如果越偏蓝色系,就代表损失越小,就代表这一组 w 跟 b 越好,拿这一组 w 跟 b,放到函数里面,预测会越精准。假设 w = −0.25, b = −500,这代表这个频道每天看的人越来越少,而且损失这么大,跟真实的情况不太合。如果 w = 0.75, b = 500,估测会比较精准。如果 w 代一个很接近 1 的值,b 带一个小小的值,比如说 100 多,这个时候估测是最精准的,这跟大家的预期可能是比较接近的,就是拿前一天的点击的总次数,去预测隔天的点击的总次数,可能前一天跟隔天的点击的总次数是差不多的,因此 w 设 1,b 设一个小一点的数值,也许估测就会蛮精准的。如图 1.2 所示的等高线图,就是试了不同的参数,计算它的损失,画出来的等高线图称为误差表面(error surface)。这是机器学习的第 2 步。

  接下来进入机器学习的第 3 步:解一个最优化的问题。找一个 w 跟 b,把未知的参数找一个数值出来,看代哪一个数值进去可以让损失 L 的值最小,就是要找的 w 跟 b,这个可以让损失最小的 w 跟 b 称为 w∗ 跟 b∗ 代表它们是最好的一组 w 跟 b,可以让损失的值最小。梯度下降(gradient descent)是经常会使用优化的方法。为了要简化起见,先假设只有一个未知的参数 w,b 是已知的。w 代不同的数值的时候,就会得到不同的损失,这一条曲线就是误差表面,只是刚才在前一个例子里面,误差表面是 2 维的,这边只有一个参数,所以这个误差表面是 1 维的。怎么样找一个 w 让损失的值最小呢? 如图 1.3 所示,首先要随机选取一个初始的点 w0。接下来计算 ∂L∂w |w=w0,在 w 等于 w0 的时候,参数 w 对损失的微分。计算在这一个点,在 w0 这个位置的误差表面的切线斜率,也就是这一条蓝色的虚线,它的斜率,如果这一条虚线的斜率是负的,代表说左边比较高,右边比较低。在这个位置附近,左边比较高,右边比较低。如果左边比较高右边比较低的话,就把 w 的值变大,就可以让损失变小。如果算出来的斜率是正的,就代表左边比较低右边比较高。左边比较低右边比较高,如果左边比较低右边比较高的话,就代表把 w 变小了,w 往左边移,可以让损失的值变小。这个时候就应该把 w 的值变小。我们可以想像说有一个人站在这个地方,他左右环视一下,算微分就是左右环视,它会知道左边比较高还是右边比较高,看哪边比较低,它就往比较低的地方跨出一步。这一步的步伐的大小取决于两件事情:

• 第一件事情是这个地方的斜率,斜率大步伐就跨大一点,斜率小步伐就跨小一点。

• 另外,学习率(learning rate)η 也会影响步伐大小。学习率是自己设定的,如果 η 设大一点,每次参数更新就会量大,学习可能就比较快。如果 η 设小一点,参数更新就很慢,每次只会改变一点点参数的数值。这种在做机器学习,需要自己设定,不是机器自己找出来的,称为超参数(hyperparameter)。

Q: 为什么损失可以是负的?A: 损失函数是自己定义的,在刚才定义里面,损失就是估测的值跟正确的值的绝对值。如果根据刚才损失的定义,它不可能是负的。但是损失函数是自己决定的,比如设置一个损失函数为绝对值再减 100,其可能就有负的。这个曲线并不是一个真实的损失,并不是一个真实任务的误差表面。因此这个损失的曲线可以是任何形状。

把 w0 往右移一步,新的位置为 w1,这一步的步伐是 η 乘上微分的结果,即:

接下来反复进行刚才的操作,计算一下 w1 微分的结果,再决定现在要把 w1 移动多少,再移动到 w2,再继续反复做同样的操作,不断地移动 w 的位置,最后会停下来。往往有两种情况会停下来。

• 第一种情况是一开始会设定说,在调整参数的时候,在计算微分的时候,最多计算几次。上限可能会设为 100 万次,参数更新 100 万次后,就不再更新了,更新次数也是一个超参数。

• 还有另外一种理想上的,停下来的可能是,当不断调整参数,调整到一个地方,它的微分的值就是这一项,算出来正好是 0 的时候,如果这一项正好算出来是 0,0 乘上学习率 η 还是 0,所以参数就不会再移动位置。假设是这个理想的情况,把 w0 更新到 w1,再更新到 w2,最后更新到 wT 有点卡,wT 卡住了,也就是算出来这个微分的值是 0 了,参数的位置就不会再更新。

梯度下降有一个很大的问题,没有找到真正最好的解,没有找到可以让损失最小的 w。在图 1.4 所示的例子里面,把 w 设定在最右侧红点附近这个地方可以让损失最小。但如果在梯度下降中,w0 是随机初始的位置,也很有可能走到 wT 这里,训练就停住了,无法再移动 w 的位置。右侧红点这个位置是真的可以让损失最小的地方,称为全局最小值(global minima),而 wT 这个地方称为局部最小值(local minima),其左右两边都比这个地方的损失还要高一点,但是它不是整个误差表面上面的最低点。

   所以常常可能会听到有人讲到梯度下降不是个好方法,这个方法会有局部最小值的问题,无法真的找到全局最小值。事实上局部最小值是一个假问题,在做梯度下降的时候,真正面对的难题不是局部最小值。有两个参数的情况下使用梯度下降,其实跟刚才一个参数没有什么不同。如果一个参数没有问题的话,可以很快的推广到两个参数。

   假设有两个参数,随机初始值为 w0, b0。要计算 w, b 跟损失的微分,计算在 w = w0 的位置,b = b0 的位置,要计算 w 对 L 的微分,计算 b 对 L 的微分

计算完后更新 w 跟 b,把 w0 减掉学习率乘上微分的结果得到 w1,把 b0 减掉学习率乘上微分的结果得到 b1。

在深度学习框架里面,比如 PyTorch 里面,算微分都是程序自动帮计算的。就是反复同样的步骤,就不断的更新 w 跟 b,期待最后,可以找到一个最好的 w,w∗ 跟最好的 b∗. 如图 1.5 所示,随便选一个初始的值,先计算一下 w 对 L 的微分,跟计算一下 b 对 L 的微分,接下来更新 w 跟 b,更新的方向就是 ∂L/∂w,乘以 η 再乘以一个负号,∂L/∂b,算出这个微分的值,就可以决定更新的方向,可以决定 w 要怎么更新。把 w 跟 b 更新的方向结合起来,就是一个向量,就是红色的箭头,再计算一次微分,再决定要走什么样的方向,把这个微分的值乘上学习率,再乘上负号,我们就知道红色的箭头要指向那里,就知道如何移动 w 跟 b 的位置,一直移动,期待最后可以找出一组不错的 w, b。实际上真的用梯度下降,进行一番计算以后,这个是真正的数据,算出来的最好的 w∗ = 0.97, b∗ = 100,跟猜测蛮接近的。因为x1 的值可能跟 y 很接近,所以这个 w 就设一个接近 1 的值,b 就设一个比较偏小的值。损失 L(w∗, b∗) 算一下是 480,也就是在 2017 到 2020 年的数据上,如果使用这一个函数,b 代100,w 代 0.97,平均的误差是 480,其预测的观看次数误差,大概是 500 人左右。

---------------------------------------------------------------------------------------------------------------------------------

1.2 了解线性模型

1.2 线性模型

   w 跟 b 的值刚才已经找出来的,这组 w 跟 b 可以让损失小到 480。在已经知道答案的数据上去计算损失,2017 到 2020 年每天的观看次数是已知的。所以假装不知道隔天的观看次数,拿这一个函数来进行预测,发现误差是 480。接下来使用这个函数预测未来的观看次数。预测从 2021 年开始每一天都拿这个函数去预测次日的观看人次:用 2020 年的 12 月 31 日的观看人次预测 2021 年 1 月 1 日的观看人次,用 2021 年 1 月 1 日的观看人次预测 1 月 2 日的观看人次,用 1 月 2 日的观看人次去预测 1 月 3 日的观看人次⋯⋯每天都做这件事,一直做到 2 月 14 日,得到平均的值,在 2021 年没有看过的数据上,误差值用 L′ 来表示,它是0.58,所以在有看过的数据上,在训练数据上,误差值是比较小的,在没有看过的数据上,在2021 年的数据上,看起来误差值是比较大的,每一天的平均误差有 580 人左右,600 人左右。如图 1.6 所示,横轴是代表的是时间,所以 0 这个点代表的是 2021 年 1 月 1 日,最右边点代表的是 2021 年 2 月 14 日,纵轴就是观看的人次,这边是用千人当作单位。红色线是真实的观看人次,蓝色线是机器用这一个函数预测出来的观看人次。蓝色的线几乎就是红色的线往右平移一天而已,这很合理,因为 x1 也就是前一天的观看人次,跟隔天观看人次的,要怎么拿前一天的观看人次,去预测隔天的观看人次呢,前一天观看人次乘以 0.97,加上 100 加上100,就是隔天的观看人次。机器几乎就是拿前一天的观看人次来预测隔天的观看人次。这个真实的数据有一个很神奇的现象,它是有周期性的,它每隔 7 天就会有两天特别低(周五和周六),两天观看的人特别少,每隔 7 天,就是一个循环。目前的模型不太行,它只能够看前一天。 每隔 7 天它一个循环,如果一个模型参考前 7 天的数据,把 7 天前的数据,直接复制到拿来当作预测的结果,也许预测的会更准也说不定,所以我们就要修改一下模型。通常一个模型的修改,往往来自于对这个问题的理解,即领域知识。

一开始,对问题完全不理解的时候,胡乱写一个

y = b + wx1                                                              (1.11)

并没有做得特别好。接下来我们观察了真实的数据以后,得到一个结论是,每隔 7 天有一个循环。所以要把前 7 天的观看人次都列入考虑,写了一个新的模型

其中 xj 代表第 j 天的观看测试,也就是 7 天前的数据,通通乘上不同的权重 wj,加起来,再加上偏置得到预测的结果。使用该模型预测,其在训练数据上的损失是 380,而只考虑 1 天的模型在训练数据上的损失是 480。因为其考虑了 7 天,所以在训练数据上会得到比较低的损失。考虑了比较多的信息,在训练数据上应该要得到更好的、更低的损失。在没有看到的数据上的损失有比较好是 490。只考虑 1 天的误差是 580,考虑 7 天的误差是 490。用梯度下降,算出 w 跟 b 的最优值如 表 1.1 所示。

机器的逻辑是前一天跟要预测的隔天的数值的关系很大,所以 w∗1 是 0.79,不过它知道,如果是前两天前四天前五天,它的值会跟未来要预测的,隔天的值是成反比的,所以 w2, w4, w5最佳的值(让训练数据上的损失为 380 的值)是负的。但是 w1, w3, w6, w7 是正的,考虑前 7天的值,其实可以考虑更多天,本来是考虑前 7 天,可以考虑 28 天,即

28 天是一个月,考虑前一个月每一天的观看人次,去预测隔天的观看人次,训练数据上是 330。在 2021 年的数据上,损失是 460,看起来又更好一点。如果考虑 56 天,即

在训练数据上损失是 320,在没看过的数据上损失还是 460。考虑更多天没有办法再更降低损失了。看来考虑天数这件事,也许已经到了一个极限。这些模型都是把输入的特征 x 乘上一个权重,再加上一个偏置就得到预测的结果,这样的模型称为线性模型(linear model)。接下来会看如何把线性模型做得更好。

1.2.1 分段线性曲线

  线性模型也许过于简单,x1 跟 y 可能中间有比较复杂的关系,如图 1.7 所示。对于线性模型,x1 跟 y 的关系就是一条直线,随着 x1 越来越高,y 就应该越来越大。设定不同的 w可以改变这条线的斜率,设定不同的 b 可以改变这一条蓝色的直线跟 y 轴的交叉点。但是无论如何改 w 跟 b,它永远都是一条直线,永远都是 x1 越大,y 就越大,前一天观看的次数越多,隔天的观看次数就越多。但现实中也许在 x1 小于某一个数值的时候,前一天的观看次数跟隔天的观看次数是成正比;也许当 x1 大于一个数值的时候,x1 太大,前天观看的次数太高,隔天观看次数就会变少;也许 x1 跟 y 中间,有一个比较复杂的、像红色线一样的关系。但不管如何设置 w 跟 b,永远制造不出红色线,永远无法用线性模型制造红色线。显然线性模型有很大的限制,这一种来自于模型的限制称为模型的偏差,无法模拟真实的情况。

  所以需要写一个更复杂的、更有灵活性的、有未知参数的函数。红色的曲线可以看作是一个常数再加上一群 Hard Sigmoid 函数。Hard Sigmoid 函数的特性是当输入的值,当 x 轴的值小于某一个阈值(某个定值)的时候,大于另外一个定值阈值的时候,中间有一个斜坡。所以它是先水平的,再斜坡,再水平的。所以红色的线可以看作是一个常数项加一大堆的蓝色函数(Hard Sigmoid)。常数项设成红色的线跟 x 轴的交点一样大。常数项怎么加上蓝色函数后,变成红色的这一条线? 蓝线 1 函数斜坡的起点,设在红色函数的起始的地方,第 2 个斜坡的终点设在第一个转角处,让第 1 个蓝色函数的斜坡和红色函数的斜坡的斜率是一样的,这个时候把 0+1 就可以得到红色曲线左侧的线段。接下来,再加第 2 个蓝色的函数,所以第2 个蓝色函数的斜坡就在红色函数的第一个转折点到第 2 个转折点之间,让第 2 个蓝色函数

的斜率跟红色函数的斜率一样,这个时候把 0+1+2,就可以得到红色函数左侧和中间的线段。接下来第 3 个部分,第 2 个转折点之后的部分,就加第 3 个蓝色的函数,第 3 个蓝色的函数坡度的起始点设的跟红色函数转折点一样,蓝色函数的斜率设的跟红色函数斜率一样,接下来把 0+1+2+3 全部加起来,就得到完整红色的线。

所以红色线,即分段线性曲线(piecewise linear curve)可以看作是一个常数,再加上一堆蓝色的函数。分段线性曲线可以用常数项加一大堆的蓝色函数组合出来,只是用的蓝色函数不一定一样。要有很多不同的蓝色函数,加上一个常数以后就可以组出这些分段线性曲线。如果分段线性曲线越复杂,转折的点越多,所需的蓝色函数就越多。

也许要考虑的 x 跟 y 的关系不是分段线性曲线,而是如图 1.9 所示的曲线。可以在这样的曲线上面,先取一些点,再把这些点点起来,变成一个分段线性曲线。而这个分段线性曲线跟原来的曲线,它会非常接近,如果点取的够多或点取的位置适当,分段线性曲线就可以逼近这一个连续的曲线,就可以逼近有角度的、有弧度的这一条曲线。 所以可以用分段线性曲线去逼近任何的连续的曲线,而每个分段线性曲线都可以用一大堆蓝色的函数组合起来。也就是说,只要有足够的蓝色函数把它加起来,就可以变成任何连续的曲线。

假设 x 跟 y 的关系非常复杂也没关系,就想办法写一个带有未知数的函数。直接写 HardSigmoid 不是很容易,但是可以用一条曲线来理解它,用 Sigmoid 函数来逼近 Hard Sigmoid,如图 1.10 所示。Sigmoid 函数的表达式为

   如果 x1 的值,趋近于无穷大的时候,e−(b+wx1) 这一项就会消失,当 x1 非常大的时候,这一条就会收敛在高度为 c 的地方。如果 x1 负的非常大的时候,分母的地方就会非常大,y的值就会趋近于 0。

   所以可以用这样子的一个函数逼近这一个蓝色的函数,即 Sigmoid 函数,Sigmoid 函数就是 S 型的函数。因为它长得是有点像是 S 型,所以叫它 Sigmoid 函数。

   为了简洁,去掉了指数的部分,蓝色函数的表达式为

y = cσ(b + wx1)                                                      (1.15)

所以可以用 Sigmoid 函数逼近 Hard Sigmoid 函数。

调整这里的 b、w 和 c 可以制造各种不同形状的 Sigmoid 函数,用各种不同形状的 Sigmoid函数去逼近 Hard Sigmoid 函数。如图 1.11 所示,如果改 w,就会改变斜率,就会改变斜坡的坡度。如果改了 b,就可以把这一个 Sigmoid 函数左右移动;如果改 c,就可以改变它的高度。所以只要有不同的 w 不同的 b 不同的 c,就可以制造出不同的 Sigmoid 函数,把不同的Sigmoid 函数叠起来以后就可以去逼近各种不同的分段线性函数;分段线性函数可以拿来近似各种不同的连续的函数。

如图 1.12 所示,红色这条线就是 0 加 1+2+3,而 1、2、3 都是蓝色的函数,其都可写成 (b + wx1),去做 Sigmoid 再乘上 ci1,只是 1、2、3 的 w、b、c 不同。

   所以这边每一个式子都代表了一个不同蓝色的函数,求和就是把不同的蓝色的函数相加,再加一个常数 b。假设里面的 b 跟 w 跟 c,它是未知的,它是未知的参数,就可以设定不同的b 跟 w 跟 c,就可以制造不同的蓝色的函数,制造不同的蓝色的函数叠起来以后,就可以制造出不同的红色的曲线,就可以制造出不同的分段线性曲线,逼近各式各样不同的连续函数。

   此外,我们可以不只用一个特征 x1,可以用多个特征代入不同的 c, b, w,组合出各种不同的函数,从而得到更有灵活性(flexibility)的函数,如图 1.13 所示。用 j 来代表特征的编号。如果要考虑前 28 天,j 就是 1 到 28。

   直观来讲,先考虑一下 j 就是 1、2、3 的情况,就是只考虑 3 个特征。举个例子,只考虑前一天、前两天跟前 3 天的情况,所以 j 等于 1,2,3,所以输入就是 x1 代表前一天的观看

次数,x2 两天前观看次数,x3 3 天前的观看次数,每一个 i 就代表了一个蓝色的函数。每一个蓝色的函数都用一个 Sigmoid 函数来比近似它,1,2,3 代表有个 Sigmoid 函数。

b1 + w11x1 + w12x2 + w13x3                                               (1.18)

wij 代表在第 i 个 Sigmoid 里面,乘给第 j 个特征的权重,w 的第一个下标代表是现在在考虑的是第一个 Sigmoid 函数。为了简化起见,括号里面的式子为

接下来,如图 1.15 所示,x 是特征,绿色的 b 是一个向量,灰色的 b 是一个数值。W, b, cT, b是未知参数。把这些东西通通拉直,“拼”成一个很长的向量,我们把 W 的每一行或者是每一列

拿出来。无论是拿行或拿列都可以,把 W 的每一列或每一行“拼”成一个长的向量,把 b, cT, b” 拼” 上来,这个长的向量直接用 θ 来表示。所有的未知的参数,一律统称 θ。

Q: 优化是找一个可以让损失最小的参数,是否可以穷举所有可能的未知参数的值?A:只有 w 跟 b 两个参数的前提之下,可以穷举所有可能的 w 跟 b 的值,所以在参数很少的情况下。甚至可能不用梯度下降,不需要优化的技巧。但是参数非常多的时候,就不能使用穷举的方法,需要梯度下降来找出可以让损失最低的参数。

Q:刚才的例子里面有 3 个 Sigmoid,为什么是 3 个,能不能 4 个或更多?A:Sigmoid 的数量是由自己决定的,而且 Sigmoid 的数量越多,可以产生出来的分段线性函数就越复杂。Sigmoid 越多可以产生有越多段线的分段线性函数,可以逼近越复杂的函数。Sigmoid 的数量也是一个超参数。

接下来要定义损失。之前是 L(w, b),因为 w 跟 b 是未知的。现在未知的参数很多了,再把它一个一个列出来太累了,所以直接用 θ 来统设所有的参数,所以损失函数就变成 L(θ)。损失函数能够判断 θ 的好坏,其计算方法跟刚才只有两个参数的时候是一样的。

先给定 θ 的值,即某一组 W, b, cT, b 的值,再把一种特征 x 代进去,得到估测出来的 y,再计算一下跟真实的标签之间的误差 e。把所有的误差通通加起来,就得到损失。

接下来下一步就是优化

要找到 θ 让损失越小越好,可以让损失最小的一组 θ 称为 θ∗。一开始要随机选一个初始

的数值 θ0。接下来计算每一个未知的参数对 L 的微分,得到向量 g,即可以让损失变低的函数

假设有 1000 个参数,这个向量的长度就是 1000,这个向量也称为梯度,∇L 代表梯度。L(θ0) 是指计算梯度的位置,是在 θ 等于 θ0 的地方。计算出 g 后,接下来跟新参数,θ0 代表它是一个起始的值,它是一个随机选的起始的值,代表 θ1 更新过一次的结果,θ02 减掉微分乘以,减掉 η 乘上微分的值,得到 θ12,以此类推,就可以把 1000 个参数都更新了。

假设参数有 1000 个,θ0 就是 1000 个数值,1000 维的向量,g 是 1000 维的向量,θ1 也是 1000 维的向量。 整个操作就是这样,由 θ0 算梯度,根据梯度去把 θ0 更新成 θ1,再算一次梯度,再根据梯度把 θ1 再更新成 θ2,再算一次梯度把 θ2 更新成 θ3,以此类推,直到不想做。或者计算出梯度为 0 向量,导致无法再更新参数为止,不过在实现上几乎不太可能梯度为 0,通常会停下来就是我们不想做了。

但实现上有个细节的问题,实际使用梯度下降的时候,如图 1.17 所示,会把 N 笔数据随机分成一个一个的批量(batch),一组一组的。每个批量里面有 B 笔数据,所以本来有 N笔数据,现在 B 笔数据一组,一组叫做批量。本来是把所有的数据拿出来算一个损失,现在只拿一个批量里面的数据出来算一个损失,记为 L1 跟 L 以示区别。假设 B 够大,也许 L 跟L1 会很接近。所以实现上每次会先选一个批量,用该批量来算 L1,根据 L1 来算梯度,再用梯度来更新参数,接下来再选下一个批量算出 L2,根据 L2 算出梯度,再更新参数,再取下一个批量算出 L3,根据 L3 算出梯度,再用 L3 算出来的梯度来更新参数。

所以并不是拿 L 来算梯度,实际上是拿一个批量算出来的 L1, L2, L3 来计算梯度。把所有的批量都看过一次,称为一个回合(epoch),每一次更新参数叫做一次更新。更新跟回合是不同的东西。每次更新一次参数叫做一次更新,把所有的批量都看过一遍,叫做一个回合。

更新跟回合的差别,举个例子,假设有 10000 笔数据,即 N 等于 10000,批量的大小是设 10,也就 B 等于 10。10000 个样本(example)形成了 1000 个批量,所以在一个回合里面更新了参数 1000 次,所以一个回合并不是更新参数一次,在这个例子里面一个回合,已经更新了参数 1000 次了。

第 2 个例子,假设有 1000 个数据,批量大小(batch size)设 100,批量大小和 Sigmoid的个数都是超参数。1000 个样本,批量大小设 100,1 个回合总共更新 10 次参数。所以做了一个回合的训练其实不知道它更新了几次参数,有可能 1000 次,也有可能 10 次,取决于它的批量大小有多大。

1.2.2 模型变形

    其实还可以对模型做更多的变形,不一定要把 Hard Sigmoid 换成 Soft Sigmoid。HardSigmoid 可以看作是两个修正线性单元(Rectified Linear Unit,ReLU)的加总,ReLU 的图像有一个水平的线,走到某个地方有一个转折的点,变成一个斜坡,其对应的公式为

c ∗ max(0, b + wx1)                                                       (1.29)

max(0, b + wx1) 是指看 0 跟 b + wx1 谁比较大,比较大的会被当做输出;如果 b + wx1 < 0,输出是 0;如果 b + wx1 > 0,输出是 b + wx1。通过 w, b, c 可以挪动其位置和斜率。把两个 ReLU 叠起来就可以变成 Hard 的 Sigmoid,想要用 ReLU,就把 Sigmoid 的地方,换成max(0, bi + wijxj )。

   如图 1.19 所示,2 个 ReLU 才能够合成一个 Hard Sigmoid。要合成 i 个 Hard Sigmoid,需要 i 个 Sigmoid,如果 ReLU 要做到一样的事情,则需要 2i 个 ReLU,因为 2 个 ReLU 合起来才是一个 Hard Sigmoid。因此表示一个 Hard 的 Sigmoid 不是只有一种做法。在机器学习里面,Sigmoid 或 ReLU 称为激活函数(activation function)。

   当然还有其他常见的激活函数,但 Sigmoid 跟 ReLU 是最常见的激活函数,接下来的实验都选择用了 ReLU,显然 ReLU 比较好,实验结果如图 1.20 所示。如果是线性模型,考虑56 天,训练数据上面的损失是 320,没看过的数据 2021 年数据是 460。连续使用 10 个 ReLU作为模型,跟用线性模型的结果是差不多的,

   但连续使用 100 个 ReLU 作为模型,结果就有显著差别了,100 个 ReLU 在训练数据上的损失就可以从 320 降到 280,有 100 个 ReLU 就可以制造比较复杂的曲线,本来线性就是一直线,但 100 个 ReLU 就可以产生 100 个折线的函数,在测试数据上也好了一些. 接下来

使用 1000 个 ReLU 作为模型,在训练数据上损失更低了一些,但是在没看过的数据上,损失没有变化。

   接下来可以继续改模型,如图 1.21 所示,从 x 变成 a,就是把 x 乘上 w 加 b,再通过Sigmoid 函数。不一定要通过 Sigmoid 函数,通过 ReLU 也可以得到 a,同样的事情再反复地多做几次。 所以可以把 x 做这一连串的运算产生 a,接下来把 a 做这一连串的运算产生 a′。反复地多做的次数又是另外一个超参数。注意,w, b 和 w′, b′ 不是同一个参数,是增加了更多的未知的参数。

   每次都加 100 个 ReLU,输入特征,就是 56 天前的数据。如图 1.22 所示,如果做两次,损失降低很多,280 降到 180。如果做 3 次,损失从 180 降到 140,通过 3 次 ReLU,从 280降到 140,在训练数据上,在没看过的数据上,从 430 降到了 380。

   通过 3 次 ReLU 的实验结果如图 1.23 所示。横轴就是时间,纵轴是观看次数。红色的线是真实的数据,蓝色的线是预测出来的数据在这种低点的地方啊,看红色的数据是每隔一段时间,就会有两天的低点,在低点的地方,机器的预测还算是蛮准确的,机器高估了真实的观看人次,尤其是在红圈标注的这一天,这一天有一个很明显的低谷,但是机器没有预测到这一天有明显的低谷,它是晚一天才预测出低谷。这天最低点就是除夕。但机器只知道看前 56 天的值,来预测下一天会发生什么事,所以它不知道那一天是除夕。

如图 1.24 所示,Sigmoid 或 ReLU 称为神经元(neuron),很多的神经元称为神经网络(neural network)。人脑中就是有很多神经元,很多神经元串起来就是一个神经网络,跟人脑是一样的。人工智能就是在模拟人脑。神经网络不是新的技术,80、90 年代就已经用过了,后来为了要重振神经网络的雄风,所以需要新的名字。每一排称为一层,称为隐藏层(hiddenlayer),很多的隐藏层就“深”,这套技术称为深度学习。

所以人们把神经网络越叠越多越叠越深,2012 年的 AlexNet 有 8 层它的错误率是 16.4%,两年之后 VGG 有 19 层,错误率在图像识别上进步到 7.3 %。这都是在图像识别上一个基准的数据库(ImageNet)上面的结果,后来 GoogleNet 有 22 层,错误率降到 6.7%。而残差网络(Residual Network,ResNet)有 152 层,错误率降到 3.57%。

刚才只做到 3 层,应该要做得更深,现在网络都是叠几百层的,深度学习就要做更深。但4 层在训练数据上,损失是 100,在没有看过 2021 年的数据上,损失是 440。在训练数据上,

3 层比 4 层差,但是在没看过的数据上,4 层比较差,3 层比较好,如图 1.25 所示。在训练数据和测试数据上的结果是不一致的,这种情况称为过拟合(overfitting)。

   但是做到目前为止,还没有真的发挥这个模型的力量,2021 年的数据到 2 月 14 日之前的数据是已知的。要预测未知的数据,选 3 层的网络还是 4 层的网络呢?假设今天是 2 月 26日,今天的观看次数是未知的,如果用已经训练出来的神经网络预测今天的观看次数。要选 3层的,虽然 4 层在训练数据上的结果比较好,但在没有看过的数据的结果更重要。应该选一个在训练的时候,没有看过的数据上表现会好的模型,所以应该选 3 层的网络。深度学习的训练会用到反向传播(BackPropagation,BP),其实它就是比较有效率、算梯度的方法。

1.2.3 机器学习框架

我们会有一堆训练的数据以及测试数据如式 (1.30) 所示,测试集就是只有 x 没有 y。

训练集就要拿来训练模型,训练的过程是 3 个步骤。

1. 先写出一个有未知数 θ 的函数,θ 代表一个模型里面所有的未知参数。fθfθ(x) 的意思就是函数叫 fθfθ(x),输入的特征为 x,;

2. 定义损失,损失是一个函数,其输入就是一组参数,去判断这一组参数的好坏;

3. 解一个优化的问题,找一个 θ,该 θ 可以让损失的值越小越好。让损失的值最小的 θ 为θ∗,即

θ∗ = argminθL                                                                   (1.31)

有了 θ∗ 以后,就把它拿来用在测试集上,也就是把 θ∗ 带入这些未知的参数,本来 fθfθ(x)里面有一些未知的参数,现在 θ 用 θ∗ 来取代,输入是测试集,输出的结果存起来,上传到Kaggle 就结束了。

---------------------------------------------------------------------------------------------------------------------------------

2  实践方法论

在应用机器学习算法时,实践方法论能够帮助我们更好地训练模型。如果在 Kaggle 上的结果不太好,虽然 Kaggle 上呈现的是测试数据的结果,但要先检查训练数据的损失。看看模型在训练数据上面,有没有学起来,再去看测试的结果,如果训练数据的损失很大,显然它在训练集上面也没有训练好。接下来再分析一下在训练集上面没有学好的原因。

2.1 模型偏差

模型偏差可能会影响模型训练。举个例子,假设模型过于简单,一个有未知参数的函数代θ1 得到一个函数 fθfθ1(x),同理可得到另一个函数 fθfθ2(x),把所有的函数集合起来得到一个函数的集合。但是该函数的集合太小了,没有包含任何一个函数,可以让损失变低的函数不在模型可以描述的范围内。在这种情况下,就算找出了一个 θ∗,虽然它是这些蓝色的函数里面最好的一个,但损失还是不够低。这种情况就是想要在大海里面捞针(一个损失低的函数),结果针根本就不在海里。

    这个时候重新设计一个模型,给模型更大的灵活性。以第一章的预测未来观看人数为例,可以增加输入的特征,本来输入的特征只有前一天的信息,假设要预测接下来的观看人数,用前一天的信息不够多,用 56 天前的信息,模型的灵活性就比较大了。也可以用深度学习,增加更多的灵活性。所以如果模型的灵活性不够大,可以增加更多特征,可以设一个更大的模型,可以用深度学习来增加模型的灵活性,这是第一个可以的解法。但是并不是训练的时候,损失大就代表一定是模型偏差,可能会遇到另外一个问题:优化做得不好。

2.2 优化问题

   一般只会用到梯度下降进行优化,这种优化的方法很多的问题。比如可能会卡在局部最小值的地方,无法找到一个真的可以让损失很低的参数,如图 2.3(a) 所示。如图 2.3(b) 所示蓝色部分是模型可以表示的函数所形成的集合,可以把 θ 代入不同的数值,形成不同的函数,把所有的函数通通集合在一起,得到这个蓝色的集合。这个蓝色的集合里面,确实包含了一些函数,这些函数它的损失是低的。但问题是梯度下降这一个算法无法找出损失低的函数,梯度下降是解一个优化的问题,找到 θ∗ 就结束了。但 θ∗ 的损失不够低。这个模型里面存在着某一个函数的损失是够低的,梯度下降没有给这一个函数。这就像是想大海捞针,针确实在海里,但是无法把针捞起来。训练数据的损失不够低的时候,到底是模型偏差,还是优化的问题呢。找不到一个损失低的函数,到底是因为模型的灵活性不够,海里面没有针。还是模型的灵活性已经够了,只是优化梯度下降不给力,它没办法把针捞出来 到底是哪一个。到底模型已经够大了,还是它不够大,怎么判断这件事呢?

一个建议判断的方法,通过比较不同的模型来判断模型现在到底够不够大。举个例子,这一个实验是从残差网络的论文“Deep Residual Learning for Image Recognition”[1] 里面节录出来的。这篇论文在测试集上测试两个网络,一个网络有 20 层,一个网络有 56 层。图 2.4(a)横轴指的是训练的过程,就是参数更新的过程,随着参数的更新,损失会越来越低,但是结果20 层的损失比较低,56 层的损失还比较高。残差网络是比较早期的论文,2015 年的论文。很多人看到这张图认为这个代表过拟合,深度学习不奏效,56 层太深了不奏效,根本就不需要这么深。但 这个不是过拟合,并不是所有的结果不好,都叫做过拟合。在训练集上,20 层的网络损失其实是比较低的,56 层的网络损失是比较高的,如图 2.4(b) 所示,这代表 56 层的网络的优化没有做好,它的优化不给力。

这边给大家的建议是看到一个从来没有做过的问题,可以先跑一些比较小的、比较浅的网络,或甚至用一些非深度学习的方法,比如线性模型、支持向量机(Support Vector Machine,SVM),SVM 可能是比较容易做优化的,它们比较不会有优化失败的问题。也就是这些模型它会竭尽全力的,在它们的能力范围之内,找出一组最好的参数,它们比较不会有失败的问题。因此可以先训练一些比较浅的模型,或者是一些比较简单的模型,先知道这些简单的模型,到底可以得到什么样的损失。

接下来还缺一个深的模型,如果深的模型跟浅的模型比起来,深的模型明明灵活性比较大,但损失却没有办法比浅的模型压得更低代表说优化有问题,梯度下降不给力,因此要有一些其它的方法来更好地进行优化。

举个观看人数预测的例子,如图 2.5 所示,在训练集上面,2017 年到 2020 年的数据是训练集,1 层的网络的损失是 280,2 层就降到 180,3 层就降到 140,4 层就降到 100。但是测 5 层的时候结果变成 340。损失很大显然不是模型偏差的问题,因为 4 层都可以做到 100了,5 层应该可以做得更低。这个是优化的问题,优化做得不好才会导致造成这样子的问题。如果训练损失大,可以先判断是模型偏差还是优化。如果是模型偏差,就把模型变大。假设经过努力可以让训练数据的损失变小,接下来可以来看测试数据损失;如果测试数据损失也小,比这个较强的基线模型还要小,就结束了。

但如果训练数据上面的损失小,测试数据上的损失大,可能是真的过拟合。在测试上的结果不好,不一定是过拟合。要把训练数据损失记下来,先确定优化没有问题,模型够大了。接下来才看看是不是测试的问题,如果是训练损失小,测试损失大,这个有可能是过拟合。

2.3 过拟合

为什么会有过拟合这样的情况呢?举一个极端的例子,这是训练集。假设根据这些训练集,某一个很废的机器学习的方法找出了一个一无是处的函数。这个一无是处的函数,只要输入 x 有出现在训练集里面,就把它对应的 y 当做输出。如果 x 没有出现在训练集里面,就输出一个随机的值。这个函数啥事也没有干,其是一个一无是处的函数,但它在训练数据上的损失是 0。把训练数据通通丢进这个函数里面,它的输出跟训练集的标签是一模一样的,所以在训练数据上面,这个函数的损失可是 0 呢,可是在测试数据上面,它的损失会变得很大,因为它其实什么都没有预测,这是一个比较极端的例子,在一般的情况下,也有可能发生类似的事情。

如图 2.6 所示,举例来说,假设输入的特征为 x,输出为 y,x 和 y 都是一维的。x 和 y之间的关系是 2 次的曲线,曲线用虚线来表示,因为通常没有办法,直接观察到这条曲线。我们真正可以观察到的是训练集,训练集可以想像成从这条曲线上面,随机采样出来的几个点。模型的能力非常的强,其灵活性很大,只给它这 3 个点。在这 3 个点上面,要让损失低,所以模型的这个曲线会通过这 3 个点,但是其它没有训练集做为限制的地方,因为它的灵活性很大,它灵活性很大,所以模型可以变成各式各样的函数,没有给它数据做为训练,可以产生各式各样奇怪的结果。

如果再丢进测试数据,测试数据和训练数据,当然不会一模一样,它们可能是从同一个分布采样出来的,测试数据是橙色的点,训练数据是蓝色的点。用蓝色的点,找出一个函数以后,测试在橘色的点上,不一定会好。如果模型它的自由度很大的话,它可以产生非常奇怪的曲线,导致训练集上的结果好,但是测试集上的损失很大。

怎么解决过拟合的问题呢,有两个可能的方向:

第一个方向是往往是最有效的方向,即增加训练集。因此如果训练集,蓝色的点变多了,虽然模型它的灵活性可能很大,但是因为点非常多,它就可以限制住,它看起来的形状还是会很像,产生这些数据背后的 2 次曲线,如图 2.7 所示。可以做数据增强(data augmentation,),这个方法并不算是使用了额外的数据。

数据增强就是根据问题的理解创造出新的数据。举个例子,在做图像识别的时候,常做的一个招式是,假设训练集里面有某一张图片,把它左右翻转,或者是把它其中一块截出来放大等等。对图片进行左右翻转,数据就变成两倍。但是数据增强不能够随便乱做。在图像识别里面,很少看到有人把图像上下颠倒当作增强。因为这些图片都是合理的图片,左右翻转图片,并不会影响到里面的内容。但把图像上下颠倒,可能不是一个训练集或真实世界里面会出现的图像。如果给机器根据奇怪的图像学习,它可能就会学到奇怪的东西。所以数据增强,要根据对数据的特性以及要处理的问题的理解,来选择合适的数据增强的方式。

另外一个解法是给模型一些限制,让模型不要有过大的灵活性。假设 x 跟 y 背后的关系其实就是一条 2 次曲线,只是该 2 次曲线里面的参数是未知的。如图 2.8 所示,要用多限制的模型才会好取决于对这个问题的理解。因为这种模型是自己设计的,设计出不同的模型,结果不同。假设模型是 2 次曲线,在选择函数的时候有很大的限制,因为 2 次曲线要就是这样子,来来去去就是几个形状而已。所以当训练集有限的时候,来来去去只能够选几个函数。所以虽然说只给了 3 个点,但是因为能选择的函数有限,可能就会正好选到跟真正的分布比较接近的函数,在测试集上得到比较好的结果。

解决过拟合的问题,要给模型一些限制,最好模型正好跟背后产生数据的过程,过程是一样的就有机会得到好的结果。给模型制造限制可以有如下方法:

• 给模型比较少的参数。如果是深度学习的话,就给它比较少的神经元的数量,本来每层一千个神经元,改成一百个神经元之类的,或者让模型共用参数,可以让一些参数有一样的数值。全连接网络(fully-connected network)其实是一个比较有灵活性的架构,而卷积神经网络(Convolutional Neural Network,CNN)是一个比较有限制的架构。CNN 是一种比较没有灵活性的模型,其是针对图像的特性来限制模型的灵活性。所以全连接神经网络,可以找出来的函数所形成的集合其实是比较大的,CNN 所找出来的函数,它形成的集合其实是比较小的,其实包含在全连接网络里面的,但是就是因为CNN 给了,比较大的限制,所以 CNN 在图像上,反而会做得比较好,这个之后都还会再提到,

• 用比较少的特征,本来给 3 天的数据,改成用给两天的数据,其实结果就好了一些。

• 还有别的方法,比如早停(early stopping)、正则化(regularization)和丢弃法(dropoutmethod)。

但也不要给太多的限制。假设模型是线性的模型,图 2.9 中有 3 个点,没有任何一条直线可以同时通过这 3 个点。只能找到一条直线,这条直线跟这些点比起来,它们的距离是比较近的。这个时候模型的限制就太大了,在测试集上就不会得到好的结果。这种情况下的结果不好,并不是因为过拟合了,而是因为给模型太大的限制,大到有了模型偏差的问题。

这边产生了一个矛盾的情况,模型的复杂程度,或这样让模型的灵活性越来越大。但复杂的程度和灵活性都没有给明确的定义。比较复杂的模型包含的函数比较多,参数比较多。如图 2.10 所示,随着模型越来越复杂,训练损失可以越来越低,但测试时,当模型越来越复杂的时候,刚开始,测试损失会跟著下降,但是当复杂的程度,超过某一个程度以后,测试损失就会突然暴增了。这就是因为当模型越来越复杂的时候,复杂到某一个程度,过拟合的情况就会出现,所以在训练损失上面可以得到比较好的结果。在测试损失上面,会得到比较大的损失,可以选一个中庸的模型,不是太复杂的,也不是太简单的,刚刚好可以在训练集上损失最低,测试损失最低。

假设 3 个模型的复杂的程度不太一样,不知道要选哪一个模型才会刚刚好,在测试集上得到最好的结果。因为选太复杂的就过拟合,选太简单的有模型偏差的问题。把这 3 个模型的结果都跑出来,上传到 Kaggle 上面,损失最低的模型显然就是最好的模型,但是不建议这么做。举个极端的例子,假设有 1 到 1012 个模型,这些模型学习出来的函数都是一无是处的函数。它们会做的事情就是,训练集里面有的数据就把它记下来,训练集没看过的,就直接输出随机的结果。把这 1012 个模型的结果,通通上传到 Kaggle 上面,得到 1012 个分数,这1012 的分数里面,结果最好的,模型也是最好的。

虽然每一个模型没看过测试数据,其输出的结果都是随机的,但不断随机,总是会找到一个好的结果。因此也许某个模型找出来的函数,正好在测试数据上面的结果比较好,选这一个模型当作最后上传的结果,当作最后要用在私人测试集上的结果。该模型是随机的,它恰好在公开的测试数据上面得到一个好结果,但是它在私人测试集上可能仍然是随机的。测试集分成公开的数据集跟私人的数据集,公开的分数可以看到,私人的分数要截止日期以后才知道。如果根据公开数据集来选择模型,可能会出现这种情况:在公开的排行榜上面排前十,但是截止日期一结束,可能掉到 300 名之外。因为计算分数的时候,会同时考虑公开和私人的分数。

Q:为什么要把测试集分成公开和私人?A:假设所有的数据都是公开,就算是一个一无是处的模型,它也有可能在公开的数据上面得到好的结果。如果只有公开的测试集,没有私人测试集,写一个程序不断随机产生输出就好,不断把随机的输出上传到 Kaggle,可以随机出一个好的结果。这个显然没有意义。而且如果公开的测试数据是公开的,公开的测试数据的结果是已知的,一个很废的模型也可能得到非常好的结果。不要用公开的测试集调模型,因为可能会在私人测试集上面得到很差的结果,不过因为在公开测试集上面的好的结果也有算分数。

2.4 交叉验证

比较合理选择模型的方法是把训练的数据分成两半,一部分称为训练集(training set),一部分是验证集(validation set)。比如 90% 的数据作为训练集,有 10% 的数据作为验证集。在训练集上训练出来的模型会使用验证集来衡量它们的分数,根据验证集上面的分数去挑选结果,再把这个结果上传到 Kaggle 上面得到的公开分数。在挑分数的时候,是用验证集来挑模型,所以公开测试集分数就可以反映私人测试集的分数。但假设这个循环做太多次,根据公开测试集上的结果调整模型太多次,就又有可能在公开测试集上面过拟合,在私人测试集上面得到差的结果。不过上传的次数有限制,所以无法走太多次循环,可以避免在公开的测试集上面的结果过拟合。根据过去的经验,就在公开排行榜上排前几名的,往往私人测试集很容易就不好。

其实最好的做法,就是用验证损失,最小的直接挑就好了,不要管公开测试集的结果。在实现上,不太可能这么做,因为公开数据集的结果对模型的选择,可能还是会有些影响的。理想上就用验证集挑就好,有过比较好的基线(baseline)算法以后,就不要再去动它了,就可以避免在测试集上面过拟合。但是这边会有一个问题,如果随机分验证集,可能会分得不好,分到很奇怪的验证集,会导致结果很差,如果有这个担心的话,可以用 k 折交叉验证(k-foldcross validation),如图 2.11 所示。k 折交叉验证就是先把训练集切成 k 等份。在这个例子,训练集被切成 3 等份,切完以后,拿其中一份当作验证集,另外两份当训练集,这件事情要重复 3 次。即第一份第 2 份当训练,第 3 份当验证;第一份第 3 份当训练,第 2 份当验证;第一份当验证,第 2 份第 3 份当训练。

接下来有 3 个模型,不知道哪一个是好的。把这 3 个模型,在这 3 个设置下,在这 3 个训练跟验证的数据集上面,通通跑过一次,把这 3 个模型,在这 3 种情况的结果都平均起来,把每一种模型在这3种情况的结果,都平均起来,再看看谁的效果最好假设现在模型1的结果最好,3折交叉验证的出来的结果是,模型1最好。再把模型1用在全部的训练集上,训练出来的模型再用在测试集上面。接下来我们要问的一个问题可能是,讲到预测2月26日,也就是上周五的观看人数的结果如图2.12所示。所以把3层的网络,拿来测试一下是测试的结果。

2.5 不匹配

不匹配其实和过拟合不同,一般的过拟合可以用搜集更多的数据来克服,但是不匹配是指训练集和测试集的分布不同,训练集再增加其实也没有帮助了。假设数据在分训练集跟测试集的时候,使用2020年的数据作为训练集,使用2021年的数据作为测试集,不匹配的问题可能就很严重,如果用2020年当训练集,2021年当测试集,根本预测不准。因为2020年的数据跟2021的背后的数据分布不同。图2.14是图像分类中的不匹配问题。增加数据也不能让模型做得更好,所以这种问题要怎么解决,匹不匹配要看对数据本身的理解了,我们可能要对训练集跟测试集的产生方式有一些理解,才能判断它是不是遇到了不匹配的情况。

这篇关于Datawhale X 李宏毅苹果书 AI夏令营task1-3笔记的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1102188

相关文章

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

AI绘图怎么变现?想做点副业的小白必看!

在科技飞速发展的今天,AI绘图作为一种新兴技术,不仅改变了艺术创作的方式,也为创作者提供了多种变现途径。本文将详细探讨几种常见的AI绘图变现方式,帮助创作者更好地利用这一技术实现经济收益。 更多实操教程和AI绘画工具,可以扫描下方,免费获取 定制服务:个性化的创意商机 个性化定制 AI绘图技术能够根据用户需求生成个性化的头像、壁纸、插画等作品。例如,姓氏头像在电商平台上非常受欢迎,

从去中心化到智能化:Web3如何与AI共同塑造数字生态

在数字时代的演进中,Web3和人工智能(AI)正成为塑造未来互联网的两大核心力量。Web3的去中心化理念与AI的智能化技术,正相互交织,共同推动数字生态的变革。本文将探讨Web3与AI的融合如何改变数字世界,并展望这一新兴组合如何重塑我们的在线体验。 Web3的去中心化愿景 Web3代表了互联网的第三代发展,它基于去中心化的区块链技术,旨在创建一个开放、透明且用户主导的数字生态。不同于传统

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

AI hospital 论文Idea

一、Benchmarking Large Language Models on Communicative Medical Coaching: A Dataset and a Novel System论文地址含代码 大多数现有模型和工具主要迎合以患者为中心的服务。这项工作深入探讨了LLMs在提高医疗专业人员的沟通能力。目标是构建一个模拟实践环境,人类医生(即医学学习者)可以在其中与患者代理进行医学

AI行业应用(不定期更新)

ChatPDF 可以让你上传一个 PDF 文件,然后针对这个 PDF 进行小结和提问。你可以把各种各样你要研究的分析报告交给它,快速获取到想要知道的信息。https://www.chatpdf.com/

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学

系统架构师考试学习笔记第三篇——架构设计高级知识(20)通信系统架构设计理论与实践

本章知识考点:         第20课时主要学习通信系统架构设计的理论和工作中的实践。根据新版考试大纲,本课时知识点会涉及案例分析题(25分),而在历年考试中,案例题对该部分内容的考查并不多,虽在综合知识选择题目中经常考查,但分值也不高。本课时内容侧重于对知识点的记忆和理解,按照以往的出题规律,通信系统架构设计基础知识点多来源于教材内的基础网络设备、网络架构和教材外最新时事热点技术。本课时知识

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti