所谓梯度 (Gradient Descent)的概念,通常出现在损失函数优化中。而我们常说的梯度,通常会和函数偏导数联系在一起,我们定义一个函数 J ( θ 0 , θ 1 , . . . . . . , θ n ) J(\theta_0, \theta_1,......, \theta_n) J(θ0,θ1,......,θn)关于参数 θ j \theta_j θj的梯度为:
∂ J ( θ 0 , θ 1 , . . . . . . , θ n ) ∂ θ j \frac{\partial J(\theta_0, \theta_1,......, \theta_n)}{\partial \theta_j} ∂θj∂J(θ0,θ1,......,θn)
沿着梯度方向,函数值增长最快。注意这里是增长最快,所以我们通常所说的梯度下降法,都是沿着梯度反方向更新参数,也就是说:
θ j : = θ j − α ∂ J ( θ 0 , θ 1 , . . . . . . , θ n ) ∂ θ j . \theta_j := \theta_j - \alpha\frac{\partial J(\theta_0, \theta_1,......, \theta_n)}{\partial \theta_j}. θj:=θj−α∂θj∂J(θ0,θ1,......,θn).
这里, α \alpha α通常叫做步长或者学习率,用于控制参数变动的幅度。这是一个需要调整的参数, α \alpha α设置过大,会使得参数一下子变化太大,可能会让函数跳过局部最小点,从而永远找不到(局部)极小点; α \alpha α设置过小,会使得参数变化太小,每次更新只变化一点点,学习太慢,需要很长时间才能找到极小点。
上式中给出了一个参数的更新公式。那么在实际算法中,我们需要对多个参数进行更新。
那么正确的更新顺序为:
1. t e m p 0 : = ∂ J ( θ 0 , θ 1 , . . . . . . , θ n ) ∂ θ j . 1. temp0 := \frac{\partial J(\theta_0, \theta_1,......, \theta_n)}{\partial \theta_j}. 1.temp0:=∂θj∂J(θ0,θ1,......,θn).
2. t e m p 1 : = ∂ J ( θ 0 , θ 1 , . . . . . . , θ n ) ∂ θ i . 2. temp1 := \frac{\partial J(\theta_0, \theta_1,......, \theta_n)}{\partial \theta_i}. 2.temp1:=∂θi∂J(θ0,θ1,......,θn).
3. θ j : = θ j − α t e m p 0. 3. \theta_j := \theta_j-\alpha temp0. 3.θj:=θj−αtemp0.
4. θ i : = θ i − α t e m p 1. 4. \theta_i := \theta_i-\alpha temp1. 4.θi:=θi−αtemp1.
也就是说,我们需要先计算好当前状态下每个参数的梯度,再进行参数更新。而不能根据顺序1,3,2,4,计算一个梯度就更新一个梯度。这就是所谓的同步更新。
最简单的特征缩放为 x i / s x_i/s xi/s, s s s为某个值,能够把 x i x_i xi缩放至一个较为合理的范围。
常用的缩放还有:
我们刚才讨论的都是批量梯度下降,也就是说在每一步的梯度下降中都使用所有的训练样本。因为我们通常所用的损失函数 J θ ( x 0 , x 1 , x 2 , . . . . . . , x n ) J_\theta(x_0, x_1, x_2,......,x_n) Jθ(x0,x1,x2,......,xn)包含了所有训练样本 ( x 0 , x 1 , x 2 , . . . . . . , x n ) (x_0,x_1,x_2,......,x_n) (x0,x1,x2,......,xn)。