<jupyter_start><jupyter_text>模拟梯度下降法  梯度下降法的封装和实现<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
plot_x = np.linspace(-1, 6, 141) # [-1, 6]等间距取141个点
plot_x
plot_y = (plot_x - 2.5)**2 - 1 # 损失函数J
plt.plot(plot_x, plot_y)
plt.show()
# theta对应的导数
def dJ(theta):
    return 2*(theta - 2.5)
    
# theta对应的损失函数
def J(theta):
    try:
        return (theta - 2.5)**2 - 1
    except:
        return float("inf") # 防止梯度下降法结果收敛不了
theta = 0.0
eta = 0.1 # 学习率η
epsilon = 1e-8 # 接近0的定义
while True:
    gradient = dJ(theta) # 获取导数变换值
    last_theta = theta 
    theta = theta - eta * gradient # eta即η, theta即θ(指的是特征系数的取值，一个一维数组，不断变化使得J(θ)最小)
    
    # 比较差值是否越来越小.当变换接近于最小精度时，已经可以认为到达导数为0的点了
    if(abs(J(theta) - J(last_theta)) < epsilon):
        break
        
print(theta)
print(J(theta))
theta = 0.0
theta_history = [theta]
while True:
    gradient = dJ(theta) # 求导
    last_theta = theta 
    theta = theta - eta * gradient # -η*dJ
    # 把每次的theta存储到数组中，方便下面进行绘图
    theta_history.append(theta)
    
    # 比较损失函数的差值是否越来越小.当变化接近于最小精度时，已经可以认为到达导数为0的点了
    if(abs(J(theta) - J(last_theta)) < epsilon):
        break
        
plt.plot(plot_x, J(plot_x)) # 画出整个曲线
plt.plot(np.array(theta_history), J(np.array(theta_history)), color = 'r', marker = '+') # 画出所有梯度下降法经过的点
plt.show()
len(theta_history) # 执行了46次，得到了导数为0的点
def gradient_descent(initial_theta,eta,epsilon=1e-8):
    """
    梯度下降法的封装
    """
    theta = initial_theta
    theta_history = [initial_theta]
    while True:
        gradient = dJ(theta)
        last_theta = theta 
        theta = theta - eta * gradient
        # 把每次的theta存储到数组中，方便下面进行绘图
        theta_history.append(theta)
        # print(theta)
        # 比较差值是否越来越小.当变换接近于最小经度时，已经可以人为到达导数为0的点了
        if(abs(J(theta) - J(last_theta)) < epsilon):
            print("累计查找的次数："+str(len(theta_history)))
            plot_theta_history(theta_history)
            break
def plot_theta_history(theta_history):
    plt.plot(plot_x, J(plot_x))
    plt.plot(np.array(theta_history), J(np.array(theta_history)), color = 'r', marker = '+')
    plt.show()<jupyter_output><empty_output><jupyter_text>下面分别对不同的η(即eta)进行测试，看下不同的η对收敛速度和收敛性的影响> 一般η初始取0.01比较好<jupyter_code>eta = 0.8 # 分别自己试试0.1、0.01、0.001；0.8、、
gradient_descent(0.,eta)
eta = 0.1 # 分别自己试试0.1、0.01、0.001；0.8、、
gradient_descent(0.,eta)
eta = 0.01 # 分别自己试试0.1、0.01、0.001；0.8、、
gradient_descent(0.,eta)
eta = 0.001 # 分别自己试试0.1、0.01、0.001；0.8、、
gradient_descent(0.,eta)
eta = 1.1 # 分别自己试试0.1、0.01、0.001；0.8；1.1的时候越蹦越高，收敛不了了
gradient_descent(0.,eta)
def gradient_descent(initial_theta,eta,epsilon=1e-8,max_iters=10000): # max_iters:最大循环次数，防止无法首先时陷入死循环
    theta = initial_theta
    theta_history = [initial_theta]
    for i in range(0, max_iters): # 只梯度下降指定的次数，这样就不会出现上面死循环的情况了
        gradient = dJ(theta)
        last_theta = theta 
        theta = theta - eta * gradient
        # 把每次的theta存储到数组中，方便下面进行绘图
        theta_history.append(theta)
        # 比较差值是否越来越小.当变换接近于最小经度时，已经可以人为到达导数为0的点了
        if(abs(J(theta) - J(last_theta)) < epsilon):
            print("累计查找的次数："+str(len(theta_history)))
            plot_theta_history(theta_history)
            break
        if i==max_iters-1: # 一旦到达最大梯度下降的次数就直接绘图，不再继续梯度下降下去了
            plot_theta_history(theta_history)
eta = 1.1 # 分别自己试试0.1、0.01、0.001；0.8；1.1的时候越蹦越高，收敛不了了,所以不会打印出图,这里指定迭代的最大次数
gradient_descent(0.,eta,max_iters=100)
eta = 1.1 # 分别自己试试0.1、0.01、0.001；0.8；1.1的时候越蹦越高，收敛不了了,所以不会打印出图，这里指定迭代的最大次数
gradient_descent(0.,eta,max_iters=10) # 梯度下降次数少地时候还是可以看到最开始的损失函数J曲线地<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13601586851799377, 'fraction_numerical': 0.04618872201756872, 'mean_word_length': 3.5256410256410255, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 10, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '2', 'dir': 'jupyter-structured-clean-dedup', 'id': '562519', 'license': 'MulanPSL-1.0', 'n_tokens_mistral': 1937, 'n_tokens_neox': 2025, 'n_words': 205, 'path': 'Part5Improve/06-Gradient-Descent/02-Gradient-Descent-Simulation/02-Gradient-Descent-Simulation.ipynb', 'repo_name': '19920625lsg/itcast-python', 'size': '3529'}