探秘机器学习核心逻辑:梯度下降的迭代过程 (图文详解)

一  需求解函数

f() 和 g()函数分别为求y值求导数的函数。

目的:求该函数的最小值:

        y = (x - 3.5)^ 2 - 4.5 * x + 10

 代码:

import numpy as np
import matplotlib.pyplot as plt 

f = lambda x : (x - 3.5) ** 2 - 4.5 * x + 10
g = lambda x : 2 * (x - 3.5) - 4.5

x = np.linspace(0, 11.5, 100)
y = f(x)

plt.plot(x, y) 

二 随机初始化一个值

在 0 - 12 中随机取一个值:10

k = np.random.randint(0, 12)
print('随机取到的值k:', k)  # 10 

三 查看此时的斜率

查看此时的切线方程:

k = 10
g(x) = 8.5   # 斜率
f(x) = 7.5   # y值
# 该点的切线方程:y = 8.5 * x - 77.5

plt.plot(x, y) 
plt.scatter(k, f(k), color = 'red', s = 30)

# 生成x的范围
x_values = np.linspace(8, 11.5, 100)

# 计算对应的y值
y_values = 8.5 * x_values - 77.5
# 绘制直线
plt.plot(x_values, y_values, color='blue', label='Line')

四 根据斜率和学习率确定下一个点

设置学习率为0.2,与初始点的梯度反向进行下降,如果在上一个点斜率为正,说明需要x需要向左移动才能接近最小值:next_k = k - 学习率*斜率

学习率可以改,设置值比较大移动比较快,设置比较小移动比较慢。

求到的第一个K:8.3

learing_ratio = 0.2
next_k = k - learing_ratio*g(k) 

plt.plot(x, y) 
plt.scatter(k, f(k), color = 'red', s = 30)
plt.scatter(next_k, f(next_k), color = 'red', s = 30) 

print(next_k, f(next_k))
# 8.3 -4.309999999999995

五 根据该逻辑继续计算下一个值

用上一次计算的 8.2 计算一个值:next_k2 = next_k - learing_ratio*g(next_k) 

求到的第二个K:7.28

learing_ratio = 0.2
next_k2 = next_k - learing_ratio*g(next_k) 

plt.plot(x, y) 
plt.scatter(k, f(k), color = 'red', s = 30)
plt.scatter(next_k, f(next_k), color = 'red', s = 30)
plt.scatter(next_k2, f(next_k2), color = 'red', s = 30)
print(next_k2, f(next_k2))
# 7.28 -8.471599999999995

六 同时查看两次迭代过程中 y值的变化率

查看两次迭代过程中 y值的变化率分别为:-11.559999999999995  -4.1616

plt.plot(x, y) 
plt.scatter([k, next_k, next_k2], [f(k), f(next_k), f(next_k2)], 
            color = 'red', s = 30)

# 绘制直线
plt.plot(x, [f(k)] * len(x), label='y=5', color='blue', linestyle='--')
plt.plot(x, [f(next_k)] * len(x), label='y=5', color='green', linestyle='--')
plt.plot(x, [f(next_k2)] * len(x), label='y=5', color='red', linestyle='--')

print(f(next_k) - f(k), f(next_k2) - f(next_k))  # -11.5599999999-4.1616

七 设置循环,求最接近的目标值

注意:截止条件设置的变化率是x 的变化率,就是当 斜率的变化值足够小 的时候截止,其实也是y值的变化率乘学习率后的变化值 !!

k = k - learing_ratio*g(k)

设置截止循环条件:precision = 0.0001

learing_ratio = 0.2
last_k = k + 0.1
# 精确度
precision = 0.0001

k_ = [k]
count = 0  # 记录迭代次数

while True:
    if np.abs(k - last_k) < precision:
        break
    last_k = k
    count += 1
    k = k - learing_ratio*g(k)  # 迭代
    k_.append(k)
    print(f'-> 迭代次数cnt:{count:2},更新后的x:{k:0.7f}, 实时的y:{f(k):0.7f}')

print(f'梯度下降的次数:{count}')
plt.plot(x, y) 
print('最后的k值:', k)  # 5.75009323204022

# 散点图,转换为array数组可以用f(x)直接求列表的y值
k_ = np.array(k_)
plt.scatter(k_, f(k_), color = 'red', s = 30)

 

PS:最后的列表直接求y值是先转换为了 np.array数组!!!

实际值:5.75

循环21次,最后求到的k值:5.75009323204022

相关推荐

  1. 梯度下降机器学习关系

    2023-12-10 11:20:02       26 阅读

最近更新

  1. TCP协议是安全的吗?

    2023-12-10 11:20:02       17 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2023-12-10 11:20:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2023-12-10 11:20:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2023-12-10 11:20:02       18 阅读

热门阅读

  1. DevOps - Spug 自动化运维平台

    2023-12-10 11:20:02       36 阅读
  2. Liunx的LVM与磁盘配额

    2023-12-10 11:20:02       40 阅读
  3. Python中函数详解

    2023-12-10 11:20:02       30 阅读
  4. nginx常用笔记备忘

    2023-12-10 11:20:02       30 阅读
  5. cv2.error: OpenCV(4.7.0)

    2023-12-10 11:20:02       38 阅读
  6. PyTorch分布式overview

    2023-12-10 11:20:02       36 阅读
  7. YARN分布式资源调度框架

    2023-12-10 11:20:02       29 阅读
  8. UE5 中在全局着色器的数据更新流程

    2023-12-10 11:20:02       27 阅读
  9. Python——lambda匿名函数

    2023-12-10 11:20:02       40 阅读