code: def fit(epochs:int, learn:BasicLearner, callbacks:Optional[CallbackList]=None, metrics:OptMetrics=None)->None:
      "Fit the `model` on `data` and learn using `loss_func` and `opt`."
      assert len(learn.data.train_dl) != 0, f
      cb_handler = CallbackHandler(callbacks, metrics)
      pbar = master_bar(range(epochs))
      cb_handler.on_train_begin(epochs, pbar=pbar, metrics=metrics)
  
      exception=False
      try:
          for epoch in pbar:
              learn.model.train()
              cb_handler.set_dl(learn.data.train_dl)
              cb_handler.on_epoch_begin()
              for xb,yb in progress_bar(learn.data.train_dl, parent=pbar):
                  xb, yb = cb_handler.on_batch_begin(xb, yb)
                  loss = loss_batch(learn.model, xb, yb, learn.loss_func, learn.opt, cb_handler)
                  if cb_handler.on_batch_end(loss): break
  
              if not cb_handler.skip_validate and not learn.data.empty_val:
                  val_loss = validate(learn.model, learn.data.valid_dl, loss_func=learn.loss_func,
                                         cb_handler=cb_handler, pbar=pbar)
              else: val_loss=None
              if cb_handler.on_epoch_end(val_loss): break
      except Exception as e:
          exception = e
          raise
      finally: cb_handler.on_train_end(exception)
docs: Fit the `model` on `data` and learn using `loss_func` and `opt`.