梯度下降法-6.调试梯度下降法

梯度下降法的准确性与调试

对于梯度下降法的使用,一个非常重要的步骤是求解我们定义的损失函数\(J\)在某个点\(\theta\)上的梯度值\(dJ\),我们也花了很长时间来推导此公式,但是对于一些复杂的函数如非线性函数,求解梯度并不容易,在这种情况下,为了保证求解的梯度表达式正确,发现求解过程中的错误,需要进行梯度下降法的调试

定义\(\theta=(\theta_0,\theta_1,\theta_2,\theta _0,...,\theta _n)\) ,对每一个\(\theta\)求导:

\[\Lambda J = (\frac{\partial J}{\partial \theta _0},\frac{\partial J}{\partial \theta _1},\frac{\partial J}{\partial \theta _2},...,\frac{\partial J}{\partial \theta _n}) \]

而其中:

\[\frac{\partial J}{\partial \theta _i} = \frac{J(\theta_i^+ )-J(\theta_i^-)}{2\varepsilon } =\frac{J(\theta_i +\varepsilon )-J(\theta_i -\varepsilon )}{2\varepsilon } \]

调试的过程:

构造数据集

import numpy
import matplotlib.pyplot as plt

numpy.random.seed(666)
X = numpy.random.random(size=(1000,10))
true_theta = numpy.arange(1,12)

X_b = numpy.hstack([numpy.ones((len(X),1)),X])
y = X_b.dot(true_theta) + numpy.random.normal(size=1000)

定义损失函数和梯度下降方法:

def J(theta,X_b,y):   #损失函数的表达式
    return numpy.sum((y - X_b.dot(theta))**2)/len(X_b)

def dJ_math(theta,X_b,y):
    return X_b.T.dot(X_b.dot(theta)-y)*2/len(X_b)

def dJ_Debug(theta,X_b,y,epsilon=0.01):
    m = len(theta)
    res = numpy.empty(m)
    for i in range(m):
        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

定义梯度下降过程:

def gradient_descent(dJ,X_b,y,init_theta,eta,n_iters=1e4,espilon=1e-8):
    
    theta = init_theta
    i_iters = 0
    
    # n_iters 表示梯度下降的次数,超过这个值,有可能算法不收敛,退出
    while n_iters>i_iters: 
        gradient = dJ(theta,X_b,y)  #偏导数
        last_theta = theta
        theta = theta - eta * gradient  #梯度下降,向极值移动   
        if abs(J(theta,X_b,y) - J(last_theta,X_b,y)) < espilon:
            break
        i_iters += 1 
    # 返回求出的theta值
    return theta
    
init_theta = numpy.zeros(X_b.shape[1])
eta=0.01

使用调试的方法梯度下降,查看\(\theta\)值和计算时间

%time theta = gradient_descent(dJ_Debug,X_b,y,init_theta,eta,n_iters=1e4,espilon=1e-8)


使用数学推导的方法梯度下降,查看\(\theta\)值和计算时间

%time theta = gradient_descent(dJ_math,X_b,y,init_theta,eta,n_iters=1e4,espilon=1e-8)

通过结果比较,我们能确定数学推导的求梯度公式的正确性。

posted @ 2019-07-20 16:17  凌晨四点的洛杉矶  阅读(195)  评论(0编辑  收藏  举报