![TensorFlow知识图谱实战](https://wfqqreader-1252317822.image.myqcloud.com/cover/115/44510115/b_44510115.jpg)
3.2.3 最小二乘法的梯度下降算法及其Python实现
下面介绍一下如何使用梯度下降算法计算最小二乘法。从前面的介绍可以看到,任何一个需要进行梯度下降的函数可以被比作一座山,而梯度下降的目标就是找到这座山的底部,也就是函数的最小值。根据之前道士下山的场景,最快的下山方式就是找到最陡峭的山路,然后沿着这条山路走下去,直到下一个观望点。之后在下一个观望点重复这个过程,继续寻找最陡峭的山路,直到山脚。
在实现这个过程去求解最小二乘法的最小值之前,先介绍部分需要读者掌握的数学原理。
1.微分
高等数学中对函数微分的解释有很多,最主要的有两种:
- 函数曲线上某点切线的斜率。
- 函数的变化率。
对于一个二元微分的计算如下所示。
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P77_8404.jpg?sign=1739673602-MAhrzIaFz628BaiYG6UWgIdt4g8Oe7JR-0-21a96cb7f17a99ff200b0fe67c0288b5)
2.梯度
所谓的梯度就是微分的一般形式,对于多元微分来说则是各个变量的变化率总和,例如:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P77_8405.jpg?sign=1739673602-hWh9HqJbwL3K4hxSf6xlEL2EqLnR5Hjo-0-b64d270abe6e8d44b0ccdfa086fcb82b)
可以看到,求解的梯度值是分别对每个变量进行微分计算,之后用逗号隔开。这里用中括号[]将每个变量的微分值包裹在一起,形成一个三维向量,因此可以将微分计算后的梯度认为是一个向量。
在多元函数中,梯度是一个向量,而向量具有方向性,梯度的方向指出了函数在给定点上上升最快的方向,如图3.9所示。将这个与上面道士下山的过程联系在一起,如果需要到达山底,则需要在每一个观察点寻找梯度最陡峭的地方。梯度计算的值是在当前点上升最快的方向,那么反方向则是给定点下降最快的方向。梯度的计算就是得出这个值的具体向量值。
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P78_4925.jpg?sign=1739673602-BxrJ6vFK5zivQtKSBfwrKvVxzunXpl8B-0-9d66ae9df6af81f8f7557663b6671f56)
图3.9 梯度的方向性
3.梯度下降的数学计算
前面给出了梯度下降的公式,接着对其进行变形:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P78_8406.jpg?sign=1739673602-T5MvO70sqGwin3kexPTlrXGQvqVEbtBs-0-011d3283e88f47aa41d76587c7e12131)
此公式中的参数含义如下:
是关于参数
的函数,假设当前点为
,如果需要找到这个函数的最小值,也就是山底,那么首先需要确定行进的方向,也就是梯度计算的反方向,之后走
的步长,之后到达下一个观察点。
的意义在上一节已经介绍,是学习率或者步长,使用
来控制每一步走的距离。
过小会造成拟合时间过长;
过大会造成下降幅度太大,从而错过最低点,如图3.10所示。
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P78_4926.jpg?sign=1739673602-BXoGXnXDHdJXqsGJYyySKsuHnsJQgITD-0-eaef0953c9f77ddeaface73065566427)
图3.10 学习率太小(左)与学习率太大(右)
需要注意的是,地图下降公式中求出的是斜率最大值,也就是梯度上升最大的方向,而这里所需要的是梯度下降最大的方向,因此在
前加一个负号。下面用一个例子演示梯度下降法的计算。
假设这里的公式为:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P79_8437.jpg?sign=1739673602-usMuOOyuABGW6TeSrb1CkTsukvvnCKCN-0-566ff01d42604ab6d96a9e68a326d3ee)
此时的微分公式为:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P79_8439.jpg?sign=1739673602-xnYyXrMvV9skHNYxQZ4urj5RU9im7w1Q-0-89245a1ddd96c585869b39b2e33b41ee)
设第一个值,
,则根据梯度下降公式可得:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P79_8441.jpg?sign=1739673602-9n0nxWJa7XexvgPJt22ebUSOWYZu18HW-0-596e38989b1398db475f5ec8ab655a8e)
这样依次经过运算即可得到的最小值,也就是“山底”,如图3.11所示。
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P79_4934.jpg?sign=1739673602-oEAcydwWbhyjaoO8kRGbJXuiVTZJnU7q-0-61eedd83e0c79c1a84c3c44499aa8896)
图3.11 梯度下降法的计算
实现程序如下所示。
【程序3-3】
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P79_8451.jpg?sign=1739673602-pcUq0gBSs6Uk7NbdkQ6VKJfqv6JS6nT9-0-d9b96e85b9dd3db80888cd4496b3fc53)
多变量的梯度下降方法和前文所述的多元微分求导类似。例如,一个二元函数形式如下:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P79_8453.jpg?sign=1739673602-WeBlrgutffezxJzIaCnU0KFTQBgkoqY1-0-8e9ab2869af56b6a8e60928e54be02b0)
此时对其的梯度微分为:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P80_8454.jpg?sign=1739673602-KksSOdP2zfSco9NWVvcKJDaWsxu7ZobP-0-f377240abe94fd33e949eb492322de5c)
此时将设置:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P80_8456.jpg?sign=1739673602-xDvoqbuDAhwJB4SSFalClzq4Y32uHnyn-0-3d59c3ea18bda1f36f8e24cb557eceb7)
则依次计算的结果如下:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P80_8458.jpg?sign=1739673602-9rZbdQXrphoLRAQX3AlTVZa5JfqYgH1i-0-ed963eae2e2409b4e2db6974b1c8d176)
剩下的计算请读者自行完成。
如果把二元函数的函数采用图像的方式展示出来,那么可以很明显地看到梯度下降的每个“观察点”坐标,如图3.12所示。
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P80_8459.jpg?sign=1739673602-GfqJEI0RxvEcxm4kH0wYSJTpRtPBuK4V-0-8e8820a33bba5e1c0139cef881fdc72a)
图3.12 梯度下降的可视化展示
4.使用梯度下降法求解最小二乘法
下面是本节的实战部分,使用梯度下降算法计算最小二乘法。假设最小二乘法的公式如下:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P80_8461.jpg?sign=1739673602-VoSzq11uoolqGbmR56w9jO2LoYB1VB0C-0-a0082e9ae5a622cc62557003b1d2d8b8)
参数解释如下:
- m:是数据点总数。
- 1/2:是一个常量。这样是为了在求梯度的时候将二次方微分后的结果与1/2抵消,也就没有多余的常数系数了,方便后续的计算,同时不会对结果有什么影响。
- y:是数据集中每个点的真实y坐标的值。
:为预测函数,形式如下:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8472.jpg?sign=1739673602-e4G6b7y3LbpV4d1IamOl5V0tfHR7mFOl-0-90eeb116201330eb9719d638b8b88622)
根据每个输入x,有一个经过参数计算后的预测值输出。
的Python实现如下所示:
h_pred = np.dot(x,theta)
其中,x是输入的维度为[-1,2]的二维向量,-1的意思是维度不定。这里使用了一个技巧,即将的公式转化成矩阵相乘的形式,而theta是一个[2,1]维度的二维向量。
依照最小二乘法实现的Python为:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8481.jpg?sign=1739673602-ZTEmSk5xmIom942eTRZqmhmVtf6qslJe-0-358a301eb15180b59acfc711a1203c06)
这里j_theta的实现同样是将原始公式转化成矩阵计算,即:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8483.jpg?sign=1739673602-VZG1aHmWPK54np0g980LbQG58Q7LtSON-0-e0deb84442f8f8caef05bfda9df20760)
下面分析一下最小二乘法公式。要求
的梯度,则需要对其中涉及的两个参数
和
进行微分:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8485.jpg?sign=1739673602-zVxovs67dVdJLvKb3t6aiT0nXSVZk0a3-0-839dbd8d85026930fb69e62e6c1fa6c6)
下面分别对两个参数的求导公式进行求导:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8342.jpg?sign=1739673602-NyXVZ2YsbVMzHp25wDBtz4f0O6Vx8p5n-0-b8e224f30d8e6700b94ba99523162ac4)
将分开求导的参数合并可得新的公式:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8344.jpg?sign=1739673602-oZuasaGHXgKtxPvTH33dB0yCAzhY73mE-0-b2072b0ba64d40f825c80aa434e4df71)
公式最右边的常数1可以去掉,即:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8497.jpg?sign=1739673602-HaAnHpNpx3xP3NqoN0A1aqJOEEUTPXUP-0-ae94fcb2cd2c57048ec23f8eeeaff976)
依旧采用矩阵相乘的方式,则使用矩阵相乘表示的公式为:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8499.jpg?sign=1739673602-LHJSOmmPg1vSRWhrhJTcjaDmV9KllrpI-0-90f6ac8bd34d9c52c520e70aae306f71)
这里已经转化为矩阵相乘的表示形式,使用Python表示如下:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P81_8503.jpg?sign=1739673602-80xVNu1dY8qC6k6J0wqBFBYoIsKrftD2-0-3a50c5169ad5b024656c47f7056b6724)
其中,np.dot(np.transpose(X), h_pred)。如果对此理解有难度,可以将公式使用逐个x值的形式列出来,这里就不罗列了。
最后是梯度下降的Python实现,代码如下:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P82_8507.jpg?sign=1739673602-R6woFHOFLvAV8aVlB67e3tNUaTlhihuD-0-42a2f94bc986f7124305e62b9294bb4f)
或者使用如下代码:
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P82_8509.jpg?sign=1739673602-EHnQeio7SUNLOcZWZyzdS9EF5Bbgq73q-0-f04bd2dec2864618889baf74078fcba1)
这两组程序段的区别在于第一个是固定循环次数,可能会造成欠下降或者过下降,而第二个代码段使用的是数值判定,可以设定阈值或者停止条件。
全部代码如下所示。
【程序3-4】
![](https://epubservercos.yuewen.com/281CEB/23721624209516806/epubprivate/OEBPS/Images/Figure-P82_8511.jpg?sign=1739673602-HWVrJu9F3jdPfkKdnzI6In6D06itE5KI-0-60b19a08ba6f395d880a6347960e4a12)
打印结果和拟合曲线请读者自行完成。
现在回到道士下山的问题中,这个下山的道士实际上代表的是反向传播算法,而要寻找的下山路径代表着算法中一直在寻找的参数,山上当前点最陡峭的方向实际上是代价函数在这一点的梯度方向,场景中观察最陡峭方向所用的工具就是微分。