ML02
ML02
梯度下降
Gradient Descent
- Have some function J(w,b) , What min J(w,b)
- 多次梯度下降的步骤,可以看作是“从山顶最快达到山脚”的路线选择,其中路线选择的依据是“最速下降”的方向
- 如果改变“下山”的位置,“山顶”的选择不同,最终到达“山脚”的位置,不一定相同。因为有“局部最小值”的出现,算作是梯度下降的特性之一。
实习梯度下降
以下是梯度更新的方式:
注意,完成w参数的更新后,不能用作后续b参数更新的代入值,需要分别完成计算后,再进行更新。“同步更新”
- 这里的 α 称作 学习率 。决定梯度下降的步长
- α 后的导数部分可被视为J(w)函数(是一个u形函数)在w点的斜率(这里假设b=0),可以先这样简单理解。
学习率
- 如果学习率太小,会导致梯度下降过慢
- 如果学习率太大,会导致梯度下降过程中,超过最小点,且可能会发散(无法收敛)
- 如果梯度下降过程中,w的值位于局部最小值,那么梯度下降算法不会进行任何操作。
- 当越来越接近最小值的时候,即使 α 的值不变,其下降的速度也会变慢,因为函数的斜率也就是导数部分在变小。
线性回归的梯度下降
- 梯度下降:
线性回归函数的代价函数是一个凸函数,也就是弓形函数(注意这里的开口向上)
批量梯度下降:每次梯度下降都在查看所有的训练样本,而不是训练数据的一个子集
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105!sudo apt-get update
!sudo apt-get install -y fonts-wqy-zenhei
!sudo fc-cache -fv # 更新系统字体缓存
import matplotlib.pyplot as plt
import matplotlib.font_manager as fm
import numpy as np
import os
# import shutil # 导入 shutil 模块用于删除目录,但不再需要,因为移除了get_cachedir
# 定义文泉驿正黑字体的常见路径
wqy_zenhei_font_path = '/usr/share/fonts/truetype/wqy/wqy-zenhei.ttc'
# 检查字体文件是否存在
if os.path.exists(wqy_zenhei_font_path):
# 1. 删除 matplotlib 的内部字体缓存,强制其重新加载 (此方法导致AttributeError,已移除)
# cache_dir = fm.get_cachedir()
# if os.path.exists(cache_dir):
# shutil.rmtree(cache_dir)
# print(f"Deleted matplotlib font cache directory: {cache_dir}")
# 2. 将字体直接添加到 matplotlib 的字体管理器中
fm.fontManager.addfont(wqy_zenhei_font_path)
# 3. 获取 matplotlib 识别的字体家族名称
prop = fm.FontProperties(fname=wqy_zenhei_font_path)
font_name_from_file = prop.get_name() # 通常会是 'WenQuanYi Zen Hei'
# 4. 设置 matplotlib 以使用新的字体
# 添加一个或多个备用字体以防主要字体加载失败
plt.rcParams['font.sans-serif'] = [font_name_from_file, 'DejaVu Sans', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示为方块的问题
print(f"Set font to '{font_name_from_file}' using font file: {wqy_zenhei_font_path}")
print(f"Matplotlib's resolved font path for '{font_name_from_file}': {fm.findfont(font_name_from_file)}")
else:
print(f"Error: Font file not found at {wqy_zenhei_font_path}. Chinese characters might not display correctly.")
# 如果字体文件未找到,则回退到 Colab 默认字体
plt.rcParams['font.sans-serif'] = ['DejaVu Sans', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False
# 1. 定义目标函数 (例如: f(x) = (x - 3)^2 + 2)
def objective_function(x):
return (x - 3)**2 + 2
# 2. 定义目标函数的导数
def derivative_function(x):
return 2 * (x - 3)
# 3. 梯度下降算法实现
def gradient_descent(
initial_x, learning_rate, num_iterations
):
x_history = [initial_x]
for _ in range(num_iterations):
gradient = derivative_function(x_history[-1])
new_x = x_history[-1] - learning_rate * gradient
x_history.append(new_x)
return np.array(x_history)
# 参数设置
initial_x = 10.0 # 初始值设置得离最小值3远一些
learning_rate = 0.1
num_iterations = 50
# 运行梯度下降
x_values = gradient_descent(initial_x, learning_rate, num_iterations)
y_values = objective_function(x_values)
# 4. 可视化结果
x_plot = np.linspace(-5, 15, 400) # 调整x范围以更好地展示新函数
y_plot = objective_function(x_plot)
plt.figure(figsize=(10, 6))
plt.plot(x_plot, y_plot, label='目标函数 $f(x) = (x - 3)^2 + 2$')
plt.scatter(
x_values,
y_values,
color='red',
label='梯度下降路径',
zorder=5
)
plt.plot(
x_values,
y_values,
color='red',
linestyle='--',
linewidth=1,
alpha=0.6
)
plt.xlabel('x 值')
plt.ylabel('f(x) 值')
plt.title('梯度下降演示 (目标函数: $(x - 3)^2 + 2$)')
plt.legend()
plt.grid(True)
plt.show()
print(f"初始 x 值: {initial_x}")
print(f"学习率: {learning_rate}")
print(f"迭代次数: {num_iterations}")
print(f"最终 x 值: {x_values[-1]:.4f}")
print(f"最终 f(x) 值: {y_values[-1]:.4f}")输出结果:
1
2
3
4
5初始 x 值: 10.0
学习率: 0.1
迭代次数: 50
最终 x 值: 3.0001
最终 f(x) 值: 2.0000