首页 > 代码库 > 从导数谈起

从导数谈起

一个函数在某一点的导数描述了这个函数在这一点附近的变化率。(微小的dx变化,引起多大的dy变化)

对于一个隐函数F(X)(X = {x0,x1,…,xn})而言,由于其在X的各个方向上变化速率和方向都是不同的,例如可以在x0方向上以线性方式变化,在x1方向上以平方级别方式变化等等,那么如果我们想知道在给定X附近F(X)的变化方向和速率,要如何刻画?

答案是梯度。梯度是F(X)对各个分量求偏导后的结果,代表了F(X)在各个方向的变化率。整个法向量就是F(X)在各个方向上变化率叠加出来的向量。可以在使用全微分公式后,用i,j,k…代替dx1,dx2,dx3…,来表示法向量。

有上面的全微分公式,我们可以更好地理解极值,为什么常说函数取得极值的时候导数为0呢。

假设一维情况,clip_image029,如果要求极小值,两边微分后得clip_image031,当x=0时,导数2x为0,取得极值。否则,如果x为正数,那么dx只需向左调整(dx<0),就能使F(x)值变小,如果x为负数,那么dx只需向右调整(dx>0),就能使F(x)变小。因此最后调整结果是x=0。

对于二维情况,clip_image002[4]

clip_image033的值在计算后会有正负值,但我们应该注意到dx可正可负,dy也可正可负,只要clip_image033[1]有一个不为0,那么通过调整dx,dy的正负号(也就是确定怎么移动x和y)就可以使clip_image015[1]的值变大变小。只有在偏导数都是0的情况下,无论如何调整dx和dy,clip_image002[6]都是0,取得极值。

既然直接可以令导数为0来求解函数极值,那么为什么计算函数极值时还要使用梯度下降算法而不直接令导数为0来求解呢?原因如下:

并不是所有函数都可以求出导数为0的点的, 现实的情况可能是:
1. 可以求出导数在每个点的值,但是直接解方程解不出来。
2. 导数并没有解析解,像一个黑匣子一样,给定输入值,可以返回输出值,但是具体里面是什么情况,我们根本无法得知。神经网络便是如此。

牛顿迭代和梯度下降法都可以计算极值,区别在于,梯度下降法的算法复杂度低一些,但是迭代次数多一些;牛顿迭代法计算的更快(初值必须设置的很合理), 但是牛顿迭代法因为有“除法”参与(对矩阵来说就是求逆矩阵), 所以每一步迭代计算量很大。一般会根据具体的情况取舍。

总之,多数函数解不出导数得0的解析解(exp(x)+(ln(x))^2+x^5,算不出来吧?!)。梯度下降法是种数值算法,一般可以用计算机求出很好的近似解。

从导数谈起