本系列是《玩转机器学习教程》一个整理的视频笔记。本小节主要介绍梯度的调试,应用梯度下降法最主要的就是计算梯度,但很有可能计算梯度程序没有错但是求得的梯度是错误的,这个时候就需要使用梯度调试的方式来发现错误。
一
梯度的调试
前几个小节介绍了什么是梯度下降法,在使用梯度下降法的过程中最重要的就是求出定义的损失函数在某一个参数θ上的梯度值。前面介绍的都是一些简单的函数,如果遇到更加复杂函数的时候,很有可能求解梯度并不容易,在这种情况下推导出公式实现并运行的时候,很有可能程序不会报错,但是求得的梯度是错误的。这个时候就需要有个方法能够识别发现这个错误。
本小节介绍一个最简单的方法,能够调试使用梯度下降法的过程中对梯度求解公式相应的推导。下面使用二维为例:
红色点是我们想要求梯度的点,此时在二维坐标下红色点对应的梯度就是曲线上过红色点的切线的斜率。我们可以使用一种方式来模拟红色点切线的斜率,此时斜率就是红色点的梯度:
这种方法近乎就是曲线上的某一点上导数的定义,只不过在高等数学严格的导数定义中,让红色的点和左右两个蓝色点之间的最小距离趋近于0,也就是求一个极限。但是在计算机实际实现的时候,完全可以取一个特别小的值来真正的把这两个点他们连线的斜率给算出来,然后作为红色点导数的一个取代值,这种计算方法也是非常容易,其实就是这两个蓝色点在纵方向的差除上横方向的差,相应的我们可以写出下面的式子:
当然了这种计算梯度的方法同样适用于高维的场景:
以此类推,对每一个维度都使用上面的方式进行求解。很显然这种求解梯度的方式比前面推导公式的求法在数学意义上的解释简单很多,不过这样做的时间复杂度是非常高的,因为每求一个维度对应的导数,我们都需要相应的求两遍,把某一个θ值带进J进行求解,同时还需要除以一个数,如果J的复杂度非常高的话,每求一次梯度都将消耗非常多的时间,也正因为如此,这种方法作为调试的手段,也就是说我们还没有完成我们算法的时候,可以在取出的小数据量上使用这种调试梯度的方法得到最终的结果,那么我们就可以知道这个结果肯定是对的,然后再使用推导公式的方式来看最终所求的梯度和使用调试梯度的方法所求出来的梯度是不是能够对上。
二
实现梯度的调试
这个例子告诉我们两件事情:
所以如果机器学习算法涉及到梯度的求法的时候,我们完全可以通过这种调试梯度的方式来验证我们推导梯度计算的数学解是否正确:
此时dJ_dubug函数是一个与损失函数J无关的函数,因此他适用于所有的函数,可以复用dJ_dubug,不像dJ_math只适用于当前任务中对应的损失函数J,这是因为dJ_math是基于当前的损失函数J进行推导才可以得到的,正因为如此这个dJ_dubug方式来求梯度的方法完全可以加入自己的机器学习工具箱中供以后自己调试梯度的时候使用。
def dJ_debug(theta, X_b, y, epsilon = 0.01): """使用调试梯度的方式计算梯度""" res = np.empty(len(theta)) # 遍历梯度向量的每个维度 for i in range(len(theta)): theta_1 = theta.copy() theta_1[i] += epsilon theta_2 = theta.copy() theta_2[i] -= epsilon res[i] = (J(theta_1, X_b, y) - J(theta_2, X_b, y) ) / (2 * epsilon) return res
本文分享自 AI机器学习与深度学习算法 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!