我正在构建一个带有几个FC层的CNN来预测图像中描绘的类。
架构:
X - > CNN - > ReLU - > POOL - > FC - > ReLU - > FC - > SOFTMAX - > Y_hat
我正在实施渐变检查以检查我的渐变下降的实现是否正确。我读到可接受的差异在10e-9的数量级。下面的差异是否可以接受?
Epoch: 0
Cost: 2.8568426944476157
Numerical Grad Computed Grad
-5.713070134419862e-11 -6.616929226765933e-11
-5.979710331310053e-11 -6.94999613415348e-11
-5.87722383797037e-11 -6.816769371198461e-11
-5.948114792212038e-11 -6.905587213168474e-11
-5.756886551189494e-11 -6.683542608243442e-11
-5.995452767971952e-11 -6.94999613415348e-11
-5.772401095738584e-11 -6.705747068735946e-11
-5.5480026579651e-11 -6.439293542825908e-11
-5.8138150324971285e-11 -6.727951529228449e-11
-5.76037967235867e-11 -6.683542608243442e-11
供参考,这是我的渐变检查实现:
def gradient_check(self, layer):
# get grads from layer
grads = layer.backward_cache['dW']
# flatten layer W
shape = layer.W.shape
W_flat = layer.W.flatten()
epsilon = 0.001
print('Numerical Grad', 'Computed Grad')
# loop through first few W's
for i in range(0, 10):
W_initial = W_flat[i]
W_plus = W_initial + epsilon
W_minus = W_initial - epsilon
W_flat[i] = W_plus
layer.W = W_flat.reshape(shape)
cost_plus = self.compute_cost(self.forward_propogate())
W_flat[i] = W_minus
layer.W = W_flat.reshape(shape)
cost_minus = self.compute_cost(self.forward_propogate())
computed_grad = (cost_plus - cost_minus) / (2 * epsilon)
print(grads.flatten()[i], computed_grad)
# reset layers W's
W_flat[i] = W_initial
layer.W = W_flat.reshape(shape)
return layer
答案 0 :(得分:1)
在研究了渐变壁橱的原因之后,我发现我的网络可能遇到了梯度高原的问题。解决方案是添加以下一项或全部:动量,RMS道具或亚当优化。我将尝试实现Adam优化,因为它封装了动量和RMS道具,如果这有效,我会将我的答案标记为正确。
后续编辑:不幸的是,当我实施Adam时,这只会导致爆炸性的渐变。即使学习率很低,1e-5也是如此。通过添加两个更多的conv-> relu->池层,我确实在增加数值梯度方面取得了一些进展。但无论哪种方式,梯度计算似乎都不正确。问题必须在于我实施backprop。
答案 1 :(得分:0)
您可以使用此公式查看这些数字之间的相对误差:
diff =(| grads-computing_grad |)/(| grads | + | computed_grad |)
通过正确的实现,预计该值将小于1e-7。
请参阅:MDN web docs