'Backpropagate through this layer.
Args:
step: The training step. Needed because some hyperparameters depend on
which training step they are being used in.'

def ComputeDown(self, layer, step):

    if layer.is_input:
        return
    h = layer.hyperparams
    loss = None
    if h.fast_dropout:
        if layer.hyperparams.sparsity:
            layer.AddSparsityGradient()
        loss = self.GetFastDropoutGradient(layer)
    elif layer.is_output:
        loss = layer.GetLoss(get_deriv=True)
    else:
        if layer.hyperparams.sparsity:
            layer.AddSparsityGradient()
        layer.ComputeDeriv()
    for edge in layer.incoming_edge:
        if (edge.conv or edge.local):
            AccumulateConvDeriv(edge.node1, edge, layer.deriv)
        else:
            self.AccumulateDeriv(edge.node1, edge, layer.deriv)
        self.UpdateEdgeParams(edge, layer.deriv, step)
    self.UpdateLayerParams(layer, step)
    return loss
