{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "from fastai2.basics import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "from nbdev.showdoc import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#default_exp callback.schedule" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Hyperparam schedule\n", "\n", "> Callback and helper functions to schedule any hyper-parameter" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from fastai2.test_utils import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Annealing" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class _Annealer:\n", " def __init__(self, f, start, end): store_attr(self, 'f,start,end')\n", " def __call__(self, pos): return self.f(self.start, self.end, pos)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def annealer(f):\n", " \"Decorator to make `f` return itself partially applied.\"\n", " @functools.wraps(f)\n", " def _inner(start, end): return _Annealer(f, start, end)\n", " return _inner" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is the decorator we will use for all of our scheduling functions, as it transforms a function taking `(start, end, pos)` to something taking `(start, end)` and return a function depending of `pos`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "#TODO Jeremy, make this pickle\n", "#@annealer\n", "#def SchedLin(start, end, pos): return start + pos*(end-start)\n", "#@annealer\n", "#def SchedCos(start, end, pos): return start + (1 + math.cos(math.pi*(1-pos))) * (end-start) / 2\n", "#@annealer\n", "#def SchedNo (start, end, pos): return start\n", "#@annealer\n", "#def SchedExp(start, end, pos): return start * (end/start) ** pos\n", "#\n", "#SchedLin.__doc__ = \"Linear schedule function from `start` to `end`\"\n", "#SchedCos.__doc__ = \"Cosine schedule function from `start` to `end`\"\n", "#SchedNo .__doc__ = \"Constant schedule function with `start` value\"\n", "#SchedExp.__doc__ = \"Exponential schedule function from `start` to `end`\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def sched_lin(start, end, pos): return start + pos*(end-start)\n", "def sched_cos(start, end, pos): return start + (1 + math.cos(math.pi*(1-pos))) * (end-start) / 2\n", "def sched_no (start, end, pos): return start\n", "def sched_exp(start, end, pos): return start * (end/start) ** pos\n", "\n", "def SchedLin(start, end): return _Annealer(sched_lin, start, end)\n", "def SchedCos(start, end): return _Annealer(sched_cos, start, end)\n", "def SchedNo (start, end): return _Annealer(sched_no, start, end)\n", "def SchedExp(start, end): return _Annealer(sched_exp, start, end)\n", "\n", "SchedLin.__doc__ = \"Linear schedule function from `start` to `end`\"\n", "SchedCos.__doc__ = \"Cosine schedule function from `start` to `end`\"\n", "SchedNo .__doc__ = \"Constant schedule function with `start` value\"\n", "SchedExp.__doc__ = \"Exponential schedule function from `start` to `end`\"" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "tst = pickle.dumps(SchedCos(0, 5))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "annealings = \"NO LINEAR COS EXP\".split()\n", "p = torch.linspace(0.,1,100)\n", "fns = [SchedNo, SchedLin, SchedCos, SchedExp]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def SchedPoly(start, end, power):\n", " \"Polynomial schedule (of `power`) function from `start` to `end`\"\n", " def _inner(pos): return start + (end - start) * pos ** power\n", " return _inner" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "for fn, t in zip(fns, annealings):\n", " plt.plot(p, [fn(2, 1e-2)(o) for o in p], label=t)\n", "f = SchedPoly(2,1e-2,0.5)\n", "plt.plot(p, [f(o) for o in p], label=\"POLY(0.5)\")\n", "plt.legend();" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

SchedLin[source]

\n", "\n", "> SchedLin(**`start`**, **`end`**)\n", "\n", "Linear schedule function from `start` to `end`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(SchedLin)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sched = SchedLin(0, 2)\n", "test_eq(L(map(sched, [0., 0.25, 0.5, 0.75, 1.])), [0., 0.5, 1., 1.5, 2.])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

SchedCos[source]

\n", "\n", "> SchedCos(**`start`**, **`end`**)\n", "\n", "Cosine schedule function from `start` to `end`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(SchedCos)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sched = SchedCos(0, 2)\n", "test_close(L(map(sched, [0., 0.25, 0.5, 0.75, 1.])), [0., 0.29289, 1., 1.70711, 2.])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

SchedNo[source]

\n", "\n", "> SchedNo(**`start`**, **`end`**)\n", "\n", "Constant schedule function with `start` value" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(SchedNo)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sched = SchedNo(0, 2)\n", "test_close(L(map(sched, [0., 0.25, 0.5, 0.75, 1.])), [0., 0., 0., 0., 0.])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

SchedExp[source]

\n", "\n", "> SchedExp(**`start`**, **`end`**)\n", "\n", "Exponential schedule function from `start` to `end`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(SchedExp)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sched = SchedExp(1, 2)\n", "test_close(L(map(sched, [0., 0.25, 0.5, 0.75, 1.])), [1., 1.18921, 1.41421, 1.68179, 2.])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

SchedPoly[source]

\n", "\n", "> SchedPoly(**`start`**, **`end`**, **`power`**)\n", "\n", "Polynomial schedule (of `power`) function from `start` to `end`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(SchedPoly)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "sched = SchedPoly(0, 2, 2)\n", "test_close(L(map(sched, [0., 0.25, 0.5, 0.75, 1.])), [0., 0.125, 0.5, 1.125, 2.])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "p = torch.linspace(0.,1,100)\n", "\n", "pows = [0.5,1.,2.]\n", "for e in pows:\n", " f = SchedPoly(2, 0, e)\n", " plt.plot(p, [f(o) for o in p], label=f'power {e}')\n", "plt.legend();" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def combine_scheds(pcts, scheds):\n", " \"Combine `scheds` according to `pcts` in one function\"\n", " assert sum(pcts) == 1.\n", " pcts = tensor([0] + L(pcts))\n", " assert torch.all(pcts >= 0)\n", " pcts = torch.cumsum(pcts, 0)\n", " def _inner(pos):\n", " if pos == 1.: return scheds[-1](1.)\n", " idx = (pos >= pcts).nonzero().max()\n", " actual_pos = (pos-pcts[idx]) / (pcts[idx+1]-pcts[idx])\n", " return scheds[idx](actual_pos.item())\n", " return _inner" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`pcts` must be a list of positive numbers that add up to 1 and is the same length as `scheds`. The generated function will use `scheds[0]` from 0 to `pcts[0]` then `scheds[1]` from `pcts[0]` to `pcts[0]+pcts[1]` and so forth." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "p = torch.linspace(0.,1,100)\n", "f = combine_scheds([0.3,0.7], [SchedCos(0.3,0.6), SchedCos(0.6,0.2)])\n", "plt.plot(p, [f(o) for o in p]);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "p = torch.linspace(0.,1,100)\n", "f = combine_scheds([0.3,0.2,0.5], [SchedLin(0.,1.), SchedNo(1.,1.), SchedCos(1., 0.)])\n", "plt.plot(p, [f(o) for o in p]);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "test_close([f(0.), f(0.15), f(0.3), f(0.4), f(0.5), f(0.7), f(1.)],\n", " [0., 0.5, 1., 1., 1., 0.65451, 0.])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def combined_cos(pct, start, middle, end):\n", " \"Return a scheduler with cosine annealing from `start`→`middle` & `middle`→`end`\"\n", " return combine_scheds([pct,1-pct], [SchedCos(start, middle), SchedCos(middle, end)])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is a useful helper function for the [1cycle policy](https://sgugger.github.io/the-1cycle-policy.html). `pct` is used for the `start` to `middle` part, `1-pct` for the `middle` to `end`. Handles floats or collection of floats. For example:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "f = combined_cos(0.25,0.5,1.,0.)\n", "plt.plot(p, [f(o) for o in p]);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "test_close([f(0.), f(0.1), f(0.25), f(0.5), f(1.)], [0.5, 0.67275, 1., 0.75, 0.])\n", "f = combined_cos(0.25, np.array([0.25,0.5]), np.array([0.5,1.]), np.array([0.,0.]))\n", "test_close([f(0.), f(0.1), f(0.25), f(0.5), f(1.)], \n", " [[0.25,0.5], [0.33638,0.67275], [0.5,1.], [0.375,0.75], [0.,0.]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ParamScheduler -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@docs\n", "class ParamScheduler(Callback):\n", " \"Schedule hyper-parameters according to `scheds`\"\n", " run_after,run_valid = TrainEvalCallback,False\n", "\n", " def __init__(self, scheds): self.scheds = scheds\n", " def before_fit(self): self.hps = {p:[] for p in self.scheds.keys()}\n", " def before_batch(self): self._update_val(self.pct_train)\n", "\n", " def _update_val(self, pct):\n", " for n,f in self.scheds.items(): self.opt.set_hyper(n, f(pct))\n", "\n", " def after_batch(self):\n", " for p in self.scheds.keys(): self.hps[p].append(self.opt.hypers[-1][p])\n", "\n", " def after_fit(self):\n", " if hasattr(self.learn, 'recorder') and hasattr(self, 'hps'): self.recorder.hps = self.hps\n", "\n", " _docs = {\"before_fit\": \"Initialize container for hyper-parameters\",\n", " \"before_batch\": \"Set the proper hyper-parameters in the optimizer\",\n", " \"after_batch\": \"Record hyper-parameters of this batch\",\n", " \"after_fit\": \"Save the hyper-parameters in the recorder if there is one\"}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`scheds` is a dictionary with one key for each hyper-parameter you want to schedule, with either a scheduler or a list of schedulers as values (in the second case, the list must have the same length as the the number of parameters groups of the optimizer)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,17.4951171875,12.842596054077148,'00:00']\n" ] } ], "source": [ "learn = synth_learner()\n", "sched = {'lr': SchedLin(1e-3, 1e-2)}\n", "learn.fit(1, cbs=ParamScheduler(sched))\n", "n = len(learn.dls.train)\n", "test_close(learn.recorder.hps['lr'], [1e-3 + (1e-2-1e-3) * i/n for i in range(n)])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,12.503241539001465,14.066490173339844,'00:00']\n" ] } ], "source": [ "#hide\n", "#test discriminative lrs\n", "def _splitter(m): return [[m.a], [m.b]]\n", "learn = synth_learner(splitter=_splitter)\n", "sched = {'lr': combined_cos(0.5, np.array([1e-4,1e-3]), np.array([1e-3,1e-2]), np.array([1e-5,1e-4]))}\n", "learn.fit(1, cbs=ParamScheduler(sched))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ParamScheduler.before_fit[source]

\n", "\n", "> ParamScheduler.before_fit()\n", "\n", "Initialize container for hyper-parameters" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ParamScheduler.before_fit)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ParamScheduler.before_batch[source]

\n", "\n", "> ParamScheduler.before_batch()\n", "\n", "Set the proper hyper-parameters in the optimizer" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ParamScheduler.before_batch)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ParamScheduler.after_batch[source]

\n", "\n", "> ParamScheduler.after_batch()\n", "\n", "Record hyper-parameters of this batch" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ParamScheduler.after_batch)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ParamScheduler.after_fit[source]

\n", "\n", "> ParamScheduler.after_fit()\n", "\n", "Save the hyper-parameters in the recorder if there is one" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ParamScheduler.after_fit)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "@log_args(but_as=Learner.fit)\n", "def fit_one_cycle(self:Learner, n_epoch, lr_max=None, div=25., div_final=1e5, pct_start=0.25, wd=None,\n", " moms=None, cbs=None, reset_opt=False):\n", " \"Fit `self.model` for `n_epoch` using the 1cycle policy.\"\n", " if self.opt is None: self.create_opt()\n", " self.opt.set_hyper('lr', self.lr if lr_max is None else lr_max)\n", " lr_max = np.array([h['lr'] for h in self.opt.hypers])\n", " scheds = {'lr': combined_cos(pct_start, lr_max/div, lr_max, lr_max/div_final),\n", " 'mom': combined_cos(pct_start, *(self.moms if moms is None else moms))}\n", " self.fit(n_epoch, cbs=ParamScheduler(scheds)+L(cbs), reset_opt=reset_opt, wd=wd)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The 1cycle policy was introduced by Leslie N. Smith et al. in [Super-Convergence: Very Fast Training of Neural Networks Using Large Learning Rates](https://arxiv.org/abs/1708.07120). It schedules the learning rate with a cosine annealing from `lr_max/div` to `lr_max` then `lr_max/div_final` (pass an array to `lr_max` if you want to use differential learning rates) and the momentum with cosine annealing according to the values in `moms`. The first phase takes `pct_start` of the training. You can optionally pass additional `cbs` and `reset_opt`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,11.074447631835938,4.278277397155762,'00:00']\n", "(#4) [1,6.254273891448975,1.2542004585266113,'00:00']\n" ] } ], "source": [ "#Integration test: training a few epochs should make the model better\n", "learn = synth_learner(lr=1e-2)\n", "xb,yb = learn.dls.one_batch()\n", "init_loss = learn.loss_func(learn.model(xb), yb)\n", "learn.fit_one_cycle(2)\n", "xb,yb = learn.dls.one_batch()\n", "final_loss = learn.loss_func(learn.model(xb), yb)\n", "assert final_loss < init_loss" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Scheduler test\n", "lrs,moms = learn.recorder.hps['lr'],learn.recorder.hps['mom']\n", "test_close(lrs, [combined_cos(0.25,1e-2/25,1e-2,1e-7)(i/20) for i in range(20)])\n", "test_close(moms, [combined_cos(0.25,0.95,0.85,0.95)(i/20) for i in range(20)])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "def plot_sched(self:Recorder, keys=None, figsize=None):\n", " keys = self.hps.keys() if keys is None else L(keys)\n", " rows,cols = (len(keys)+1)//2, min(2, len(keys))\n", " figsize = figsize or (6*cols,4*rows)\n", " _, axs = plt.subplots(rows, cols, figsize=figsize)\n", " axs = axs.flatten() if len(keys) > 1 else L(axs)\n", " for p,ax in zip(keys, axs):\n", " ax.plot(self.hps[p])\n", " ax.set_ylabel(p)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,13.46381950378418,8.627909660339355,'00:00']\n" ] } ], "source": [ "#hide\n", "#test discriminative lrs\n", "def _splitter(m): return [[m.a], [m.b]]\n", "learn = synth_learner(splitter=_splitter)\n", "learn.fit_one_cycle(1, lr_max=slice(1e-3,1e-2))\n", "#n = len(learn.dls.train)\n", "#est_close(learn.recorder.hps['lr'], [1e-3 + (1e-2-1e-3) * i/n for i in range(n)])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,25.833967208862305,20.405487060546875,'00:00']\n", "(#4) [1,23.9661808013916,18.709392547607422,'00:00']\n" ] } ], "source": [ "learn = synth_learner()\n", "learn.fit_one_cycle(2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "learn.recorder.plot_sched()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "@log_args(but_as=Learner.fit)\n", "def fit_flat_cos(self:Learner, n_epoch, lr=None, div_final=1e5, pct_start=0.75, wd=None,\n", " cbs=None, reset_opt=False):\n", " \"Fit `self.model` for `n_epoch` at flat `lr` before a cosine annealing.\"\n", " if self.opt is None: self.create_opt()\n", " self.opt.set_hyper('lr', self.lr if lr is None else lr)\n", " lr = np.array([h['lr'] for h in self.opt.hypers])\n", " scheds = {'lr': combined_cos(pct_start, lr, lr, lr/div_final)}\n", " self.fit(n_epoch, cbs=ParamScheduler(scheds)+L(cbs), reset_opt=reset_opt, wd=wd)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,22.340993881225586,23.366474151611328,'00:00']\n", "(#4) [1,19.25973892211914,17.295818328857422,'00:00']\n" ] } ], "source": [ "learn = synth_learner()\n", "learn.fit_flat_cos(2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "learn.recorder.plot_sched()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "@log_args(but_as=Learner.fit)\n", "def fit_sgdr(self:Learner, n_cycles, cycle_len, lr_max=None, cycle_mult=2, cbs=None, reset_opt=False, wd=None):\n", " \"Fit `self.model` for `n_cycles` of `cycle_len` using SGDR.\"\n", " if self.opt is None: self.create_opt()\n", " self.opt.set_hyper('lr', self.lr if lr_max is None else lr_max)\n", " lr_max = np.array([h['lr'] for h in self.opt.hypers])\n", " n_epoch = cycle_len * (cycle_mult**n_cycles-1)//(cycle_mult-1)\n", " pcts = [cycle_len * cycle_mult**i / n_epoch for i in range(n_cycles)]\n", " scheds = [SchedCos(lr_max, 0) for _ in range(n_cycles)]\n", " scheds = {'lr': combine_scheds(pcts, scheds)}\n", " self.fit(n_epoch, cbs=ParamScheduler(scheds)+L(cbs), reset_opt=reset_opt, wd=wd)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This schedule was introduced by Ilya Loshchilov et al. in [SGDR: Stochastic Gradient Descent with Warm Restarts](https://arxiv.org/abs/1608.03983). It consists of `n_cycles` that are cosine annealings from `lr_max` (defaults to the `Learner` lr) to 0, with a length of `cycle_len * cycle_mult**i` for the `i`-th cycle (first one is `cycle_len`-long, then we multiply the length by `cycle_mult` at each epoch). You can optionally pass additional `cbs` and `reset_opt`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "#slow\n", "learn = synth_learner()\n", "with learn.no_logging(): learn.fit_sgdr(3, 1)\n", "test_eq(learn.n_epoch, 7)\n", "iters = [k * len(learn.dls.train) for k in [0,1,3,7]]\n", "for i in range(3):\n", " n = iters[i+1]-iters[i]\n", " #The start of a cycle can be mixed with the 0 of the previous cycle with rounding errors, so we test at +1\n", " test_close(learn.recorder.lrs[iters[i]+1:iters[i+1]], [SchedCos(learn.lr, 0)(k/n) for k in range(1,n)])\n", "\n", "learn.recorder.plot_sched()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "@log_args(but_as=Learner.fit)\n", "@delegates(Learner.fit_one_cycle)\n", "def fine_tune(self:Learner, epochs, base_lr=2e-3, freeze_epochs=1, lr_mult=100,\n", " pct_start=0.3, div=5.0, **kwargs):\n", " \"Fine tune with `freeze` for `freeze_epochs` then with `unfreeze` from `epochs` using discriminative LR\"\n", " self.freeze()\n", " self.fit_one_cycle(freeze_epochs, slice(base_lr), pct_start=0.99, **kwargs)\n", " base_lr /= 2\n", " self.unfreeze()\n", " self.fit_one_cycle(epochs, slice(base_lr/lr_mult, base_lr), pct_start=pct_start, div=div, **kwargs)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(#4) [0,8.00173282623291,5.4913434982299805,'00:00']\n", "(#4) [0,6.550796031951904,5.056417465209961,'00:00']\n" ] } ], "source": [ "learn.fine_tune(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## LRFind -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@docs\n", "class LRFinder(ParamScheduler):\n", " \"Training with exponentially growing learning rate\"\n", " run_after=Recorder\n", "\n", " def __init__(self, start_lr=1e-7, end_lr=10, num_it=100, stop_div=True):\n", " if is_listy(start_lr):\n", " self.scheds = {'lr': [SchedExp(s, e) for (s,e) in zip(start_lr,end_lr)]}\n", " else: self.scheds = {'lr': SchedExp(start_lr, end_lr)}\n", " self.num_it,self.stop_div = num_it,stop_div\n", "\n", " def before_fit(self):\n", " super().before_fit()\n", " self.learn.save('_tmp')\n", " self.best_loss = float('inf')\n", "\n", " def before_batch(self):\n", " self._update_val(self.train_iter/self.num_it)\n", "\n", " def after_batch(self):\n", " super().after_batch()\n", " if self.smooth_loss < self.best_loss: self.best_loss = self.smooth_loss\n", " if self.smooth_loss > 4*self.best_loss and self.stop_div: raise CancelFitException()\n", " if self.train_iter >= self.num_it: raise CancelFitException()\n", "\n", " def before_validate(self): raise CancelValidException()\n", "\n", " def after_fit(self):\n", " self.learn.opt.zero_grad() #Need to zero the gradients of the model before detaching the optimizer for future fits\n", " tmp_f = self.path/self.model_dir/'_tmp.pth'\n", " if tmp_f.exists():\n", " self.learn.load('_tmp')\n", " os.remove(tmp_f)\n", "\n", " _docs = {\"before_fit\": \"Initialize container for hyper-parameters and save the model\",\n", " \"before_batch\": \"Set the proper hyper-parameters in the optimizer\",\n", " \"after_batch\": \"Record hyper-parameters of this batch and potentially stop training\",\n", " \"after_fit\": \"Save the hyper-parameters in the recorder if there is one and load the original model\",\n", " \"before_validate\": \"Skip the validation part of training\"}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#slow\n", "with tempfile.TemporaryDirectory() as d:\n", " learn = synth_learner(path=Path(d))\n", " init_a,init_b = learn.model.a,learn.model.b\n", " with learn.no_logging(): learn.fit(20, cbs=LRFinder(num_it=100))\n", " assert len(learn.recorder.lrs) <= 100\n", " test_eq(len(learn.recorder.lrs), len(learn.recorder.losses))\n", " #Check stop if diverge\n", " if len(learn.recorder.lrs) < 100: assert learn.recorder.losses[-1] > 4 * min(learn.recorder.losses)\n", " #Test schedule\n", " test_eq(learn.recorder.lrs, [SchedExp(1e-7, 10)(i/100) for i in range_of(learn.recorder.lrs)])\n", " #No validation data\n", " test_eq([len(v) for v in learn.recorder.values], [1 for _ in range_of(learn.recorder.values)])\n", " #Model loaded back properly\n", " test_eq(learn.model.a, init_a)\n", " test_eq(learn.model.b, init_b)\n", " test_eq(learn.opt.state_dict()['state'], [{}, {}])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

LRFinder.before_fit[source]

\n", "\n", "> LRFinder.before_fit()\n", "\n", "Initialize container for hyper-parameters and save the model" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(LRFinder.before_fit)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

LRFinder.before_batch[source]

\n", "\n", "> LRFinder.before_batch()\n", "\n", "Set the proper hyper-parameters in the optimizer" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(LRFinder.before_batch)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

LRFinder.after_batch[source]

\n", "\n", "> LRFinder.after_batch()\n", "\n", "Record hyper-parameters of this batch and potentially stop training" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(LRFinder.after_batch)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

LRFinder.before_validate[source]

\n", "\n", "> LRFinder.before_validate()\n", "\n", "Skip the validation part of training" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(LRFinder.before_validate)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "def plot_lr_find(self:Recorder, skip_end=5):\n", " \"Plot the result of an LR Finder test (won't work if you didn't do `learn.lr_find()` before)\"\n", " lrs = self.lrs if skip_end==0 else self.lrs [:-skip_end]\n", " losses = self.losses if skip_end==0 else self.losses[:-skip_end]\n", " fig, ax = plt.subplots(1,1)\n", " ax.plot(lrs, losses)\n", " ax.set_ylabel(\"Loss\")\n", " ax.set_xlabel(\"Learning Rate\")\n", " ax.set_xscale('log')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "SuggestedLRs = collections.namedtuple('SuggestedLRs', ['lr_min', 'lr_steep'])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@patch\n", "def lr_find(self:Learner, start_lr=1e-7, end_lr=10, num_it=100, stop_div=True, show_plot=True, suggestions=True):\n", " \"Launch a mock training to find a good learning rate, return lr_min, lr_steep if `suggestions` is True\"\n", " n_epoch = num_it//len(self.dls.train) + 1\n", " cb=LRFinder(start_lr=start_lr, end_lr=end_lr, num_it=num_it, stop_div=stop_div)\n", " with self.no_logging(): self.fit(n_epoch, cbs=cb)\n", " if show_plot: self.recorder.plot_lr_find()\n", " if suggestions:\n", " lrs,losses = tensor(self.recorder.lrs[num_it//10:-5]),tensor(self.recorder.losses[num_it//10:-5])\n", " if len(losses) == 0: return\n", " lr_min = lrs[losses.argmin()].item()\n", " grads = (losses[1:]-losses[:-1]) / (lrs[1:].log()-lrs[:-1].log())\n", " lr_steep = lrs[grads.argmin()].item()\n", " return SuggestedLRs(lr_min/10.,lr_steep)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First introduced by Leslie N. Smith in [Cyclical Learning Rates for Training Neural Networks](https://arxiv.org/pdf/1506.01186.pdf), the LR Finder trains the model with exponentially growing learning rates from `start_lr` to `end_lr` for `num_it` and stops in case of divergence (unless `stop_div=False`) then plots the losses vs the learning rates with a log scale. \n", "\n", "A good value for the learning rates is then either:\n", "- one tenth of the minimum before the divergence\n", "- when the slope is the steepest\n", "\n", "Those two values are returned by default by the Learning Rate Finder." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Minimum/10: 1.20e-02, steepest point: 7.59e-07\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "#slow\n", "with tempfile.TemporaryDirectory() as d:\n", " learn = synth_learner(path=Path(d))\n", " lr_min,lr_steep = learn.lr_find()\n", "print(f\"Minimum/10: {lr_min:.2e}, steepest point: {lr_steep:.2e}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Export -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Converted 00_torch_core.ipynb.\n", "Converted 01_layers.ipynb.\n", "Converted 02_data.load.ipynb.\n", "Converted 03_data.core.ipynb.\n", "Converted 04_data.external.ipynb.\n", "Converted 05_data.transforms.ipynb.\n", "Converted 06_data.block.ipynb.\n", "Converted 07_vision.core.ipynb.\n", "Converted 08_vision.data.ipynb.\n", "Converted 09_vision.augment.ipynb.\n", "Converted 09b_vision.utils.ipynb.\n", "Converted 09c_vision.widgets.ipynb.\n", "Converted 10_tutorial.pets.ipynb.\n", "Converted 11_vision.models.xresnet.ipynb.\n", "Converted 12_optimizer.ipynb.\n", "Converted 13_callback.core.ipynb.\n", "Converted 13a_learner.ipynb.\n", "Converted 13b_metrics.ipynb.\n", "Converted 14_callback.schedule.ipynb.\n", "Converted 14a_callback.data.ipynb.\n", "Converted 15_callback.hook.ipynb.\n", "Converted 15a_vision.models.unet.ipynb.\n", "Converted 16_callback.progress.ipynb.\n", "Converted 17_callback.tracker.ipynb.\n", "Converted 18_callback.fp16.ipynb.\n", "Converted 18a_callback.training.ipynb.\n", "Converted 19_callback.mixup.ipynb.\n", "Converted 20_interpret.ipynb.\n", "Converted 20a_distributed.ipynb.\n", "Converted 21_vision.learner.ipynb.\n", "Converted 22_tutorial.imagenette.ipynb.\n", "Converted 23_tutorial.vision.ipynb.\n", "Converted 24_tutorial.siamese.ipynb.\n", "Converted 24_vision.gan.ipynb.\n", "Converted 30_text.core.ipynb.\n", "Converted 31_text.data.ipynb.\n", "Converted 32_text.models.awdlstm.ipynb.\n", "Converted 33_text.models.core.ipynb.\n", "Converted 34_callback.rnn.ipynb.\n", "Converted 35_tutorial.wikitext.ipynb.\n", "Converted 36_text.models.qrnn.ipynb.\n", "Converted 37_text.learner.ipynb.\n", "Converted 38_tutorial.text.ipynb.\n", "Converted 39_tutorial.transformers.ipynb.\n", "Converted 40_tabular.core.ipynb.\n", "Converted 41_tabular.data.ipynb.\n", "Converted 42_tabular.model.ipynb.\n", "Converted 43_tabular.learner.ipynb.\n", "Converted 44_tutorial.tabular.ipynb.\n", "Converted 45_collab.ipynb.\n", "Converted 46_tutorial.collab.ipynb.\n", "Converted 50_tutorial.datablock.ipynb.\n", "Converted 60_medical.imaging.ipynb.\n", "Converted 61_tutorial.medical_imaging.ipynb.\n", "Converted 65_medical.text.ipynb.\n", "Converted 70_callback.wandb.ipynb.\n", "Converted 71_callback.tensorboard.ipynb.\n", "Converted 72_callback.neptune.ipynb.\n", "Converted 73_callback.captum.ipynb.\n", "Converted 74_callback.cutmix.ipynb.\n", "Converted 97_test_utils.ipynb.\n", "Converted 99_pytorch_doc.ipynb.\n", "Converted index.ipynb.\n", "Converted tutorial.ipynb.\n" ] } ], "source": [ "#hide\n", "from nbdev.export import notebook2script\n", "notebook2script()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "jupytext": { "split_at_heading": true }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 4 }