![深度学习详解:基于李宏毅老师“机器学习”课程](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=1739338870-imQLuyTWq7ABIZmDdCnhe6Bh7sgdnWV8-0-a20d7f969203f1b1765656c593d1b5d9)
图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=1739338870-fKoysYCBHPsSd2Xug1w3Wdcjki6rmzYE-0-d57568b3a3c1d5f43c95e28a17eea36f)
图1.8 构建红色线
所以红色线[即分段线性曲线(piecewise linear curve)]可以看作一个常数和一些蓝色函数的叠加.分段线性曲线越复杂,转折的点越多,所需的蓝色函数就越多.
也许要考虑的 和
的关系不是分段线性曲线 ,而是图1.9 所示的曲线. 可以在这样的曲线上先取一些点,再把这些点连起来,变成一条分段线性曲线.而这条分段线性曲线跟原来的曲线非常接近,如果点取得够多或位置适当,分段线性曲线就可以逼近连续曲线,甚至可以逼近有角度和弧度的连续曲线. 我们可以用分段线性曲线来逼近任何连续曲线,只要有足够的蓝色函数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2868.jpg?sign=1739338870-utH2d3m58MWRNDQrR2u1UE9qZivHD0EG-0-1ed5c7b035351614862a76c3a15fc52c)
图1.9 分段线性曲线可以逼近任何连续曲线
和
的关系非常复杂也没关系,可以想办法写一个带有未知数的函数.直接写 hard sigmoid 函数不是很容易,但可以用 sigmoid 函数来逼近 hard sigmoid 函数,如图1.10 所示.sigmoid函数的表达式为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2833.jpg?sign=1739338870-zAYNtLa4f9ysuau3RC8bCef6w3AmJJp2-0-2c58d06273775ca787b9c0b66d0125fb)
其中,输入是 ,输出是
,
为常数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2926.jpg?sign=1739338870-7yvppX1SxS2H5ItyUW3kG2R2X0F8lfv6-0-d6781ad27ca06687a5e838382e11c76e)
图1.10 使用 sigmoid 函数逼近 hard sigmoid 函数
当 的值趋近于正无穷的时候,
这一项就会几乎消失,
就会收敛于常数
;当
的值趋近于负无穷的时候,分母就会非常大,
就会收敛于 0.
所以可以用这样的一个函数逼近蓝色函数.为了简洁,蓝色函数的表达式记为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2934.jpg?sign=1739338870-efFHr5lVXnZQrEilihNY7HSoLyKQC3td-0-b1a3da15b4db9be1f5017ac3fe093d34)
(1.15)
其中
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx2941.jpg?sign=1739338870-A1c0tsltiRuVgBgyjCOkMltfdjm8UrIK-0-03ebd12c092add420e7f7dc21820cc76)
(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=1739338870-Y0yyU3N3c4gM6x5IWeSwvxfGzi3zmbZv-0-ecaca587987c3927e51833729d4c2eb1)
(1.17)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3038.jpg?sign=1739338870-Rs8S74K0S19Wifg8kU3446QZMFzOHszZ-0-33695c8c83766138e96ad2c35d407352)
图1.11 调整参数,构造不同的 sigmoid 函数
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3048.jpg?sign=1739338870-RPTYBLx67xLhTrB0BOlBkraNLQ2nfkzp-0-594e515113f7e6c357879682d87d70ee)
图1.12 使用 hard sigmoid 函数来合成红色线
此外,我们可以不只用一个特征 ,而是用多个特征代入不同的
、
、
,构建出各种不同的sigmoid函数,从而得到更有灵活性(flexibility)的分段线性函数,如图1.13 所示. 可以用
来代表特征的编号. 如果要考虑 28 天的数据,
就可以取 1 ~ 28.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3134.jpg?sign=1739338870-QGF2rI8DmZn1MKW9OoDBxR4IyE5jBl77-0-f241ee13bee775d7764a0046879d28ec)
图1.13 构建更有灵活性的函数
举个只考虑3个特征(即只考虑前3天~前1天)的例子. 此时可以取 1、2、3,每一个
就代表一个蓝色函数. 每一个蓝色函数都用一个 sigmoid函数来近似,一共需要3个 sigmoid函数:
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3127.jpg?sign=1739338870-PgfonHpuIGuPVUVWNoc5N51yucvO31NT-0-74c803212579a4d1c9103af7659628a8)
(1.18)
代表在第
个 sigmoid 函数中乘给第
个特征的权重.设图1.13 的蓝色虚线框中有
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3177.jpg?sign=1739338870-BcY0RkQCdaW953wZL7EUMrCcbI2sxOfV-0-f967d31d99e42cef3f309902c14e1b5d)
(1.19)
我们可以用矩阵和向量相乘的方法,得到如下比较简洁的写法.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3184.jpg?sign=1739338870-HaVsDlP9lOCHgK4MHzF6z5qlRm5hl7YN-0-7f2e7b89cf2b9e6f5b3c26120f55de6f)
(1.20)
也可以改成线性代数比较常用的表示方式,如下所示.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3195.jpg?sign=1739338870-YV7AQkoqkYmJYqK8Gx9lOy6ndlYRGUnC-0-982e0f6e62ad2c3d53e35cf2d1e648a6)
(1.21)
对应的是
、
、
.有了
、
、
, 分别通过 sigmoid函数得到
、
、
,即
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3289.jpg?sign=1739338870-iABLR4g4pW8IFtYqGgk5vXGNV778lZ6u-0-f072327b0672863311a62343b1b01f9b)
(1.22)
因此,如图1.14 所示,蓝色虚线框里面做的事情,就是从 、
、
得到
、
、
.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3473.jpg?sign=1739338870-bpxkKc89O0dO5aIxvukbUcox7fSC6pxp-0-b4def838816cc0a9224be7c33e57a821)
图1.14 比较有灵活性函数的计算过程
上面这个比较有灵活性的函数可以用线性代数来表示,即
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3348.jpg?sign=1739338870-FAdr572JByO9gmGkyH2jXVGSknzUrON0-0-a05b0523fafafd0a2bb09ce23a14f26e)
(1.23)
接下来,如图1.15 所示,是特征,绿色的
是向量,灰色的
是数值.
、
、
、
是未知参数.把矩阵展平,与其他项“拼合”,就可以得到一个很长的向量. 把
的每一行或每一列拿出来,拿行或拿列都可以. 先把
的每一列或每一行“拼”成一个长向量,再把
、
、
“拼”进来,这个长向量可以直接用
来表示. 我们将所有未知参数一律统称
.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3481.jpg?sign=1739338870-MwnsY3vUTuxr2i9PsH2Z7Ui6Vfh2mieK-0-22d0394a7e3c5ee50af56043b654ec0e)
图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=1739338870-uL9ajcLt1jyYEjwQVw2wx7Zx9rlYM37O-0-8e540d7e80567007ee78e00d81ab7675)
(1.24)
要找到一组 , 让损失越小越好,可以让损失最小的一组
称为
.一开始,要随机选一个初始的数值
. 接下来计算每一个未知参数对
的微分,得到向量
为
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3683.jpg?sign=1739338870-SH6s9c11l1RMKGIaCaCp7ds4hEiQ8Z3o-0-eeea9d8af702d952b0572d8afbc707fd)
(1.25)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3690.jpg?sign=1739338870-g06Yy48qehWLNdOq8CXD7mXLaoFVhZof-0-3450c3d5c37d2d8b3811edaca1346827)
(1.26)
假设有 1000 个参数,向量的长度就是 1000,这个向量也称为梯度向量.
代表梯度;
是指计算梯度的位置,也就是
等于
的地方.计算出
以后,接下来更新参数.
代表起始值,它是一个随机选的起始值,代表
更新过一次的结果. 用
减掉微分结果和
的积,得到
,以此类推,就可以把 1000 个参数都更新了(见图1.16):
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3790.jpg?sign=1739338870-Hj5ozNAFbSxF5NMVhKmERhDGKGIEEpLH-0-37c448a505893c7cd86a5eb81fb565b7)
(1.27)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3800.jpg?sign=1739338870-v9oV5j0GXymgt5tfQeeT43tBMDwwOFhD-0-d8183bce9ee545d665010738b034b27c)
(1.28)
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx3875.jpg?sign=1739338870-syEI6bhb4JzaUJVNMf8TORpz7d3TIyR7-0-f7f40d56c59fb6eca5deb3142ec1d7cc)
图1.16 使用梯度下降更新参数
参数有 1000 个,就是 1000 个数值,
是1000 维的向量,
也是 1000 维的向量.整个操作就是这样,由
开始计算梯度,根据梯度把
更新成
;再算一次梯度,再根据梯度把
更新成
;以此类推,直到不想做,或者梯度为零,导致无法再更新参数为止. 不过在实践中,几乎不太可能梯度为零,通常停下来就是因为我们不想做了.
实现上,有个细节上的区别,如图1.17 所示,实际使用梯度下降时,会把 笔数据随机分成一个个的批量(batch),每个批量里面有
笔数据.本来是把所有的数据拿出来计算损失
,现在只拿一个批量里面的数据出来计算损失,记为
.假设
够大,也许
和
会很接近.所以在实现上,每次会先选一个批量,用该批量来算
,根据
来算梯度,再用梯度来更新参数;接下来再选下一个批量,算出
,根据
算出梯度,再更新参数;最后再取下一个批量,算出
,根据
算出梯度,再用
算出来的梯度更新参数.
![](https://epubservercos.yuewen.com/91F3C0/30654405004700006/epubprivate/OEBPS/Images/tx4012.jpg?sign=1739338870-JDS3eSLrinYrd95v6rpow8u6e5rzPZXu-0-2144e59cadd5cf57eb7bee300f596352)
图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 次,取决于批量有多大.