-
Notifications
You must be signed in to change notification settings - Fork 0
/
gradient_descent.py
104 lines (83 loc) · 2.77 KB
/
gradient_descent.py
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
一维问题的梯度下降法示例
"""
def func_1d(x):
"""
目标函数
:param x: 自变量,标量
:return: 因变量,标量
"""
return x ** 2 + 1
def grad_1d(x):
"""
目标函数的梯度
:param x: 自变量,标量
:return: 因变量,标量
"""
return x * 2
def gradient_descent_1d(grad, cur_x=0.1, learning_rate=0.01, precision=0.0001, max_iters=10000):
"""
一维问题的梯度下降法
:param grad: 目标函数的梯度
:param cur_x: 当前 x 值,通过参数可以提供初始值
:param learning_rate: 学习率,也相当于设置的步长
:param precision: 设置收敛精度
:param max_iters: 最大迭代次数
:return: 局部最小值 x*
"""
for i in range(max_iters):
grad_cur = grad(cur_x)
if abs(grad_cur) < precision:
break # 当梯度趋近为 0 时,视为收敛
cur_x = cur_x - grad_cur * learning_rate
print("第", i, "次迭代:x 值为 ", cur_x)
print("局部最小值 x =", cur_x)
return cur_x
# if __name__ == '__main__':
# gradient_descent_1d(grad_1d, cur_x=10, learning_rate=0.4, precision=0.000001, max_iters=10000)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
二维问题的梯度下降法示例
"""
import math
import numpy as np
def func_2d(x):
"""
目标函数
:param x: 自变量,二维向量
:return: 因变量,标量
"""
return - math.exp(-(x[0] ** 2 + x[1] ** 2))
def grad_2d(x):
"""
目标函数的梯度
:param x: 自变量,二维向量
:return: 因变量,二维向量
"""
deriv0 = 2 * x[0] * math.exp(-(x[0] ** 2 + x[1] ** 2))
deriv1 = 2 * x[1] * math.exp(-(x[0] ** 2 + x[1] ** 2))
return np.array([deriv0, deriv1])
def gradient_descent_2d(grad, cur_x=np.array([0.1, 0.1]), learning_rate=0.01, precision=0.0001, max_iters=10000):
"""
二维问题的梯度下降法
:param grad: 目标函数的梯度
:param cur_x: 当前 x 值,通过参数可以提供初始值
:param learning_rate: 学习率,也相当于设置的步长
:param precision: 设置收敛精度
:param max_iters: 最大迭代次数
:return: 局部最小值 x*
"""
print(f"{cur_x} 作为初始值开始迭代...")
for i in range(max_iters):
grad_cur = grad(cur_x)
if np.linalg.norm(grad_cur, ord=2) < precision:
break # 当梯度趋近为 0 时,视为收敛
cur_x = cur_x - grad_cur * learning_rate
print("第", i, "次迭代:x 值为 ", cur_x)
print("局部最小值 x =", cur_x)
return cur_x
if __name__ == '__main__':
gradient_descent_2d(grad_2d, cur_x=np.array([1, -1]), learning_rate=0.2, precision=0.000001, max_iters=10000)