{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "%load_ext autoreload\n", "%autoreload 2\n", "\n", "%matplotlib inline" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "#export\n", "from exp.nb_05 import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Jump_to notebook introduction in lesson 10 video](https://course.fast.ai/videos/?lesson=10&t=3167)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Early stopping" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Better callback cancellation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Jump_to lesson 10 video](https://course.fast.ai/videos/?lesson=10&t=3230)" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "# get the data, set the loss function\n", "x_train,y_train,x_valid,y_valid = get_data()\n", "train_ds,valid_ds = Dataset(x_train, y_train),Dataset(x_valid, y_valid)\n", "n_hidden,batch_size = 50,512\n", "n_out = y_train.max().item()+1\n", "loss_func = F.cross_entropy" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# create a DataBunch\n", "data = DataBunch(*get_dls(train_ds, valid_ds, batch_size), n_out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Slightly refactor Callback() and add three Cancellation callbacks" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "#export\n", "\n", "# Callback() class is slightly refactored from notebook 04_callbacks\n", "class Callback():\n", " \n", " # initialize _order to zero. \n", " _order=0\n", " \n", " # set_runner() method takes a callback as an input\n", " # note that initially self.run is unset -- there is no default value \n", " def set_runner(self, run): \n", " self.run=run\n", " def __getattr__(self, callback_name): \n", " return getattr(self.run, callback_name)\n", " \n", " # set the callback name property\n", " # if the callback doesn't have a name, set the callback name property to 'callback'\n", " @property\n", " def name(self):\n", " name = re.sub(r'Callback$', '', self.__class__.__name__)\n", " return camel2snake(name or 'callback')\n", " \n", " # this is the only modification to the 04_callbacks notebook\n", " # it allows the Callback() class to be called as a function\n", " def __call__(self, callback_name):\n", " f = getattr(self, callback_name, None)\n", " # check this callback name, and return True if it is the requested callback\n", " if f and f(): return True\n", " return False\n", "\n", "# this helper callback is used in Runner()\n", "class TrainEvalCallback(Callback):\n", " \n", " # initialize the epoch, batch, and iteration counters\n", " def begin_fit(self):\n", " self.run.n_epoch_float=0.\n", " self.run.n_batch = 0\n", " self.run.n_iter=0\n", " \n", " # if we are in the training phase, update the epoch and batch counters\n", " def after_batch(self):\n", " if not self.in_train: \n", " return\n", " # each batch represents a fraction of an epoch\n", " self.run.n_epoch_float += 1./self.n_batches\n", " self.run.n_batch += 1\n", " \n", " # execute the training phase\n", " def begin_epoch(self):\n", " self.run.n_epoch_float=self.n_epoch_float\n", " self.model.train()\n", " self.run.in_train=True\n", "\n", " # execute the prediction phase\n", " def begin_validate(self):\n", " self.model.eval()\n", " self.run.in_train=False\n", "\n", "# add three cancellation callbacks\n", "class CancelTrainException(Exception): pass\n", "class CancelEpochException(Exception): pass\n", "class CancelBatchException(Exception): pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Refactor Runner() to use the cancellation callbacks" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "#export\n", "class Runner():\n", "\n", " # initialize by setting the stop Flag to False, and constructing a list of callbacks from the inputs\n", " def __init__(self, callbacks=None, callback_funcs=None):\n", " # inputs are two lists: callbacks and callback_funcs\n", " # Q: it's not clear why we need two lists rather than one\n", " # create a list of callbacks from the input callbacks\n", " self.in_train = False\n", " callbacks = listify(callbacks)\n", " # associate each callback_func() to its snake case callback name then append it to the callbacks list\n", " for callback_func in listify(callback_funcs):\n", " callback = callback_func()\n", " setattr(self, callback.name, callback)\n", " callbacks.append(callback)\n", " # set the stopping flag to `False` and append TrainEvalCallback() to the callbacks list\n", " self.stop,self.callbacks = False,[TrainEvalCallback()]+callbacks\n", "\n", " # get the properties of the Learner object\n", " @property\n", " def opt(self): return self.learn.opt\n", " @property\n", " def model(self): return self.learn.model\n", " @property\n", " def loss_func(self): return self.learn.loss_func\n", " @property\n", " def data(self): return self.learn.data\n", " \n", " \n", " # method to process a single batch\n", " def one_batch(self, xb, yb):\n", " try:\n", " self.xb,self.yb = xb,yb\n", " self('begin_batch')\n", " self.pred = self.model(self.xb)\n", " self('after_pred')\n", " self.loss = self.loss_func(self.pred, self.yb)\n", " self('after_loss')\n", " if not self.in_train: return\n", " self.loss.backward()\n", " self('after_backward')\n", " self.opt.step()\n", " self('after_step')\n", " self.opt.zero_grad()\n", " except CancelBatchException: self('after_cancel_batch')\n", " finally: self('after_batch')\n", "\n", " # method to process all batches\n", " def all_batches(self, dataloader):\n", " # total number of batches in an epoch\n", " # self.n_epoch_float = 0.\n", " self.n_batches = len(dataloader)\n", " try:\n", " for xb,yb in dataloader: self.one_batch(xb, yb)\n", " except CancelEpochException: self('after_cancel_epoch')\n", "\n", " # method to process training or validation data\n", " def fit(self, learn, n_epochs,):\n", " self.n_epochs,self.learn,self.loss = n_epochs,learn,tensor(0.)\n", "\n", " try:\n", " for callback in self.callbacks: \n", " callback.set_runner(self)\n", " self('begin_fit')\n", " for epoch_number in range(n_epochs):\n", " self.epoch_number = epoch_number\n", " \n", " \n", " # training phase\n", " if not self('begin_epoch'): \n", " self.all_batches(self.data.train_dl)\n", "\n", " # validation phase\n", " with torch.no_grad(): \n", " if not self('begin_validate'): \n", " self.all_batches(self.data.valid_dl)\n", " self('after_epoch')\n", " \n", " except CancelTrainException: \n", " self('after_cancel_train')\n", " \n", " finally:\n", " # set the `after_fit` state to `True`\n", " self('after_fit')\n", " # erase the Learner object\n", " self.learn = None\n", "\n", " def __call__(self, callback_name):\n", " # __call__ allows an instance of this class to be called as a function\n", " # Q: note clear what this loop is trying to do; it always returns result = False\n", " result = False\n", " for callback in sorted(self.callbacks, key=lambda x: x._order): \n", " result = callback(callback_name) and result\n", " return result" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Refactor TestCallback() to use a cancellation callback" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "class TestCallback(Callback):\n", " _order=1\n", " def after_step(self):\n", " self.n_iter += 1\n", " print(self.n_iter)\n", " if self.n_iter>=10: \n", " raise CancelTrainException()" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [], "source": [ "learn = create_learner(get_model, loss_func, data)" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "run = Runner(callback_funcs=TestCallback)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1\n", "2\n", "3\n", "4\n", "5\n", "6\n", "7\n", "8\n", "9\n", "10\n" ] } ], "source": [ "run.fit(learn, n_epochs = 3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. AvgStatsCallback, Recorder, and ParamScheduler Callbacks" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "#export\n", "class AvgStatsCallback(Callback):\n", " def __init__(self, metrics):\n", " self.train_stats,self.valid_stats = AvgStats(metrics,in_train = True),AvgStats(metrics,in_train = False)\n", " \n", " # initialize train_stats and valid_stats\n", " def begin_epoch(self):\n", " self.train_stats.reset()\n", " self.valid_stats.reset()\n", " \n", " # compute and accumulate stats after the loss function has been evaluated\n", " def after_loss(self):\n", " stats = self.train_stats if self.in_train else self.valid_stats\n", " with torch.no_grad(): stats.accumulate(self.run)\n", " \n", " # print stats after the epoch has been processed\n", " def after_epoch(self):\n", " print(self.train_stats)\n", " print(self.valid_stats)\n", " \n", "class Recorder(Callback):\n", " def begin_fit(self):\n", " self.lrs = [[] for _ in self.opt.param_groups]\n", " self.losses = []\n", "\n", " def after_batch(self):\n", " if not self.in_train: return\n", " for pg,lr in zip(self.opt.param_groups,self.lrs): lr.append(pg['lr'])\n", " self.losses.append(self.loss.detach().cpu()) \n", "\n", " def plot_lr (self, pgid=-1): \n", " plt.plot(self.lrs[pgid])\n", " plt.xlabel('iteration')\n", " plt.ylabel('loss')\n", " def plot_loss(self, skip_last=0): # !!!!! not used\n", " plt.plot(self.losses[:len(self.losses)-skip_last])\n", " plt.xlabel('iteration')\n", " plt.ylabel('loss')\n", "\n", " \n", " def plot(self, skip_last=0, pgid=-1):\n", " losses = [o.item() for o in self.losses]\n", " lrs = self.lrs[pgid]\n", " n = len(losses)-skip_last\n", " plt.xscale('log')\n", " plt.plot(lrs[:n], losses[:n])\n", " plt.xlabel('learning rate')\n", " plt.ylabel('loss')\n", "\n", "class ParamScheduler(Callback):\n", " _order=1\n", " def __init__(self, pname, sched_funcs): \n", " self.pname,self.sched_funcs = pname,sched_funcs\n", " \n", " def begin_fit(self):\n", " if not isinstance(self.sched_funcs, (list,tuple)):\n", " self.sched_funcs = [self.sched_funcs] * len(self.opt.param_groups)\n", "\n", " def set_param(self):\n", " assert len(self.opt.param_groups)==len(self.sched_funcs)\n", " for pg,f in zip(self.opt.param_groups,self.sched_funcs):\n", " # !!!!! this is wrong -- \n", " pg[self.pname] = f(self.n_epochs/self.n_epochs)\n", " \n", " def begin_batch(self): \n", " if self.in_train: self.set_param()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3. Learning Rate Finder" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NB: You may want to also add something that saves the model before running this, and loads it back after running - otherwise you'll lose your weights!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[Jump_to lesson 10 video](https://course.fast.ai/videos/?lesson=10&t=3545)" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "class LR_Find(Callback):\n", " _order=1\n", " def __init__(self, max_iter=100, min_lr=1e-6, max_lr=10):\n", " self.max_iter,self.min_lr,self.max_lr = max_iter,min_lr,max_lr\n", " self.best_loss = 1e9\n", " \n", " def begin_batch(self): \n", " if not self.in_train: \n", " return\n", " pos = self.n_iter/self.max_iter\n", " lr = self.min_lr * (self.max_lr/self.min_lr) ** pos\n", " for pg in self.opt.param_groups: pg['lr'] = lr\n", " \n", " def after_step(self):\n", " self.n_iter += 1\n", " if self.n_iter >= self.max_iter or self.loss > self.best_loss*10:\n", " raise CancelTrainException()\n", " if self.loss < self.best_loss: \n", " self.best_loss = self.loss" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "NB: In fastai we also use exponential smoothing on the loss. For that reason we check for `best_loss*3` instead of `best_loss*10`." ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [], "source": [ "# instantiate a Learner object with data, loss_func, opt and model\n", "learn = Learner(*get_model(data), loss_func, data) " ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# instantiate a Runner object using the callback_funcs() input\n", "run = Runner(callback_funcs=[LR_Find, Recorder])" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [], "source": [ "# run a training/validation loop\n", "run.fit(learn, n_epochs=2)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# plot learning rate vs. loss\n", "run.recorder.plot(skip_last=5)" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "<Figure size 432x288 with 1 Axes>" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# plot iteration number vs. loss\n", "run.recorder.plot_lr()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Export" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Converted 05b_early_stopping_jcat.ipynb to exp\\nb_05b.py\n" ] } ], "source": [ "!python notebook2script.py 05b_early_stopping_jcat.ipynb" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.7.3" } }, "nbformat": 4, "nbformat_minor": 2 }