![深度学习详解:基于李宏毅老师“机器学习”课程](https://wfqqreader-1252317822.image.myqcloud.com/cover/19/51893019/b_51893019.jpg)
1.2.1 分段线性曲线
线性模型也许过于简单, 和
之间可能存在比较复杂的关系,如图1.7 所示.对于
的线性模型,
和
的关系就是一条斜率为正的直线,随着
越来越大,
也应该越来越大.设定不同的
可以改变这条直线的斜率,设定不同的
则可以改变这条直线和
轴的交点.但无论如何改变
和
,它永远都是一条直线,永远都是
越大,
就越大:某一天的观看次数越多,次日的观看次数就越多.但在现实中,也许当
大于某个数值的时候,次日的观看次数反而会变少.
和
之间可能存在一种比较复杂的、像红色线一样的关系.但不管如何设置
和
,我们永远无法用简单的线性模型构造红色线.显然,线性模型有很大的限制,这种来自模型的限制称为模型的偏差,无法模拟真实情况.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2739.jpg?sign=1739305628-jy5F7BE9tmZcFZvDvlhwpJozYMOAgAUQ-0-2962b7f333f89eaf597128d9dc67622f)
图1.7 线性模型的局限性
所以,我们需要写一个更复杂、更有灵活性、有更多未知参数的函数. 图1.8 中,红色线可以看作一个常数项 再加上一些 hard sigmoid 函数(hard sigmoid 函数的特性是当输入的值介于两个阈值间的时候,图像呈现出一个斜坡,其余位置都是水平的).常数项被设成红色线和
轴的交点一样大.第1个蓝色函数斜坡的起点,设在红色函数的起始地方. 第2个斜坡的终点设在第一个转角处,第1个蓝色函数的斜坡和红色函数的第1段斜坡斜率相同,这时候求
+❶, 就可以得到红色线左侧的线段.接下来,叠加第2个蓝色函数,所以第2个蓝色函数的斜坡就在红色函数的第1个转折点和第2个转折点之间,第2个蓝色函数的斜坡和红色函数的第2段斜坡斜率相同. 这时候求
+❶+❷,就可以得到红色函数左侧和中间的线段.对于第2个转折点之后的部分,再叠加第3个蓝色函数,第3个蓝色函数的斜坡的起点设在红色函数的第2个转折点,蓝色函数的斜坡和红色函数的第3段斜坡斜率相同. 最后,求
+❶+❷+❸,就得到了完整的红色线.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2793.jpg?sign=1739305628-lfefGJ2Go0uouyfnFCRCvzrSeIV9pmfK-0-734f2c28f11d1b0d17779b3a527250ca)
图1.8 构建红色线
所以红色线[即分段线性曲线(piecewise linear curve)]可以看作一个常数和一些蓝色函数的叠加.分段线性曲线越复杂,转折的点越多,所需的蓝色函数就越多.
也许要考虑的 和
的关系不是分段线性曲线 ,而是图1.9 所示的曲线. 可以在这样的曲线上先取一些点,再把这些点连起来,变成一条分段线性曲线.而这条分段线性曲线跟原来的曲线非常接近,如果点取得够多或位置适当,分段线性曲线就可以逼近连续曲线,甚至可以逼近有角度和弧度的连续曲线. 我们可以用分段线性曲线来逼近任何连续曲线,只要有足够的蓝色函数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2868.jpg?sign=1739305628-LNjVfS8ixpjnec5BCf4lTVA9kJRwesqO-0-6b285c8ce25548e111de0e337c212598)
图1.9 分段线性曲线可以逼近任何连续曲线
和
的关系非常复杂也没关系,可以想办法写一个带有未知数的函数.直接写 hard sigmoid 函数不是很容易,但可以用 sigmoid 函数来逼近 hard sigmoid 函数,如图1.10 所示.sigmoid函数的表达式为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2833.jpg?sign=1739305628-osj618cdJIDYELYuU3BFBXLlqxQTGOAi-0-d08c95d7b15c58ad9e3edebfec314343)
其中,输入是 ,输出是
,
为常数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2926.jpg?sign=1739305628-8YzEaxc2A4eBWVTvdRMLbkmOklMRkeHe-0-a4e6e43161fec81d71ab0b61cfb033aa)
图1.10 使用 sigmoid 函数逼近 hard sigmoid 函数
当 的值趋近于正无穷的时候,
这一项就会几乎消失,
就会收敛于常数
;当
的值趋近于负无穷的时候,分母就会非常大,
就会收敛于 0.
所以可以用这样的一个函数逼近蓝色函数.为了简洁,蓝色函数的表达式记为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2934.jpg?sign=1739305628-OXxBIw6S6HU6ZEttq9eGYeASoJ3zii40-0-3a83b0d02c75511b03d1a5282a9de45f)
(1.15)
其中
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2941.jpg?sign=1739305628-RvfcPQ69vUaMYn9Dlygq1Oq0nR2wSdBi-0-809e5ce1c8a4d2240e763723ceb5c0be)
(1.16)
调整式(1.15)中的 、
和
, 就可以构造各种不同形状的 sigmoid函数,从而用各种不同形状的 sigmoid函数逼近 hard sigmoid 函数.如图1.11 所示,如果调整
,就会改变斜坡的坡度;如果调整
,就可以左右移动sigmoid函数曲线;如果调整
,就可以改变曲线的高度.所以,只要叠加拥有不同的
、 不同的
和不同的
的sigmoid函数,就可以逼近各种不同的分段线性函数(如图1.12 所示):
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3031.jpg?sign=1739305628-uTYPyoipv6OBnnVuMxI9QLyJ1dSy7wcy-0-4a7573a1902e4f9f8bf5d599a0192b74)
(1.17)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3038.jpg?sign=1739305628-tUpimZikbqeN1s9hIko4EPp0fntkHhAp-0-567d82eee693f76be4fdf258e3d2557e)
图1.11 调整参数,构造不同的 sigmoid 函数
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3048.jpg?sign=1739305628-2qSgxAN8etB2haoaOkCEvpCCsbxF4Z3q-0-ebb4216bd445eea2174c498c391f0166)
图1.12 使用 hard sigmoid 函数来合成红色线
此外,我们可以不只用一个特征 ,而是用多个特征代入不同的
、
、
,构建出各种不同的sigmoid函数,从而得到更有灵活性(flexibility)的分段线性函数,如图1.13 所示. 可以用
来代表特征的编号. 如果要考虑 28 天的数据,
就可以取 1 ~ 28.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3134.jpg?sign=1739305628-8vHAFixaDxcaAFwTaSgmoAKfxbCQC8Pz-0-43e2bc9e84ea93fb34118ba587116d64)
图1.13 构建更有灵活性的函数
举个只考虑3个特征(即只考虑前3天~前1天)的例子. 此时可以取 1、2、3,每一个
就代表一个蓝色函数. 每一个蓝色函数都用一个 sigmoid函数来近似,一共需要3个 sigmoid函数:
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3127.jpg?sign=1739305628-v1NYK52Oaih75b4I5HvSgC7796CH9w9D-0-c7cbfa27a1af79343d168d9576f92557)
(1.18)
代表在第
个 sigmoid 函数中乘给第
个特征的权重.设图1.13 的蓝色虚线框中有
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3177.jpg?sign=1739305628-A0G23OKpzL4Pdm6ezQ7qQPKiDCupBuCO-0-9445cf3e9880ffd3fbcc8f0c209cc64c)
(1.19)
我们可以用矩阵和向量相乘的方法,得到如下比较简洁的写法.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3184.jpg?sign=1739305628-sqfekZDYbmURDbI5RxZyQxwGsqyUbLwB-0-dcace970556dc6679988346308f2bf23)
(1.20)
也可以改成线性代数比较常用的表示方式,如下所示.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3195.jpg?sign=1739305628-fULMawysLqNfWbxlebsouJSrOeR8jw6x-0-9b0f59dcfb3ae2123daefa81e3f8b218)
(1.21)
对应的是
、
、
.有了
、
、
, 分别通过 sigmoid函数得到
、
、
,即
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3289.jpg?sign=1739305628-NafsxMcsQdM5sN2z40Y2iq3SzhNkC2xn-0-293cd97144934a39b3dab9d782facf16)
(1.22)
因此,如图1.14 所示,蓝色虚线框里面做的事情,就是从 、
、
得到
、
、
.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3473.jpg?sign=1739305628-7qoF5VvFP0JvLRvO5FcavUotcCoIE1FU-0-d23fb1cfb65a18c87f4e61005e72f0b8)
图1.14 比较有灵活性函数的计算过程
上面这个比较有灵活性的函数可以用线性代数来表示,即
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3348.jpg?sign=1739305628-xLgdg85CgBrwYJvOccis6RLEbHHdXNje-0-0775570426558d29c67e0f7965d56443)
(1.23)
接下来,如图1.15 所示,是特征,绿色的
是向量,灰色的
是数值.
、
、
、
是未知参数.把矩阵展平,与其他项“拼合”,就可以得到一个很长的向量. 把
的每一行或每一列拿出来,拿行或拿列都可以. 先把
的每一列或每一行“拼”成一个长向量,再把
、
、
“拼”进来,这个长向量可以直接用
来表示. 我们将所有未知参数一律统称
.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3481.jpg?sign=1739305628-NAA8ac0XUJHmRiXlXu40OQTJvt6HeCyX-0-14b719f2cc52b310ae88866457284f29)
图1.15 将未知参数“拼”成一个向量
Q: 优化是找一个可以让损失最小的参数,是否可以穷举所有可能的未知参数的值?
A:在只有 和
两个参数的前提下,可以穷举所有可能的
和
的值. 所以在参数很少的情况下,甚至可能不用梯度下降,也不需要优化技巧. 但是当参数非常多的时候,就不能使用穷举的方法,而应使用梯度下降的方法找出可以让损失最小的参数.
Q:刚才的例子里面有 3 个 sigmoid函数,为什么是 3 个,能不能是 4 个或更多个?
A:sigmoid 函数的数量由我们自己决定,sigmoid 函数的数量越多,可以产生的分段线性函数就越复杂.sigmoid 函数的数量也是一个超参数.
接下来定义损失. 此前的损失函数记作 ,现在未知参数太多了,所以直接用
来统设所有的参数,损失函数记作
. 损失函数能够判断
的好坏,计算方法跟只有两个参数的情况是一样的:先给定
的值,即某一组
、
、
、
的值,再把特征
加进去,得到估测出来的
,最后计算一下跟真实标签之间的误差. 把所有的误差通通加起来,就得到了损失.
下一步就是优化,即优化
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3626.jpg?sign=1739305628-kmenAqzNCiAQgXrdoodIlnoNegpOK0cS-0-ced77c3e004f51d64daa1250736924d0)
(1.24)
要找到一组 , 让损失越小越好,可以让损失最小的一组
称为
.一开始,要随机选一个初始的数值
. 接下来计算每一个未知参数对
的微分,得到向量
为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3683.jpg?sign=1739305628-p8Q6SAojV5C8p5VTcJSNscFB30Bd1goy-0-add88cf2254b1e16aa15db60997734f4)
(1.25)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3690.jpg?sign=1739305628-0qMEVEXLLRKnQS1eFrJC5DAI9aeRi3TV-0-8e141ca94907d79da3d2d636d3ca7c85)
(1.26)
假设有 1000 个参数,向量的长度就是 1000,这个向量也称为梯度向量.
代表梯度;
是指计算梯度的位置,也就是
等于
的地方.计算出
以后,接下来更新参数.
代表起始值,它是一个随机选的起始值,代表
更新过一次的结果. 用
减掉微分结果和
的积,得到
,以此类推,就可以把 1000 个参数都更新了(见图1.16):
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3790.jpg?sign=1739305628-WvkwF1FXqniIaeivevzrmd9JqEpzfQn3-0-80f8e99389581ed0c955d4f77835b4a6)
(1.27)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3800.jpg?sign=1739305628-BbBLs9qFS5hejR3ygp7qbVyTpH5biSNw-0-266122f4146e77bda149baa5509c3c09)
(1.28)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3875.jpg?sign=1739305628-gCl7qvIgfcpmM68y8zWj9B9A7BC6sUTo-0-ed064c956c385f92c31621eb3ed5a001)
图1.16 使用梯度下降更新参数
参数有 1000 个,就是 1000 个数值,
是1000 维的向量,
也是 1000 维的向量.整个操作就是这样,由
开始计算梯度,根据梯度把
更新成
;再算一次梯度,再根据梯度把
更新成
;以此类推,直到不想做,或者梯度为零,导致无法再更新参数为止. 不过在实践中,几乎不太可能梯度为零,通常停下来就是因为我们不想做了.
实现上,有个细节上的区别,如图1.17 所示,实际使用梯度下降时,会把 笔数据随机分成一个个的批量(batch),每个批量里面有
笔数据.本来是把所有的数据拿出来计算损失
,现在只拿一个批量里面的数据出来计算损失,记为
.假设
够大,也许
和
会很接近.所以在实现上,每次会先选一个批量,用该批量来算
,根据
来算梯度,再用梯度来更新参数;接下来再选下一个批量,算出
,根据
算出梯度,再更新参数;最后再取下一个批量,算出
,根据
算出梯度,再用
算出来的梯度更新参数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx4012.jpg?sign=1739305628-V55FeWGb1Zurglqyu3VmcaT4rZwR6Ljp-0-77a8f91c625c2b1246f1fec5fc549690)
图1.17 分批量进行梯度下降
把所有的批量都看过一遍的过程称为一个回合(epoch),每更新一次参数称为一次更新. 更新和回合是两个不同的概念.
举个例子,假设有 10 000 笔数据,即 等于 10 000;批量大小(batch size)设为 10,即
等于10.10 000 个样本(example)形成了 1000 个批量,所以在一个回合里面更新了参数 1000 次,所以一个回合不只更新参数一次.
再举个例子,假设有 1000 个数据,批量大小设为 100,批量大小和sigmoid 函数的个数都是超参数.1000 个 样本,批量大小 设为 100,1个回合总共更新10次参数.一个回合的训练其实不知道更新了几次参数,有可能 1000 次,也有可能 10 次,取决于批量有多大.