Python实现: 使用梯度下降法求解f(x)=cos(x)/x的最小值

本文将介绍如何使用Python实现梯度下降法,并以函数f(x)=cos(x)/x为例,详细讲解如何找到该函数的局部最小值。

代码实现

import numpy as np
import matplotlib.pyplot as plt

def f(x):
    return np.cos(x) / x

def f_prime(x):
    return (-x * np.sin(x) - np.cos(x)) / x**2

def gradient_descent(x0, learning_rate):
    val = []
    func_value = []

    print('Initial point is:', x0, '\n')
    x = x0
    f = f(x)
    print('The initial function value is:', f, '\n')
    val.append(x)
    func_value.append(f)

    count = 0
    iter_max = 100
    delta = 10

    while count < iter_max and delta > 10**(-4):
        count += 1
        print('The current iteration is:', count, '\n')

        up_x = x - learning_rate * f_prime(x)
        up_f = f(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 variable x is:', x, '\n')

    x_end = x
    first_grad = f_prime(x_end)
    second_grad = (-x * np.sin(x) - 2 * np.cos(x)) / x**3

    print('It converges after', count, 'iterations, and the local minimum is', x_end, '\n')
    print('First derivative of the local minimum point is', first_grad, '\n')
    print('Second derivative of the local minimum point is', second_grad, '\n')

    return [val, func_value, count]

if __name__=='__main__':
    x_min = -15
    x_max = 15
    sample_num = 1000
    dot_x = np.linspace(x_min, x_max, sample_num)
    dot_y = f(dot_x)

    x0 = -5
    learning_rate = 1
    [val, func_value, count] = gradient_descent(x0, learning_rate)
    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.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)
        plt.pause(0.2)

    plt.title(r'$\eta = %.3f$, $x_{0} = %.1f$, it iterates %d steps in total' % (learning_rate, x0, count), fontsize=10)
    plt.show()

代码解读

  1. 定义目标函数和梯度函数:
    • f(x): 定义目标函数 f(x) = cos(x)/x
    • f_prime(x): 定义目标函数的导数 f'(x) = (-x*sin(x) - cos(x))/x^2
  2. 实现梯度下降算法:
    • gradient_descent(x0, learning_rate): 实现了梯度下降算法,包括迭代更新变量x的值,直到满足停止条件。
    • 函数内部打印每次迭代的信息,包括当前迭代次数、函数值和变量x的值。
    • 函数返回最终找到的局部最小值点x_end、该点的函数值,以及迭代次数。
  3. 可视化结果:
    • 使用matplotlib.pyplot库绘制函数曲线和每次迭代的点。
    • 动态展示梯度下降过程中点的位置变化,方便理解算法的运行过程。

总结

本文使用Python实现了梯度下降算法,并以函数f(x)=cos(x)/x为例,找到了该函数的局部最小值。代码清晰易懂,并包含了详细的注释,方便读者理解和学习。读者可以根据自己的需要修改代码中的参数,例如学习率、初始点等,以观察不同参数对算法性能的影响。

Python实现: 使用梯度下降法求解f(x)=cos(x)/x的最小值

原文地址: https://www.cveoy.top/t/topic/b0VT 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录