def get_numerical_gradient(f, tensors, delta=1e-5):
    # buffer for gradients
    gradients = []
    for i in range(len(tensors)):
        tensors[i] = tensors[i].astype(np.float64)
        gradients.append(np.zeros(tensors[i].shape))

    # iterate throuth each tensor
    for tensor, gradient in zip(tensors, gradients):

        tensor_flat = tensor.reshape((-1, ))
        gradient_flat = gradient.reshape((-1, ))

        # iterate throuth each element
        for idx in range(len(tensor_flat)):
            # backup
            backup = tensor_flat[idx]
            # increment
            tensor_flat[idx] = tensor_flat[idx] + delta
            f_inc = np.sum(f(np, *tensors))
            # decrement
            tensor_flat[idx] = backup - delta
            f_dec = np.sum(f(np, *tensors))
            # recover
            tensor_flat[idx] = backup
            # gradient
            gradient_flat[idx] = (f_inc - f_dec) / (2.0 * delta)

    return gradients
sum all of f's elements to make the last layer error as one
dataset/ETHPy150Open NervanaSystems/neon/neon/backends/tests/test_autodiff.py/get_numerical_gradient