梯度下降算法 (机器学习)
机器学习中的梯度下载算法
本人在学习机器学习时, 线性回归学习算法中有使用梯度下降算法, 在线性回归学习算法中我们假设一个预测函数: h ( θ ) = θ 0 + θ 1 x h(\theta)=\theta_0+\theta_1x h(θ)=θ0+θ1x(或者说 h ( θ ) = θ 0 + ∑ i = 1 n θ i x i h(\theta)=\theta_0+\sum_{i=1}^n\theta_ix_i h(θ)=θ0+∑i=1nθixi))公式中 θ i \theta_i θi,然后我们用这个预测函数与训练集计算出误差,这个误差函数(cost function): J ( θ ) = 1 2 m ∑ i = 0 n ( h ( θ ) − y i ) 2 J(\theta)=\frac{1}{2m}\sum_{i=0}^n(h(\theta)-y_i)^2 J(θ)=2m1∑i=0n(h(θ)−yi)2(公式里的 y i y_i yi是训练集的结果)–将预测函数代入 J ( θ ) = 1 2 m ∑ i = 0 n ( θ 0 + θ 1 x − y i ) 2 J(\theta)=\frac{1}{2m}\sum_{i=0}^n(\theta_0+\theta_1x-y_i)^2 J(θ)=2m1∑i=0n(θ0+θ1x−yi)2,在这个损失函数中 x i , y i x_i,y_i xi,yi都是训练集中的值,是已知的,我们需要求出 θ 0 , θ 1 \theta_0, \theta_1 θ0,θ1的值,使得损失函数最小,也就是预测最准确。而我们要求出 θ 0 , θ 1 \theta_0, \theta_1 θ0,θ1最佳的值,就需要求出梯度,然后使 θ 0 , θ 1 \theta_0, \theta_1 θ0,θ1往梯度下降的方向移动,这样损失函数也会不断下降,直到局部最小值。学习到的 h ( θ ) = θ 0 + θ 1 x h(\theta)=\theta_0+\theta_1x h(θ)=θ0+θ1x函数就是最佳预测函数。
梯度的解释
梯度是数学中的一个概念,比较形象的解释就是将函数比喻成不平的曲面(或曲线),我们处于某个点,那么我们要从这个点移动到更低位置的点,而梯度的方向是往高处移动,那我们要移动到低处就是往梯度的反方向移动,也就是梯度下降。
- 在单变量的函数中,梯度其实就是函数的微分,代表着函数在某个给定点的切线的斜率
- 在多变量函数中,梯度是一个向量,向量有方向,梯度的方向就指出了函数在给定点的上升最快的方向,而这个向量就是由各个变量的偏微分组成: ∇ J ( θ ) = ⟨ ∂ J ∂ θ 0 , ∂ J ∂ θ 1 , ∂ J ∂ θ 2 … ⟩ \nabla J(\theta) = \langle \frac{\partial J}{\partial\theta_0}, \frac{\partial J}{\partial\theta_1}, \frac{\partial J}{\partial\theta_2} \ldots \rangle ∇J(θ)=⟨∂θ0∂J,∂θ1∂J,∂θ2∂J…⟩(其实就是雅可比矩阵)
算法数学原理
在算法概述中我们知道梯度下降算法是用于优化损失函数 J ( θ ) = 1 2 m ∑ i = 0 n ( θ 0 + θ 1 x − y i ) 2 J(\theta)=\frac{1}{2m}\sum_{i=0}^n(\theta_0+\theta_1x-y_i)^2 J(θ)=2m1∑i=0n(θ0+θ1x−yi)2中的参数 θ 0 , θ 1 \theta_0, \theta_1 θ0,θ1值,使得这个损失函数的值最小或者说局部最小。
- 我们假设初始的预测函数为
h
(
θ
)
=
θ
0
(
1
)
+
θ
1
(
1
)
x
h(\theta) = \theta_0^{(1)} + \theta_1^{(1)}x
h(θ)=θ0(1)+θ1(1)x
我们的损失函数就是: J ( θ ) ( 1 ) = 1 2 m ∑ i = 0 n ( θ 0 ( 1 ) + θ 1 ( 1 ) x − y i ) 2 J(\theta)^{(1)}=\frac{1}{2m}\sum_{i=0}^n(\theta_0^{(1)}+\theta_1^{(1)}x-y_i)^2 J(θ)(1)=2m1∑i=0n(θ0(1)+θ1(1)x−yi)2 - 我们就可以算出 J ( θ ) ( 1 ) J(\theta)^{(1)} J(θ)(1)的梯度 ⟨ ∂ J ∂ θ 0 ( 1 ) , ∂ J ∂ θ 1 ( 1 ) ⟩ \langle \frac{\partial J}{\partial\theta_0^{(1)}}, \frac{\partial J}{\partial\theta_1^{(1)}} \rangle ⟨∂θ0(1)∂J,∂θ1(1)∂J⟩
- 然后我们根据公式移动参数
θ
0
,
θ
1
\theta_0, \theta_1
θ0,θ1的值
公式:
θ j ( n + 1 ) = θ j ( n ) − α ∂ J ( θ j ) ∂ θ j (1) \theta_j^{(n+1)} = \theta_j^{(n)} - \alpha\frac{\partial J(\theta_j^{})}{\partial\theta_j}\tag{1} θj(n+1)=θj(n)−α∂θj∂J(θj)(1) - 根据第三步骤的不断迭代, θ j \theta_j θj可以形成一个队列: θ 0 , θ 1 , … θ n \theta_0, \theta_1, \ldots \theta_n θ0,θ1,…θn 并且该队列是一个单调递增(梯度为负数)或递减(梯度为正)的,而损失函数的值也会形成一个队列 J ( θ ) ( 0 ) , J ( θ ) ( 0 ) , … J ( θ ) ( n ) J(\theta)^{(0)}, J(\theta)^{(0)}, \ldots J(\theta)^{(n)} J(θ)(0),J(θ)(0),…J(θ)(n),而这个队列是单调递减的。
公式(1)的说明 :
- 公式中 α \alpha α是损失函数的下降速率,机器学习中我们称为学习速率(the learning rate)
- 关于公式1为什么是用减去 α \alpha α倍的梯度,我们可以用单变量函数作比方,假设预测函数就是个普通的二维坐标中的直线,那么损失函数就是个普通二次函数,函数图形就是个抛物线,那么在一个点的斜率就是该点的梯度,那么情况就有两种:斜率为正,斜率为负。描述图形如同下面 图1(梯度为正)
图1
θ j ( n + 1 ) = θ j ( n ) − α ∂ J ( θ j ) ∂ θ j (1) \theta_j^{(n+1)} = \theta_j^{(n)} - \alpha\frac{\partial J(\theta_j^{})}{\partial\theta_j}\tag{1} θj(n+1)=θj(n)−α∂θj∂J(θj)(1)
下图解释为什么是减去 α \alpha α倍的梯度。
局部最小或最小
下图可以看出不同的起始点通过梯度下降算法最后得到的最小值是不同的,算法迭代得到的最小值是局部最小值(可能正好是全局最小值)。
算法的代码实现(python)
# 梯度下降算法
def gradientDescent(X,y,theta,alpha,num_iters):
# theta 是 向量多个未知的theta参数 y = theta_1 * x_1 + theta_2 * x_2 ........
# alpha 是学习率
# num_iters 迭代次数
m = len(y)
n = len(theta)
temp = np.matrix(np.zeros((n,num_iters))) # 暂存每次迭代计算的theta,转化为矩阵形式
J_history = np.zeros((num_iters,1)) #记录每次迭代计算的代价值
for i in range(num_iters):
# hypothesis - 假设
# 计算内积,matrix可以直接乘 ,计算出的就是当前的参数预测到的Y值向量
h = np.dot(X,theta)
# h-y 就是损失值
# np.dot(np.transpose(X),h-y) 这个是计算梯度
temp[:,i] = theta - ((alpha/m)*(np.dot(np.transpose(X),h-y))) #梯度的计算
theta = temp[:,i]
J_history[i] = computerCost(X,y,theta) #调用计算代价函数
print('.', end=' ')
return theta,J_history
计算梯度说明
np.dot(np.transpose(X),h-y)
这个计算出梯度的解释: