![深度学习详解:基于李宏毅老师“机器学习”课程](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=1739348728-iHf3EAzlcbho4cLLfFFuhJO93oxS3lIc-0-f9446364a7ecc98feafbf7ebd78a47a6)
图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=1739348728-1BhZObSXHnzHq58GFz4BAVa3GuVJNdoE-0-cff7ad8ccab504c218c04dab2e373d92)
图1.8 构建红色线
所以红色线[即分段线性曲线(piecewise linear curve)]可以看作一个常数和一些蓝色函数的叠加.分段线性曲线越复杂,转折的点越多,所需的蓝色函数就越多.
也许要考虑的 和
的关系不是分段线性曲线 ,而是图1.9 所示的曲线. 可以在这样的曲线上先取一些点,再把这些点连起来,变成一条分段线性曲线.而这条分段线性曲线跟原来的曲线非常接近,如果点取得够多或位置适当,分段线性曲线就可以逼近连续曲线,甚至可以逼近有角度和弧度的连续曲线. 我们可以用分段线性曲线来逼近任何连续曲线,只要有足够的蓝色函数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2868.jpg?sign=1739348728-acTNwzsfCdxnytRiNG3C0yGycKbXbkW7-0-227db851b227a0164df1f310b41057ad)
图1.9 分段线性曲线可以逼近任何连续曲线
和
的关系非常复杂也没关系,可以想办法写一个带有未知数的函数.直接写 hard sigmoid 函数不是很容易,但可以用 sigmoid 函数来逼近 hard sigmoid 函数,如图1.10 所示.sigmoid函数的表达式为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2833.jpg?sign=1739348728-wRJN45O6bJm6IhOpucbRQarRWtuRkdBY-0-daea59002e8eb688aa60ff9b8dd6bb48)
其中,输入是 ,输出是
,
为常数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2926.jpg?sign=1739348728-OdjvlVAhUL6szmAGtXZefJlGAOkQoSNS-0-96c4f1e7138231fe56885c77a6e0eb3f)
图1.10 使用 sigmoid 函数逼近 hard sigmoid 函数
当 的值趋近于正无穷的时候,
这一项就会几乎消失,
就会收敛于常数
;当
的值趋近于负无穷的时候,分母就会非常大,
就会收敛于 0.
所以可以用这样的一个函数逼近蓝色函数.为了简洁,蓝色函数的表达式记为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2934.jpg?sign=1739348728-wJOyAcWHn9tG18gDNKBq2HGGw1jlUMGv-0-428f0e6fb4323ae207dd3a2625eefb83)
(1.15)
其中
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2941.jpg?sign=1739348728-VtqusCwptumjOWJ1OIbqi8aRZiUD6gh1-0-dfd7eb4c65588eae6fb88976da500090)
(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=1739348728-7vCPtYGRqjU22T9GoOLPyzpcp4FmcDsC-0-ce9a7e7740181556e5c02eac25a35598)
(1.17)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3038.jpg?sign=1739348728-jabZnSemfNBNzBhqJki8vDprziQzGKX4-0-28d9dfd3e1cd07905806dcf921ecc9ae)
图1.11 调整参数,构造不同的 sigmoid 函数
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3048.jpg?sign=1739348728-1LFh1Q8m1hoPygB58alggqHnJY2BhWE2-0-b4500c9c63264baa6f996d78c6b7edc0)
图1.12 使用 hard sigmoid 函数来合成红色线
此外,我们可以不只用一个特征 ,而是用多个特征代入不同的
、
、
,构建出各种不同的sigmoid函数,从而得到更有灵活性(flexibility)的分段线性函数,如图1.13 所示. 可以用
来代表特征的编号. 如果要考虑 28 天的数据,
就可以取 1 ~ 28.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3134.jpg?sign=1739348728-1tCtNclpueWUucgWSXWwrwua7zHzmI6d-0-c736ab13dde6ce6f3c9b856955a0c35a)
图1.13 构建更有灵活性的函数
举个只考虑3个特征(即只考虑前3天~前1天)的例子. 此时可以取 1、2、3,每一个
就代表一个蓝色函数. 每一个蓝色函数都用一个 sigmoid函数来近似,一共需要3个 sigmoid函数:
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3127.jpg?sign=1739348728-43zoragMkiWUBEQwQbXepwqvRXdPj6hq-0-95e56b59beb4f71264de38c3f5ab1197)
(1.18)
代表在第
个 sigmoid 函数中乘给第
个特征的权重.设图1.13 的蓝色虚线框中有
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3177.jpg?sign=1739348728-fB44hFizdZobQsxvpsyYJN5Rq9fXUCNw-0-e817492241484a4802dbf5d5a800cf7d)
(1.19)
我们可以用矩阵和向量相乘的方法,得到如下比较简洁的写法.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3184.jpg?sign=1739348728-RP3gP1KeNZO4ZLlxIgitOFNjnsDRvp8a-0-0d5c4153c20c60979ff97f8796064f47)
(1.20)
也可以改成线性代数比较常用的表示方式,如下所示.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3195.jpg?sign=1739348728-OAVGGM7FXnos8Reh85teJZPmmdimR8AK-0-f377e665a67c24c0124aff5e45913f74)
(1.21)
对应的是
、
、
.有了
、
、
, 分别通过 sigmoid函数得到
、
、
,即
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3289.jpg?sign=1739348728-UMBq6C5jjszlI0mAErdBAPCWEvyPslOj-0-71d8a58a11a243e436581e752b7d369e)
(1.22)
因此,如图1.14 所示,蓝色虚线框里面做的事情,就是从 、
、
得到
、
、
.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3473.jpg?sign=1739348728-ASzLXbDCzcHNvRmp2oWu3PTctSUNHX9f-0-0ec4ee7ac60974b50868d29d069d1acd)
图1.14 比较有灵活性函数的计算过程
上面这个比较有灵活性的函数可以用线性代数来表示,即
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3348.jpg?sign=1739348728-7qV4R9TGcWyJu4ZmzBIo8bzxYrD3kAYm-0-44d3c3eca582817e19eb7dcbdbfbb35b)
(1.23)
接下来,如图1.15 所示,是特征,绿色的
是向量,灰色的
是数值.
、
、
、
是未知参数.把矩阵展平,与其他项“拼合”,就可以得到一个很长的向量. 把
的每一行或每一列拿出来,拿行或拿列都可以. 先把
的每一列或每一行“拼”成一个长向量,再把
、
、
“拼”进来,这个长向量可以直接用
来表示. 我们将所有未知参数一律统称
.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3481.jpg?sign=1739348728-WUeOxmNNLJIiF45HgAqRc9CLX9OKvgco-0-defb3fbd0ac4e0d0ee32c1df700c4f59)
图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=1739348728-xrqvOJtVmToWsaZeOYqny4dPfH16qVjE-0-079a9d56efa18689f925e84fefa14d07)
(1.24)
要找到一组 , 让损失越小越好,可以让损失最小的一组
称为
.一开始,要随机选一个初始的数值
. 接下来计算每一个未知参数对
的微分,得到向量
为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3683.jpg?sign=1739348728-vc14OxKWteVeRvnE7ETpxjn7DC4R2RMI-0-39b169d5e2deada7259f0ebe6d4c4bf5)
(1.25)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3690.jpg?sign=1739348728-LRdnV7PErDr1BFh0m9ANmazVKDyyOA2W-0-c2c67fb7dd9c7fe78e303787315c03ea)
(1.26)
假设有 1000 个参数,向量的长度就是 1000,这个向量也称为梯度向量.
代表梯度;
是指计算梯度的位置,也就是
等于
的地方.计算出
以后,接下来更新参数.
代表起始值,它是一个随机选的起始值,代表
更新过一次的结果. 用
减掉微分结果和
的积,得到
,以此类推,就可以把 1000 个参数都更新了(见图1.16):
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3790.jpg?sign=1739348728-fg5BWnUO9YTqOJ7St2ugJLFsQ56MFr46-0-9e15f9fd77e9ba2d867b4bf78f58e36f)
(1.27)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3800.jpg?sign=1739348728-VgOlPMDiixjMqd0A4TxKQLPIoK1njcZp-0-cd313fd96c885c18fb610a1535611dd5)
(1.28)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3875.jpg?sign=1739348728-s0a5SNrCMiKG3ixtLhJyuffHM7sCWIut-0-2fcad62192cef1e275b89281ac7f851a)
图1.16 使用梯度下降更新参数
参数有 1000 个,就是 1000 个数值,
是1000 维的向量,
也是 1000 维的向量.整个操作就是这样,由
开始计算梯度,根据梯度把
更新成
;再算一次梯度,再根据梯度把
更新成
;以此类推,直到不想做,或者梯度为零,导致无法再更新参数为止. 不过在实践中,几乎不太可能梯度为零,通常停下来就是因为我们不想做了.
实现上,有个细节上的区别,如图1.17 所示,实际使用梯度下降时,会把 笔数据随机分成一个个的批量(batch),每个批量里面有
笔数据.本来是把所有的数据拿出来计算损失
,现在只拿一个批量里面的数据出来计算损失,记为
.假设
够大,也许
和
会很接近.所以在实现上,每次会先选一个批量,用该批量来算
,根据
来算梯度,再用梯度来更新参数;接下来再选下一个批量,算出
,根据
算出梯度,再更新参数;最后再取下一个批量,算出
,根据
算出梯度,再用
算出来的梯度更新参数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx4012.jpg?sign=1739348728-YRbl39pqgwVF9CqQEJ3zdNP6Gposx5BU-0-2fa60c9a7bdd69543a8f9df7799c6bcb)
图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 次,取决于批量有多大.