Exemplo n.º 1
0
def test_finite_differences():
    """Test gradient of loss function

    Assert that the gradient is almost equal to its finite differences
    approximation.
    """
    # Initialize the transformation `M`, as well as `X` and `y` and `NCA`
    rng = np.random.RandomState(42)
    X, y = make_classification()
    M = rng.randn(rng.randint(1, X.shape[1] + 1), X.shape[1])
    nca = NeighborhoodComponentsAnalysis()
    nca.n_iter_ = 0
    mask = y[:, np.newaxis] == y[np.newaxis, :]

    def fun(M):
        return nca._loss_grad_lbfgs(M, X, mask)[0]

    def grad(M):
        return nca._loss_grad_lbfgs(M, X, mask)[1]

    # compute relative error
    rel_diff = check_grad(fun, grad, M.ravel()) / np.linalg.norm(grad(M))
    np.testing.assert_almost_equal(rel_diff, 0., decimal=5)
Exemplo n.º 2
0
def test_finite_differences():
    """Test gradient of loss function

    Assert that the gradient is almost equal to its finite differences
    approximation.
    """
    # Initialize the transformation `M`, as well as `X` and `y` and `NCA`
    rng = np.random.RandomState(42)
    X, y = make_classification()
    M = rng.randn(rng.randint(1, X.shape[1] + 1),
                  X.shape[1])
    nca = NeighborhoodComponentsAnalysis()
    nca.n_iter_ = 0
    mask = y[:, np.newaxis] == y[np.newaxis, :]

    def fun(M):
        return nca._loss_grad_lbfgs(M, X, mask)[0]

    def grad(M):
        return nca._loss_grad_lbfgs(M, X, mask)[1]

    # compute relative error
    rel_diff = check_grad(fun, grad, M.ravel()) / np.linalg.norm(grad(M))
    np.testing.assert_almost_equal(rel_diff, 0., decimal=5)
Exemplo n.º 3
0
def test_finite_differences():
    r"""Test gradient of loss function

    Test if the gradient is correct by computing the relative difference
    between the projected gradient PG:

    .. math::

        PG = \mathbf d^{\top} \cdot \nabla
        \mathcal L(\mathbf x)

    and the finite differences FD:

    .. math::

        FD = \frac{\mathcal L(\mathbf x + \epsilon \mathbf d) -
        \mathcal L(\mathbf x - \epsilon \mathbf d)}{2 \epsilon}


    where :math:`d` is a random direction (random vector of shape `n_features`,
    and norm 1), :math:`\epsilon` is a very small number, :math:`\mathcal L` is
    the loss function and :math:`\nabla \mathcal L` is its gradient. This
    relative difference should be zero:

    .. math ::

        \frac{|PG -FD|}{|PG|} = 0


    """
    # Initialize `transformation`, `X` and `y` and `NCA`
    X = iris_data
    y = iris_target
    point = rng.randn(rng.randint(1, X.shape[1] + 1), X.shape[1])
    nca = NeighborhoodComponentsAnalysis(init=point)

    X, y, init = nca._validate_params(X, y)
    mask = y[:, np.newaxis] == y[np.newaxis, :]  # (n_samples, n_samples)
    nca.n_iter_ = 0

    point = nca._initialize(X, init)
    # compute the gradient at `point`
    _, gradient = nca._loss_grad_lbfgs(point, X, mask)

    # create a random direction of norm 1
    random_direction = rng.randn(*point.shape)
    random_direction /= np.linalg.norm(random_direction)

    # computes projected gradient
    projected_gradient = random_direction.ravel().dot(
                                      gradient.ravel())

    # compute finite differences
    eps = 1e-5
    right_loss, _ = nca._loss_grad_lbfgs(point + eps * random_direction, X,
                                         mask)
    left_loss, _ = nca._loss_grad_lbfgs(point - eps * random_direction, X,
                                        mask)
    finite_differences = 1 / (2 * eps) * (right_loss - left_loss)

    # compute relative error
    relative_error = np.abs(finite_differences - projected_gradient) / \
        np.abs(projected_gradient)
    np.testing.assert_almost_equal(relative_error, 0.)