梯度检测
概论
在进行BP算法进行训练时,但是在训练时是否出现错误我们也不清楚,训练一旦开始,我们就只能观测到输出信息,如何检测反向传播算法是否正确工作呢?
梯度检验来了,它通过拉格朗日定理检测偏导值与实际的偏导函数之间的误差大小来判断是否出现了错误。
还有一点,在现有的训练框架中,这些细节都被封装起来了,但是作为学习,还是有必要搞清楚的其原理实现的。
1 基础原理
1.1 拉格朗日中值定理
f ( θ + ε ) − f ( θ − ε ) 2 ε ≈ f ′ ( θ ) \frac{f(\theta + ε) -f(\theta - ε)}{2ε} \approx f'(\theta) 2εf(θ+ε)−f(θ−ε)≈f′(θ)
实际上,这个公式只是近似等于,而且成立的条件是ε趋向于0,要想使其成为恒等式,则要加上误差
f
(
θ
+
ε
)
−
f
(
θ
−
ε
)
2
ε
=
f
′
(
θ
)
+
O
(
ε
2
)
\frac{f(\theta + ε) -f(\theta - ε)}{2ε} = f'(\theta) + O(ε^{2})
2εf(θ+ε)−f(θ−ε)=f′(θ)+O(ε2)
1.2 验证公式
得到了恒等式,那么怎么评判是否合格呢?还需要将O(ε^2)标准化,那就要用到二范数,计算公式为:
所以令h(θ)
h
(
θ
)
=
f
(
θ
+
ε
)
−
f
(
θ
−
ε
)
2
ε
h(\theta)=\frac{f(\theta + ε) -f(\theta - ε)}{2ε}
h(θ)=2εf(θ+ε)−f(θ−ε)
则
∣
∣
h
(
θ
)
−
f
′
(
θ
)
∣
∣
2
∣
∣
h
(
θ
)
∣
∣
2
+
∣
∣
f
′
(
θ
)
∣
∣
2
\frac{||h(\theta)-f'(\theta)||_2}{||h(\theta)||_2 + ||f'(\theta)||_2}
∣∣h(θ)∣∣2+∣∣f′(θ)∣∣2∣∣h(θ)−f′(θ)∣∣2
到此处,就计算出了偏差值的标准化结果。
如果值小于10的-7次方则完全不用担心,如果数值过大,则需要检查下代码了。
2 梯度检验的实现
原理明白了,接下来该实现了
在实际操作中,肯定不止一个θ,定义J(θ)为损失函数
则上述公式就变成了
h
(
θ
i
)
=
J
(
θ
1
,
θ
2
,
θ
3
,
.
.
.
θ
i
+
ϵ
,
.
.
.
)
−
J
(
θ
1
,
θ
2
,
θ
3
,
.
.
.
θ
i
−
ϵ
,
.
.
.
)
2
ϵ
d
θ
i
=
∂
J
∂
θ
i
h(\theta_i) = \frac{J(\theta_1,\theta_2,\theta_3,...\theta_i+\epsilon,...)-J(\theta_1,\theta_2,\theta_3,...\theta_i-\epsilon,...)}{2\epsilon}\\ d\theta_i = \frac{\partial J}{\partial \theta_i}
h(θi)=2ϵJ(θ1,θ2,θ3,...θi+ϵ,...)−J(θ1,θ2,θ3,...θi−ϵ,...)dθi=∂θi∂J
于是乎:
d
i
f
f
e
r
e
n
c
e
=
∣
∣
h
(
θ
i
)
−
d
θ
i
∣
∣
2
∣
∣
h
(
θ
i
)
∣
∣
2
+
∣
∣
d
θ
i
∣
∣
2
<
t
h
r
e
s
h
o
l
d
difference = \frac{||h(\theta_i)-d\theta_i||_2}{||h(\theta_i)||_2+||d\theta_i||_2}<threshold
difference=∣∣h(θi)∣∣2+∣∣dθi∣∣2∣∣h(θi)−dθi∣∣2<threshold
代码表示为
for i =1 :n,
thetaPlus = theta;
thetaPlus(i) = thetaPlus(i);
thetaMinus = theta;
thetaMinus(i) =thetaMinus(i) - EPSILON;
gradApprox(i) = (J(thetaPlus) - J(thetaMinus)) / (2*EPSILON);
END
3 注意事项
1.只适用于调试阶段,训练阶段使用太耗费时间而且意义不大
2.不能与dropout同时使用,使用dropout会使得损失函数变得不明确,从而无法使用该方法检测
3.如果使用L2正则项,还需要加上L2正则项