Python 在我的梯度检查实现中,这些梯度差异是否可以接受?

Python 在我的梯度检查实现中,这些梯度差异是否可以接受?,python,machine-learning,gradient-descent,Python,Machine Learning,Gradient Descent,我正在构建一个带有几个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.61692922

我正在构建一个带有几个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

在研究了梯度接近于零的原因后,我发现我的网络可能遇到了梯度高原的问题。解决方案是添加以下一项或全部内容:动量、RMS道具或Adam优化。我将尝试实现Adam优化,因为它封装了动量和RMS prop,如果这样做有效,我将标记我的答案为正确


后续编辑:不幸的是,当我实现Adam时,这只会导致渐变爆炸。即使学习率很低,1e-5。通过增加两个conv->relu->pool层,我确实在增加数值渐变方面取得了一些进展。但不管怎样,梯度计算似乎都不对。问题一定出在我的backprop实现上。

您可以使用此公式查看这些数字之间的相对误差:

差异=(|梯度-计算的|梯度)/(|梯度+|计算的|梯度)

如果实施正确,预计将低于1e-7


请参阅:

1e-11基本上是0,因此我认为您正在检查的数据没有什么意义(如果所有“真”渐变都低于有趣的精度,同样可以接受的代码是“返回0”)。数据是一组图像,每个图像代表7个类中的一个。我以前训练过模型,以便准确预测课程(仅在训练集中)。你能解释一下在这种情况下你所说的“毫无意义”是什么意思吗?谢谢。您所指的输出中显示的梯度非常小,因此同样正确的梯度估计将输出0。我猜你的学习速度对于处理这个问题来说是巨大的,或者在以后的训练中这些梯度会增长;或者这些是退化的10维,在剩余的维度上,值更高。无论哪种方式——为了回答序言中提出的问题(检查梯度计算的数值精度,总是输出1e-11阶值的东西将很难检查估计),我对ML和更复杂的东西,如CNN,都是新手。我正试图从零开始建立自己的公司。我注意到,如果我在最初的CNN之后移除ReLU激活,训练速度会快得多。我发布了上面的架构以供参考,而不是打印梯度的每个维度-测量梯度之间的L2距离(或其他标准/统计,如最小/最大误差等)。这会给你更合适的图片。