def rehearse(self, docs, sgd=None, losses=None, config=None):
        """Make a "rehearsal" update to the models in the pipeline, to prevent
        forgetting. Rehearsal updates run an initial copy of the model over some
        data, and update the model so its current predictions are more like the
        initial ones. This is useful for keeping a pre-trained model on-track,
        even if you're updating it with a smaller set of examples.

        docs (iterable): A batch of `Doc` objects.
        drop (float): The droput rate.
        sgd (callable): An optimizer.
        RETURNS (dict): Results from the update.

        EXAMPLE:
            >>> raw_text_batches = minibatch(raw_texts)
            >>> for labelled_batch in minibatch(zip(train_docs, train_golds)):
            >>>     docs, golds = zip(*train_docs)
            >>>     nlp.update(docs, golds)
            >>>     raw_batch = [nlp.make_doc(text) for text in next(raw_text_batches)]
            >>>     nlp.rehearse(raw_batch)
        """
        # TODO: document
        if len(docs) == 0:
            return
        if sgd is None:
            if self._optimizer is None:
                self._optimizer = create_default_optimizer(Model.ops)
            sgd = self._optimizer
        docs = list(docs)
        for i, doc in enumerate(docs):
            if isinstance(doc, basestring_):
                docs[i] = self.make_doc(doc)
        pipes = list(self.pipeline)
        random.shuffle(pipes)
        if config is None:
            config = {}
        grads = {}

        def get_grads(W, dW, key=None):
            grads[key] = (W, dW)

        get_grads.alpha = sgd.alpha
        get_grads.b1 = sgd.b1
        get_grads.b2 = sgd.b2
        for name, proc in pipes:
            if not hasattr(proc, "rehearse"):
                continue
            grads = {}
            proc.rehearse(docs, sgd=get_grads, losses=losses, **config.get(name, {}))
            for key, (W, dW) in grads.items():
                sgd(W, dW, key=key)
        return losses
Make a "rehearsal" update to the models in the pipeline, to prevent
        forgetting. Rehearsal updates run an initial copy of the model over some
        data, and update the model so its current predictions are more like the
        initial ones. This is useful for keeping a pre-trained model on-track,
        even if you're updating it with a smaller set of examples.

        docs (iterable): A batch of `Doc` objects.
        drop (float): The droput rate.
        sgd (callable): An optimizer.
        RETURNS (dict): Results from the update.

        EXAMPLE:
            >>> raw_text_batches = minibatch(raw_texts)
            >>> for labelled_batch in minibatch(zip(train_docs, train_golds)):
            >>>     docs, golds = zip(*train_docs)
            >>>     nlp.update(docs, golds)
            >>>     raw_batch = [nlp.make_doc(text) for text in next(raw_text_batches)]
            >>>     nlp.rehearse(raw_batch)