梯度的数值逼近
在实施dropout时,由于无法保证dropout是否正确,需要梯度检验来确保网络的正确。具体步骤是我们先通过双边差分计算出一个近似的梯度,和代码计算出的梯度比较,如果二者差的绝对值小于一个阈值,就可以认定计算正确。设函数f如下图所示:
对点
θ
\theta
θ加减
ε
\varepsilon
ε,其中
ε
\varepsilon
ε越小越好,由拉格朗日中值定理得:
f
′
(
θ
)
=
f
(
θ
+
ε
)
−
f
(
θ
−
ε
)
2
ε
=
3.000
f^{'}(\theta) = \frac{f(\theta + \varepsilon) - f(\theta - \varepsilon)}{2\varepsilon}=3.000
f′(θ)=2εf(θ+ε)−f(θ−ε)=3.000
设程序中计算出的梯度为
g
′
(
θ
)
=
3.001
g^{'}(\theta) = 3.001
g′(θ)=3.001,则逼近误差为0.001。至于为什么使用双边差分而不是单边差分请看这篇文章,https://blog.csdn.net/kaede_xiao/article/details/115709852。
梯度检验
梯度检验步骤:
- 将矩阵
W
[
1
]
,
b
[
1
]
,
.
.
.
.
.
,
W
L
,
b
[
L
]
W^{[1]}, b^{[1]}, .....,W^{{L}},b^{[L]}
W[1],b[1],.....,WL,b[L]拼接成一个巨大的向量
θ
\theta
θ,现在代价函数变为如下:
J ( W [ 1 ] , b [ 1 ] , . . . , W [ l ] , b [ l ] ) = J ( θ ) J(W^{[1]}, b^{[1]},...,W^{[l]},b^{[l]}) = J(\theta) J(W[1],b[1],...,W[l],b[l])=J(θ) - 把矩阵 d W [ 1 ] , d b [ 1 ] , . . . . , d W [ L ] , d b [ l ] dW^{[1]}, db^{[1]}, ....,dW^{[L]}, db^{[l]} dW[1],db[1],....,dW[L],db[l]拼接成一个巨大的向量 d θ d\theta dθ,它和 θ \theta θ有相同得长度。
- 检验梯度
for each i:
d θ a p p e a r [ i ] = J ( θ 1 , θ 2 , . . . . , θ i + ε , . . . . . . ) − J ( θ 1 , θ 2 , . . . . , θ i − ε , . . . . . . ) 2 ε d\theta_{appear}[i] = \frac{J(\theta_1, \theta_2,...., \theta_i + \varepsilon, ......) - J(\theta_1, \theta_2,...., \theta_i - \varepsilon, ......)}{2 \varepsilon} dθappear[i]=2εJ(θ1,θ2,....,θi+ε,......)−J(θ1,θ2,....,θi−ε,......)
此时的 d θ a p p e a r [ i ] d\theta_{appear}[i] dθappear[i]应该逼近于 d θ [ i ] d\theta[i] dθ[i]。对于两个向量来说就是判断两个向量是否接近,公式如下:
L = ∣ ∣ d θ a p p e a r − d θ ∣ ∣ 2 ∣ ∣ d θ a p p e a r ∣ ∣ 2 + ∣ ∣ d θ ∣ ∣ 2 L = \frac{||d\theta_{appear}-d\theta||_{2}}{||d\theta_{appear}||_2 + ||d\theta||_2} L=∣∣dθappear∣∣2+∣∣dθ∣∣2∣∣dθappear−dθ∣∣2
根据L值大小判断代码运行是否正确。
梯度检验使用技巧和注意事项
- 不要在训练中使用梯度检验,仅仅用于debug—因为梯度检验算起来很慢。
- 如果算法出错的话,检查每一个 θ i \theta_i θi来查找出bug。
- 不要忘记正则项。
- 梯度检验不能和dropout同时使用,因为使用dropout的网络代价函数J是不确定的,双边差分计算结果会随之变化。使用时先关闭dropout,然后进行梯度检验确保算法正确,再打开dropout。
- 在随机初始化参数时运行梯度检验,然后反复训练网络,再重新运行梯度检验。