机器学习2——梯度下降
梯度下降是机器学习很核心的思想,对初值依赖很强
甚至觉得很多机器学习,强化学习的算法就是
-
建模(这当然不容易)
-
找指标(损失函数/代价函数/成本函数/cost function/loss function),这个指标就是把实际问题转化成优化问题后的目标函数
-
然后不同的处理思路,优化算法,最底层的操作还是梯度下降,找最值
前言
一个函数L()或者 J(),常见的就是这两种写法。
- 函数会强假设是凸函数,有的算法会拓展,不满足强假设,算法也能表现良好,但是怎么说呢,随机性太强了,尤其有很多局部最优值的时候,最好还是满足凸性假设
然后找让函数最小或者最大(这取决于问题的抽象)的参数,下面就拿最小来说
一般是给参数设置初始值(随机性的开始,苦涩.jpg)
然后更新参数,让函数更小,直到满足精度要求
- 满足迭代次数,停止更新
- 柯西思想,相邻两部的函数值之间,误差有上界
一、算法
某个参数 θ ∈ Θ \theta\in \Theta θ∈Θ (参数集合)的更新
θ
n
e
w
=
θ
o
l
d
−
α
∂
J
(
Θ
)
∂
θ
\theta_{new}=\theta_{old}-\alpha \frac{\partial J(\Theta ) }{\partial \theta }
θnew=θold−α∂θ∂J(Θ)
步长参数(学习率)
α
\alpha
α的设置要随着代价函数的变化设置适合的值
- 在更新的时候,
- 同步就是所有参数都一起更新(用同一个J,这个时候J的参数是这一次没更新前的),只有参数在优化
- 异步就是,更新一个参数,J里的这个参数就立刻同步更新(参数和代价函数都在优化)
细说
从最简单的二次函数
a
x
2
+
b
x
+
c
ax^{2} +bx+c
ax2+bx+c 出发,这个时候把x看作参数,对x的导数就是某一点的斜率,x0是初始值
初始值在对称轴左侧的话,思路是类似的
- 更高维的话,对某个参数求导时,其他参数是固定的,就可以抽象成二次函数这种类似的,只能说类似的去理解,不能直接等价看
- 这样其实就很好理解,步长太大,一步更新太多,就可能跳过最小值,步长太小,就会非常慢,而复杂的算法是要很多次梯度下降的,效率会非常低下
二、代码
1.线性回归模型
import numpy as np
def gradient_descent(X, y, learning_rate=0.01, n_iters=1000):
"""
参数:
X -- 输入数据的特征矩阵,维度为 (n_samples, n_features)
y -- 输入数据的目标向量,维度为 (n_samples,)
learning_rate -- 学习率,用于控制参数更新的步长
n_iters -- 迭代次数,用于控制算法的收敛速度
返回:
weights -- 优化后的权重参数
bias -- 优化后的偏置参数
loss_history -- 每次迭代的损失值列表,用于观察收敛情况
"""
n_samples, n_features = X.shape
weights = np.zeros(n_features) # 初始化权重参数为0
bias = 0 # 初始化偏置参数为0
loss_history = [] # 用于存储每次迭代的损失值
for _ in range(n_iters):
y_predicted = np.dot(X, weights) + bias # 计算预测值
# 计算损失函数对权重和偏置的梯度
dw = (1 / n_samples) * np.dot(X.T, (y_predicted - y))
db = (1 / n_samples) * np.sum(y_predicted - y)
# 根据梯度更新权重和偏置
weights -= learning_rate * dw
bias -= learning_rate * db
# 计算当前迭代的损失值,并记录下来
loss = (1 / n_samples) * np.sum((y_predicted - y) ** 2)
loss_history.append(loss)
return weights, bias, loss_history
# 示例数据
X = np.array([[1, 1], [2, 2], [3, 3], [4, 4]]) # 输入数据特征
y = np.array([2, 4, 6, 8]) # 目标值
# 使用梯度下降算法进行参数优化
weights, bias, loss_history = gradient_descent(X, y)
# 输出优化后的权重和偏置
print("Weights:", weights)
print("Bias:", bias)
2.更一般
import numpy as np
def function(x):
""" 定义目标函数 f(x) = x^2 """
return x**2
def gradient(x):
""" 定义目标函数的梯度 f'(x) = 2x """
return 2 * x
def gradient_descent(start_point, learning_rate, num_iterations):
""" 实现梯度下降算法 """
x = start_point
history = []
for _ in range(num_iterations):
grad = gradient(x)
x -= learning_rate * grad
history.append((x, function(x)))
return x, history
# 参数设定
start_point = 3.0 # 初始点
learning_rate = 0.1 # 学习率
num_iterations = 100 # 迭代次数
# 运行梯度下降
min_x, history = gradient_descent(start_point, learning_rate, num_iterations)
print(f"Minimum point found at x={min_x}")
一般来讲,图就是随着迭代,损失函数的下降