def learning_rate_linearly_decayed(initial_rate, final_rate=0,
    max_iterations=20):
    """ A generator function that, starting from `initial_rate`, decays the
    learning rate linearly. After `max_iterations` it always yields final_rate.

    It can be passed as ``learning_rate`` argument to :py:meth:`.SGD.train` .

    Formally, it computes :math:`\\epsilon_k = (1 - \\alpha)\\epsilon_0+
    \\alpha \\epsilon_\\tau`, where :math:`k` is the iteration number,
    :math:`\\tau` is ``max_iterations``, :math:`\\epsilon_0` is
    ``initial_rate``, :math:`\\epsilon_\\tau` is ``final_rate``, and
    :math:`\\alpha=\\frac{k}{\\tau}`.


    :param initial_rate: the rate at the first iteration.
    :param final_rate: the rate to return after the maximum number of
        iterations.
    :param max_iterations: the maximum number of iterations.
    """
    for i in range(max_iterations):
        alpha = i / max_iterations
        rate = (1.0 - alpha) * initial_rate + alpha * final_rate
        yield rate
    while True:
        yield final_rate
