您可以在我的个人博客 blog.pengwill.info 获得更好的阅读体验。
思维导图
回顾
在Step3中,我们需要根据loss function,对参数
θ
\theta
θ进行优化,使用到的方法就是梯度下降算法。可以用如下的函数表示。
θ
∗
=
arg
min
θ
L
(
θ
)
\theta^{*}=\arg \min _{\theta} L(\theta)
θ∗=argθminL(θ)
其中
L
L
L表示loss function,
θ
\theta
θ表示待优化的参数。
优化的方法是使参数
θ
\theta
θ向其梯度方向减小,具体来说
θ
:
=
θ
−
η
∇
L
(
θ
)
\theta:=\theta-\eta \nabla L\left(\theta\right)
θ:=θ−η∇L(θ)
η
\eta
η称为学习速率,是一个超参数,需要手动进行调整。
Tip1: 调整学习速率
learning rate 太小,loss下降太慢;learning rate太大,loss震荡或者增加。建议画出随着loss值随迭代次数变化的曲线,根据曲线进行调整。
learning rate调整建议
- 将learning rate随迭代次数逐渐减小。在刚开始时候希望收敛的步子大一点,而在后面的时候learning rate随迭代次数逐渐减小。比如 η = η t + 1 \eta = \frac{\eta}{\sqrt{t+1}} η=t+1η,其中 t t t为迭代次数。
- 不同的参数设置不同的learning rate。
Adagrad
对每个参数设置不同的learning rate。在每次迭代时,将学习速率除以偏导和的均方根。
即
θ
i
:
=
θ
i
−
η
σ
∂
L
∂
θ
i
\theta_i:=\theta_i-\frac{\eta}{\sigma} \frac{\partial L}{\partial \theta_i}
θi:=θi−ση∂θi∂L
其中
σ
\sigma
σ为Loss function对
θ
i
\theta^i
θi偏导累计和的均方根。decay项(
1
t
+
1
\frac{1}{\sqrt{t+1}}
t+11)和原本
σ
\sigma
σ中的项相消掉了。
Tip2: 随机梯度下降
传统梯度下降,迭代时需要根据所有的样本来更新loss function,进而根据loss function对参数的偏导更新参数。当样本非常多的时候,单次迭代就可能花费大量的时间。
随机梯度下降,迭代时选择一个样本点来更新loss function,再根据loss function对参数的偏导更新参数值。这样的优点是速度更快。但是由于样本中可能含有噪声,单次迭代不一定向函数减小最快的方向更新,甚至有可能迭代后loss值会增加。
Tip3: 特征缩放
采用特征缩放是为了避免数据大小或者数据的量纲不同对学习过程造成的影响。
假如当前的loss function为 L ( θ ) = θ 0 + x 1 θ 1 + x 2 θ 2 L(\theta) =\theta_0+ x_1\theta_1+x_2\theta_2 L(θ)=θ0+x1θ1+x2θ2。其中属性 x 1 x_1 x1的变化范围为 − 1 ≤ x 1 ≤ 1 -1\le x_1\le1 −1≤x1≤1, x 2 x_2 x2的变化范围为 100 ≤ x 2 ≤ 1000 100\le x_2 \le 1000 100≤x2≤1000。在学习过程中,因为 ∣ x 1 ∣ ≤ ∣ x 2 ∣ |x_1|\le|x_2| ∣x1∣≤∣x2∣,所以只要 θ 2 \theta_2 θ2略微变化一点,就会对 L L L函数值造成很大影响;相反, θ 1 \theta_1 θ1的变化对函数值造成的影响不大。
我们更加希望数据的每个属性的尺度都接近。
标准化
对数据的每一个特征值,减去特征的均值,除以特征的标准差,最后可以使这个特征的均值为0,方差为1。
梯度下降的数学原理
泰勒展开
若一元函数
h
(
x
)
h(x)
h(x)在
x
=
x
0
x=x_0
x=x0处无限可导,则可以用多项式来逼近函数
h
(
x
)
h(x)
h(x)
h
(
x
)
=
∑
k
=
0
∞
h
(
k
)
(
x
0
)
k
!
(
x
−
x
0
)
k
h(x)=\sum_{k=0}^\infty\frac{h^{(k)}(x_0)}{k!}(x-x_0)^k
h(x)=k=0∑∞k!h(k)(x0)(x−x0)k
二元函数的泰勒展开为:
h
(
x
,
y
)
=
∑
k
=
0
∞
k
!
∂
k
h
∂
x
(
x
−
x
0
)
+
k
!
∂
k
h
∂
y
(
y
−
y
0
)
h(x, y) = \sum_{k=0}^\infty k!\frac{\partial^kh}{\partial x}(x-x_0)+k!\frac{\partial^kh}{\partial y}(y-y_0)
h(x,y)=k=0∑∞k!∂x∂kh(x−x0)+k!∂y∂kh(y−y0)
梯度下降算法在计算损失函数值时候,实际上为在原来参数点的一阶展开,即
L
(
θ
)
≈
L
(
a
,
b
)
+
∂
L
(
a
,
b
)
∂
θ
1
(
θ
1
−
a
)
+
∂
L
(
a
,
b
)
∂
θ
2
(
θ
2
−
b
)
\mathrm{L}(\theta) \approx \mathrm{L}(a, b)+\frac{\partial \mathrm{L}(a, b)}{\partial \theta_{1}}\left(\theta_{1}-a\right)+\frac{\partial \mathrm{L}(a, b)}{\partial \theta_{2}}\left(\theta_{2}-b\right)
L(θ)≈L(a,b)+∂θ1∂L(a,b)(θ1−a)+∂θ2∂L(a,b)(θ2−b)
泰勒展开只在接近展开点的处的函数值是近似准确的,故需要对更新参数时加以限制,以保证在展开点附近。我们希望参数更新的时候,整体的函数值减小,即
L
(
θ
)
−
L
(
a
,
b
)
≈
∂
L
(
a
,
b
)
∂
θ
1
(
θ
1
−
a
)
+
∂
L
(
a
,
b
)
∂
θ
2
(
θ
2
−
b
)
<
0
∂
L
(
a
,
b
)
∂
θ
1
(
Δ
θ
1
)
+
∂
L
(
a
,
b
)
∂
θ
2
(
Δ
θ
2
)
<
0
∇
L
⋅
Δ
θ
<
0
\mathrm{L}(\theta) - \mathrm{L}(a, b) \approx \frac{\partial \mathrm{L}(a, b)}{\partial \theta_{1}}\left(\theta_{1}-a\right)+\frac{\partial \mathrm{L}(a, b)}{\partial \theta_{2}}\left(\theta_{2}-b\right) < 0 \\ \frac{\partial \mathrm{L}(a, b)}{\partial \theta_{1}}\left(\Delta\theta_1\right)+\frac{\partial \mathrm{L}(a, b)}{\partial \theta_{2}}\left(\Delta\theta_2\right) < 0 \\ \nabla L · \Delta\theta < 0
L(θ)−L(a,b)≈∂θ1∂L(a,b)(θ1−a)+∂θ2∂L(a,b)(θ2−b)<0∂θ1∂L(a,b)(Δθ1)+∂θ2∂L(a,b)(Δθ2)<0∇L⋅Δθ<0
其中
∇
L
\nabla L
∇L是一个向量,当
Δ
θ
\Delta\theta
Δθ和
∇
L
\nabla L
∇L方向相反的时候,乘积为负值,且最大。故可以得出应该为梯度的反方向。同时需要注意,应该保证要在展开点的附近才可以,否则一阶泰勒展开不成立,则引入学习速率
η
\eta
η,即:
∇
L
⋅
η
Δ
θ
<
0
\nabla L · \eta \Delta\theta <0
∇L⋅ηΔθ<0
理论上需要保证无限接近展开点,计算出的值才是准确的,实际操作过程中,保证较小并且合适的学习速率就可以。