Implementation of gradient descent algorithm based on python language: take y = sinx/x as an example to explain

Implementation of gradient descent algorithm based on python language: take y = sinx/x as an example to explain

Gradient descent principle:

Gradient descent principle website


The y = sinx/x function graph is as follows:

Insert image description here


Now our goal is to find the points at the following locations through the gradient descent algorithm

Insert image description here


function:

Original function :
y = sin ⁡ ( x ) x \displaystyle y = \frac{\sin \left(x\right)}{x}y=xsin(x)
一阶导数:
y ′ = cos ⁡ ( x ) x − sin ⁡ ( x ) x 2 y' = \frac{\cos\left(x\right)}{x}-\frac{\sin\left(x\right)}{x^2} y=xcos(x)x2sin(x)
Second derivative:
y ′ ′ = − sin ⁡ ( x ) x − 2 cos ⁡ ( x ) x 2 + 2 sin ⁡ ( x ) x 3 y''= -\frac{\sin(x)}{x} -\frac{2\cos(x)}{x^2}+\frac{2\sin(x)}{x^3}y′′=xsin(x)x22cos(x)+x32sin(x)


Code demonstration effect:

Insert image description here


code show as below:

The comments have been written, please browse by yourself

import numpy as np
import matplotlib.pyplot as plt

#plt.rc('text', usetex=True) #使用latex
#原函数
def fun(X):
    return np.sin(X)/X
#一阶导数
def grad(X):
    return np.cos(X)/X - np.sin(X)/(X**2)
#二阶导数
def seconds_grad(x):
    return - np.sin(x) / x - 2 * np.cos(x) / (x ** 2) + 2 * np.sin(x) / (x ** 3)
def gradient_descent(X0, ita):
    #用来保存自变量和因变量的值
    Val=list()
    Func_Value = list()

    print('Initial point is:', X0, '\n')
    X = X0
    f = fun(X) #计算原函数的值,之后用于在图像上用小红点表示出来
    print('The initial function value is:', f, '\n')
    Val.append(X) #将自变量加入
    Func_Value.append(f)#将因变量加入

    count = 0 #迭代次数
    iter_max = 100 #最大允许迭代次数
    Delta = 10 #f(k)-f(k-1) < Delta

    while count < iter_max and Delta > 10**(-4):
        count = count+1
        print('The current iteration is:', count, '\n')
        #梯度下降的公式得到下降后的自变量
        up_X = X - ita*grad(X)
        #得到下降后的因变量
        up_f = fun(up_X)
        #Delta = grad(up_X)
        #原来的函数值与下降后的函数值相减
        Delta = np.abs(f - up_f)

        X = up_X
        f = up_f
        Val.append(X)
        Func_Value.append(f)

        print('The function value is:', f, '\n')
        print('The var is:',X, '\n')
    #循环结束后的X点,即接近函数局部最低点的自变量的值
    X_end = X
    #求一阶导数
    first_grad = grad(X_end)
    #求二阶导数,用于判断是凹函数还是凸函数
    second_grad = seconds_grad(X_end)
    print('It converges after', count, 'iterations, and the local minimal is', X_end,'\n')
    print('Fisrt gradient of the local minimal point is', first_grad, '\n')
    print('Second gradient of the local minimal point is', second_grad, '\n')
    return [Val, Func_Value, count]



if __name__=="__main__":
    # y = x^2 - 2*x + 1
    #有= sin(x)/x 的函数区间为-15 到 15
    x_min = -15
    x_max = 15
    #在-15到15上取1000个平均分布的点,即自变量
    sample_num = 1000
    dot_x = np.linspace(x_min, x_max, sample_num)
    dot_y = fun(dot_x)
    #X0为在函数图像选取的一个点,之后得到会得到y = sin(X0)/X0 ,即X0 = -1 对应的函数值
    X0 = -1
    ita = 1
    #此处Val表示从X0 = -1点开始,沿函数图像的左边不断下降所记录的所有的自变量的值,运行代码是能看到图像上的点是往左下方下降的
    #此处Func_Value表示从X0 = -1点开始,沿函数图像的左边不断下降所记录的所有的的值因变量,运行代码是能看到图像上的点是往左下方下降的
    #count 表示函数迭代的次数
    #gradient_descent函数用于计算并Val和Func_value的值
    [Val, Func_Value, count] = gradient_descent(X0, ita)
    Val = np.array(Val)
    Func_Value = np.array(Func_Value)
    np.set_printoptions(formatter={
    
    'float': '{: 0.3f}'.format})
    print(Val)
    print(Func_Value)
    plt.figure()
    plt.plot(dot_x, dot_y, "-", c='b')
    for i in range(count+1):
        plt.title(r'$\eta = %.3f$, $x_{0} = %.1f$, it iterates %d steps in total' % (ita, X0, count), fontsize=10)
        plt.scatter(Val[i], Func_Value[i], color='r',s =40, marker = 'o')
        text_pt = plt.text(Val[i] + 0.1 , Func_Value[i], '', fontsize=10)
        # text_pt.set_text(r'$x_{%d}$' % i)

        # text_pt = plt.text(0, 6, '', fontsize=10)
        # text_pt.set_text(r'$x_{%d} = %.3f$' % (i, Val[i]))

        plt.pause(0.2)
    # plt.grid()
    plt.show()


Guess you like

Origin blog.csdn.net/qq_60943902/article/details/127428358