我正在构建一个带有几个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发布于 2018-04-23 22:23:05
在研究了梯度接近于零的原因后,我发现我的网络可能正在遭受梯度高原的问题。对此的解决方案是添加以下一项或全部内容:动量、RMS属性或Adam优化。我将尝试实现Adam优化,因为它封装了动量和RMS属性,如果它有效,我会将我的答案标记为正确。
后续编辑:不幸的是,当我实现Adam时,这只会导致渐变的爆炸。即使在非常小的学习率1e-5的情况下。我确实通过增加两个conv->relu->pool层来增加数值梯度。但无论哪种方式,梯度计算似乎都不正确。问题一定是我的backprop实现出了问题。
发布于 2020-09-23 12:33:14
您可以使用此公式查看这些数字之间的相对误差:
diff = (|grads - computed_grad|)/(|grads| + |computed_grad|)
在正确实施的情况下,预计它将小于1e-7。
请参阅:https://towardsdatascience.com/how-to-debug-a-neural-network-with-gradient-checking-41deec0357a9
https://stackoverflow.com/questions/49971487
复制相似问题