{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Basic training functionality" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "hide_input": true }, "outputs": [], "source": [ "from fastai.basic_train import *\n", "from fastai.gen_doc.nbdoc import *\n", "from fastai import *\n", "from fastai.vision import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[`basic_train`](/basic_train.html#basic_train) wraps together the data (in a [`DataBunch`](/basic_data.html#DataBunch) object) with a pytorch model to define a [`Learner`](/basic_train.html#Learner) object. This is where the basic training loop is defined for the [`fit`](/basic_train.html#fit) function. The [`Learner`](/basic_train.html#Learner) object is the entry point of most of the [`Callback`](/callback.html#Callback) functions that will customize this training loop in different ways (and made available through the [`train`](/train.html#train) module), notably:\n", "\n", " - [`Learner.lr_find`](/train.html#lr_find) will launch an LR range test that will help you select a good learning rate\n", " - [`Learner.fit_one_cycle`](/train.html#fit_one_cycle) will launch a training using the 1cycle policy, to help you train your model fast.\n", " - [`Learner.to_fp16`](/train.html#to_fp16) will convert your model in half precision and help you launch a training in mixed precision." ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

class Learner[source]

\n", "\n", "> Learner(`data`:[`DataBunch`](/basic_data.html#DataBunch), `model`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module), `opt_func`:`Callable`=`'Adam'`, `loss_func`:`Callable`=`None`, `metrics`:`Collection`\\[`Callable`\\]=`None`, `true_wd`:`bool`=`True`, `bn_wd`:`bool`=`True`, `wd`:`Floats`=`0.01`, `train_bn`:`bool`=`True`, `path`:`str`=`None`, `model_dir`:`str`=`'models'`, `callback_fns`:`Collection`\\[`Callable`\\]=`None`, `callbacks`:`Collection`\\[[`Callback`](/callback.html#Callback)\\]=``, `layer_groups`:`ModuleList`=`None`)\n", "\n", "Train `model` using `data` to minimize `loss_func` with optimizer `opt_func`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner, title_level=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The main purpose of [`Learner`](/basic_train.html#Learner) is to train `model` using [`Learner.fit`](/basic_train.html#Learner.fit). After every epoch, all *metrics* will be printed, and will also be available to callbacks.\n", "\n", "The default weight decay will be `wd`, which will be handled using the method from [Fixing Weight Decay Regularization in Adam](https://arxiv.org/abs/1711.05101) if `true_wd` is set (otherwise it's L2 regularization). If `bn_wd` is False then weight decay will be removed from batchnorm layers, as recommended in [Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour](https://arxiv.org/abs/1706.02677). You can ensure that batchnorm layer learnable params are trained even for frozen layer groups, by enabling `train_bn`.\n", "\n", "To use [discriminative layer training](#Discriminative-layer-training) pass an [`nn.Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module) for each layer group to be optimized with different settings.\n", "\n", "Any model files created will be saved in `path`/`model_dir`.\n", "\n", "You can pass a list of [`callbacks`](/callbacks.html#callbacks) that you have already created, or (more commonly) simply pass a list of callback functions to `callback_fns` and each function will be called (passing `self`) on object initialization, with the results stored as callback objects. For a walk-through, see the [training overview](/training.html) page. You may also want to use an `application` to fit your model, e.g. using the [`create_cnn`](/vision.learner.html#create_cnn) method:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "hide_input": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total time: 00:05\n", "epoch train_loss valid_loss accuracy\n", "1 0.077890 0.041011 0.985770 (00:05)\n", "\n" ] } ], "source": [ "path = untar_data(URLs.MNIST_SAMPLE)\n", "data = ImageDataBunch.from_folder(path)\n", "learn = create_cnn(data, models.resnet18, metrics=accuracy)\n", "learn.fit(1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Model fitting methods" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

fit[source]

\n", "\n", "> fit(`epochs`:`int`, `lr`:`Union`\\[`float`, `Collection`\\[`float`\\], `slice`\\]=`slice(None, 0.003, None)`, `wd`:`Floats`=`None`, `callbacks`:`Collection`\\[[`Callback`](/callback.html#Callback)\\]=`None`)\n", "\n", "Fit the model on this learner with `lr` learning rate, `wd` weight decay for `epochs` with `callbacks`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.fit)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uses [discriminative layer training](#Discriminative-layer-training) if multiple learning rates or weight decay values are passed. To control training behaviour, use the [`callback`](/callback.html#callback) system or one or more of the pre-defined [`callbacks`](/callbacks.html#callbacks)." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

fit_one_cycle[source]

\n", "\n", "> fit_one_cycle(`learn`:[`Learner`](/basic_train.html#Learner), `cyc_len`:`int`, `max_lr`:`Union`\\[`float`, `Collection`\\[`float`\\], `slice`\\]=`slice(None, 0.003, None)`, `moms`:`Point`=`(0.95, 0.85)`, `div_factor`:`float`=`25.0`, `pct_start`:`float`=`0.3`, `wd`:`float`=`None`, `callbacks`:`Optional`\\[`Collection`\\[[`Callback`](/callback.html#Callback)\\]\\]=`None`, `kwargs`)\n", "\n", "Fit a model following the 1cycle policy. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.fit_one_cycle)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uses the [`OneCycleScheduler`](/callbacks.one_cycle.html#OneCycleScheduler) callback." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

lr_find[source]

\n", "\n", "> lr_find(`learn`:[`Learner`](/basic_train.html#Learner), `start_lr`:`Floats`=`1e-07`, `end_lr`:`Floats`=`10`, `num_it`:`int`=`100`, `stop_div`:`bool`=`True`, `kwargs`:`Any`)\n", "\n", "Explore lr from `start_lr` to `end_lr` over `num_it` iterations in `learn`. If `stop_div`, stops when loss explodes. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.lr_find)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Runs the learning rate finder defined in [`LRFinder`](/callbacks.lr_finder.html#LRFinder), as discussed in [Cyclical Learning Rates for Training Neural Networks](https://arxiv.org/abs/1506.01186). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### See results" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

get_preds[source]

\n", "\n", "> get_preds(`ds_type`:[`DatasetType`](/basic_data.html#DatasetType)=``, `with_loss`:`bool`=`False`, `n_batch`:`Optional`\\[`int`\\]=`None`, `pbar`:`Union`\\[`MasterBar`, `ProgressBar`, `NoneType`\\]=`None`) → `List`\\[`Tensor`\\]\n", "\n", "Return predictions and targets on the valid, train, or test set, depending on `ds_type`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.get_preds)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

validate[source]

\n", "\n", "> validate(`dl`=`None`, `callbacks`=`None`, `metrics`=`None`)\n", "\n", "Validate on `dl` with potential `callbacks` and `metrics`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.validate)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Test time augmentation" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

TTA[source]

\n", "\n", "> TTA(`learn`:[`Learner`](/basic_train.html#Learner), `beta`:`float`=`0.4`, `scale`:`float`=`1.35`, `ds_type`:[`DatasetType`](/basic_data.html#DatasetType)=``, `with_loss`:`bool`=`False`) → `Tensors`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.TTA, full_name = 'TTA')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Applies Test Time Augmentation to `learn` on the dataset `ds_type`. We take the average of our regular predictions (with a weight `beta`) with the average of predictions obtained thourh augmented versions of the training set (with a weight `1-beta`). The transforms decided for the training set are applied with a few changes `scale` controls the scale for zoom (which isn't random), the cropping isn't random but we make sure to get the four corners of the image. Flipping isn't random but applied once on each of those corner images (so that makes 8 augmented versions total)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Mixed precision training" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

to_fp16[source]

\n", "\n", "> to_fp16(`learn`:[`Learner`](/basic_train.html#Learner), `loss_scale`:`float`=`512.0`, `flat_master`:`bool`=`False`) → [`Learner`](/basic_train.html#Learner)\n", "\n", "Transform `learn` in FP16 precision. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.to_fp16)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uses the [`MixedPrecision`](/callbacks.fp16.html#MixedPrecision) callback to train in mixed precision (i.e. forward and backward passes using fp16, with weight updates using fp32), using all [NVIDIA recommendations](https://docs.nvidia.com/deeplearning/sdk/mixed-precision-training/index.html) for ensuring speed and accuracy." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Discriminative layer training" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When fitting a model you can pass a list of learning rates (and/or weight decay amounts), which will apply a different rate to each *layer group* (i.e. the parameters of each module in `self.layer_groups`). See the [Universal Language Model Fine-tuning for Text Classification](https://arxiv.org/abs/1801.06146) paper for details and experimental results in NLP (we also frequently use them successfully in computer vision, but have not published a paper on this topic yet). When working with a [`Learner`](/basic_train.html#Learner) on which you've called `split`, you can set hyperparameters in four ways:\n", "\n", "1. `param = [val1, val2 ..., valn]` (n = number of layer groups)\n", "2. `param = val`\n", "3. `param = slice(start,end)`\n", "4. `param = slice(end)`\n", "\n", "If we chose to set it in way 1, we must specify a number of values exactly equal to the number of layer groups. If we chose to set it in way 2, the chosen value will be repeated for all layer groups. See [`Learner.lr_range`](/basic_train.html#Learner.lr_range) for an explanation of the `slice` syntax).\n", "\n", "Here's an example of how to use discriminative learning rates (note that you don't actually need to manually call [`Learner.split`](/basic_train.html#Learner.split) in this case, since fastai uses this exact function as the default split for `resnet18`; this is just to show how to customize it):" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "# creates 3 layer groups\n", "learn.split(lambda m: (m[0][6], m[1]))\n", "# only randomly initialized head now trainable\n", "learn.freeze()" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total time: 00:05\n", "epoch train_loss valid_loss accuracy\n", "1 0.038766 0.030721 0.990677 (00:05)\n", "\n" ] } ], "source": [ "learn.fit_one_cycle(1)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total time: 00:06\n", "epoch train_loss valid_loss accuracy\n", "1 0.035379 0.017087 0.995584 (00:06)\n", "\n" ] } ], "source": [ "# all layers now trainable\n", "learn.unfreeze()\n", "# optionally, separate LR and WD for each group\n", "learn.fit_one_cycle(1, max_lr=(1e-4, 1e-3, 1e-2), wd=(1e-4,1e-4,1e-1))" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

lr_range[source]

\n", "\n", "> lr_range(`lr`:`Union`\\[`float`, `slice`\\]) → `ndarray`\n", "\n", "Build differential learning rates. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.lr_range)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Rather than manually setting an LR for every group, it's often easier to use [`Learner.lr_range`](/basic_train.html#Learner.lr_range). This is a convenience method that returns one learning rate for each layer group. If you pass `slice(start,end)` then the first group's learning rate is `start`, the last is `end`, and the remaining are evenly geometrically spaced.\n", "\n", "If you pass just `slice(end)` then the last group's learning rate is `end`, and all the other groups are `end/3`. For instance (for our learner that has 3 layer groups):" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(array([1.e-05, 1.e-04, 1.e-03]), array([1.e-04, 1.e-04, 3.e-04]))" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.lr_range(slice(1e-5,1e-3)), learn.lr_range(slice(3e-4))" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

unfreeze[source]

\n", "\n", "> unfreeze()\n", "\n", "Unfreeze entire model. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.unfreeze)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sets every layer group to *trainable* (i.e. `requires_grad=True`)." ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

freeze[source]

\n", "\n", "> freeze()\n", "\n", "Freeze up to last layer. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.freeze)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sets every layer group except the last to *untrainable* (i.e. `requires_grad=False`)." ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

freeze_to[source]

\n", "\n", "> freeze_to(`n`:`int`)\n", "\n", "Freeze layers up to layer `n`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.freeze_to)" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

split[source]

\n", "\n", "> split(`split_on`:`SplitFuncOrIdxList`)\n", "\n", "Split the model at `split_on`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.split)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A convenience method that sets `layer_groups` based on the result of [`split_model`](/torch_core.html#split_model). If `split_on` is a function, it calls that function and passes the result to [`split_model`](/torch_core.html#split_model) (see above for example)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Saving and loading models" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Simply call [`Learner.save`](/basic_train.html#Learner.save) and [`Learner.load`](/basic_train.html#Learner.load) to save and load models. Only the parameters are saved, not the actual architecture (so you'll need to create your model in the same way before loading weights back in). Models are saved to the `path`/`model_dir` directory." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

load[source]

\n", "\n", "> load(`name`:`PathOrStr`, `device`:[`device`](https://pytorch.org/docs/stable/tensor_attributes.html#torch-device)=`None`)\n", "\n", "Load model `name` from `self.model_dir` using `device`, defaulting to `self.data.device`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.load)" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

save[source]

\n", "\n", "> save(`name`:`PathOrStr`, `return_path`:`bool`=`False`) → `Union`\\[`NoneType`, `str`\\]\n", "\n", "Save model with `name` to `self.model_dir`, and return path if `return_path`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.save)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Other methods" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "hide_input": false }, "outputs": [ { "data": { "text/markdown": [ "

validate[source]

\n", "\n", "> validate(`dl`=`None`, `callbacks`=`None`, `metrics`=`None`)\n", "\n", "Validate on `dl` with potential `callbacks` and `metrics`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.validate)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

init[source]

\n", "\n", "> init(`init`)" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.init)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Initializes all weights (except batchnorm) using function `init`, which will often be from PyTorch's [`nn.init`](https://pytorch.org/docs/stable/nn.html#torch-nn-init) module." ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

mixup[source]

\n", "\n", "> mixup(`learn`:[`Learner`](/basic_train.html#Learner), `alpha`:`float`=`0.4`, `stack_x`:`bool`=`False`, `stack_y`:`bool`=`True`) → [`Learner`](/basic_train.html#Learner)\n", "\n", "Add mixup https://arxiv.org/abs/1710.09412 to `learn`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.mixup)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Uses [`MixUpCallback`](/callbacks.mixup.html#MixUpCallback)." ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

pred_batch[source]

\n", "\n", "> pred_batch(`ds_type`:[`DatasetType`](/basic_data.html#DatasetType)=``, `pbar`:`Union`\\[`MasterBar`, `ProgressBar`, `NoneType`\\]=`None`) → `List`\\[`Tensor`\\]\n", "\n", "Return output of the model on one batch from valid, train, or test set, depending on `ds_type`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.pred_batch)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Get the first batch of predictions. Mainly useful for debugging and quick tests." ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

create_opt[source]

\n", "\n", "> create_opt(`lr`:`Floats`, `wd`:`Floats`=`0.0`)\n", "\n", "Create optimizer with `lr` learning rate and `wd` weight decay. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.create_opt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You generally won't need to call this yourself - it's used to create the [`optim`](https://pytorch.org/docs/stable/optim.html#module-torch.optim) optimizer before fitting the model." ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

class Recorder[source]

\n", "\n", "> Recorder(`learn`:[`Learner`](/basic_train.html#Learner)) :: [`LearnerCallback`](/basic_train.html#LearnerCallback)\n", "\n", "A [`LearnerCallback`](/basic_train.html#LearnerCallback) that records epoch, loss, opt and metric data during training. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder, title_level=2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A [`Learner`](/basic_train.html#Learner) creates a [`Recorder`](/basic_train.html#Recorder) object automatically - you do not need to explicitly pass to `callback_fns` - because other callbacks rely on it being available. It stores the smoothed loss, hyperparameter values, and metrics each batch, and provides plotting methods for each. Note that [`Learner`](/basic_train.html#Learner) automatically sets an attribute with the snake-cased name of each callback, so you can access this through `Learner.recorder`, as shown below." ] }, { "cell_type": "markdown", "metadata": { "hide_input": true }, "source": [ "### Plotting methods" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

plot[source]

\n", "\n", "> plot(`skip_start`:`int`=`10`, `skip_end`:`int`=`5`)\n", "\n", "Plot learning rate and losses, trimmed between `skip_start` and `skip_end`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.plot)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is mainly used with the learning rate finder, since it shows a scatterplot of loss vs learning rate." ] }, { "cell_type": "code", "execution_count": 28, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "LR Finder complete, type {learner_name}.recorder.plot() to see the graph.\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "learn = create_cnn(data, models.resnet18, metrics=accuracy)\n", "learn.lr_find()\n", "learn.recorder.plot()" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

plot_losses[source]

\n", "\n", "> plot_losses()\n", "\n", "Plot training and validation losses. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.plot_losses)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that validation losses are only calculated once per epoch, whereas training losses are calculated after every batch." ] }, { "cell_type": "code", "execution_count": 30, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Total time: 00:12\n", "epoch train_loss valid_loss accuracy\n", "1 0.113872 0.063511 0.976447 (00:06)\n", "2 0.055299 0.041133 0.987733 (00:05)\n", "\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "learn.fit_one_cycle(2)\n", "learn.recorder.plot_losses()" ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

plot_lr[source]

\n", "\n", "> plot_lr(`show_moms`=`False`)\n", "\n", "Plot learning rate, `show_moms` to include momentum. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.plot_lr)" ] }, { "cell_type": "code", "execution_count": 32, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "learn.recorder.plot_lr(show_moms=True)" ] }, { "cell_type": "code", "execution_count": 26, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

plot_metrics[source]

\n", "\n", "> plot_metrics()\n", "\n", "Plot metrics collected during training. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.plot_metrics)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that metrics are only collected at the end of each epoch, so you'll need to train at least two epochs to have anything to show here." ] }, { "cell_type": "code", "execution_count": 34, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "learn.recorder.plot_metrics()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Callback methods" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You don't call these yourself - they're called by fastai's [`callback`](/callback.html#callback) system automatically to enable the class's functionality." ] }, { "cell_type": "code", "execution_count": 27, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

on_backward_begin[source]

\n", "\n", "> on_backward_begin(`smooth_loss`:`Tensor`, `kwargs`:`Any`)\n", "\n", "Record the loss before any other callback has a chance to modify it. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.on_backward_begin)" ] }, { "cell_type": "code", "execution_count": 28, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

on_batch_begin[source]

\n", "\n", "> on_batch_begin(`train`, `kwargs`:`Any`)\n", "\n", "Record learning rate and momentum at beginning of batch. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.on_batch_begin)" ] }, { "cell_type": "code", "execution_count": 29, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

on_epoch_end[source]

\n", "\n", "> on_epoch_end(`epoch`:`int`, `num_batch`:`int`, `smooth_loss`:`Tensor`, `last_metrics`=`'Collection'`, `kwargs`:`Any`) → `bool`\n", "\n", "Save epoch info: num_batch, smooth_loss, metrics. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.on_epoch_end)" ] }, { "cell_type": "code", "execution_count": 30, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

on_train_begin[source]

\n", "\n", "> on_train_begin(`pbar`:`PBar`, `metrics_names`:`StrList`, `kwargs`:`Any`)\n", "\n", "Initialize recording status at beginning of training. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.on_train_begin)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Module functions" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Generally you'll want to use a [`Learner`](/basic_train.html#Learner) to train your model, since they provide a lot of functionality and make things easier. However, for ultimate flexibility, you can call the same underlying functions that [`Learner`](/basic_train.html#Learner) calls behind the scenes:" ] }, { "cell_type": "code", "execution_count": 31, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

fit[source]

\n", "\n", "> fit(`epochs`:`int`, `model`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module), `loss_func`:`LossFunction`, `opt`:[`Optimizer`](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), `data`:[`DataBunch`](/basic_data.html#DataBunch), `callbacks`:`Optional`\\[`Collection`\\[[`Callback`](/callback.html#Callback)\\]\\]=`None`, `metrics`:`OptMetrics`=`None`)\n", "\n", "Fit the `model` on `data` and learn using `loss` and `opt`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(fit)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note that you have to create the `Optimizer` yourself if you call this function, whereas [`Learn.fit`](/basic_train.html#fit) creates it for you automatically." ] }, { "cell_type": "code", "execution_count": 32, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

train_epoch[source]

\n", "\n", "> train_epoch(`model`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module), `dl`:[`DataLoader`](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader), `opt`:[`Optimizer`](https://pytorch.org/docs/stable/optim.html#torch.optim.Optimizer), `loss_func`:`LossFunction`)\n", "\n", "Simple training of `model` for 1 epoch of `dl` using optim `opt` and loss function `loss_func`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(train_epoch)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You won't generally need to call this yourself - it's what [`fit`](/basic_train.html#fit) calls for each epoch." ] }, { "cell_type": "code", "execution_count": 33, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

validate[source]

\n", "\n", "> validate(`model`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module), `dl`:[`DataLoader`](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader), `loss_func`:`OptLossFunc`=`None`, `cb_handler`:`Optional`\\[[`CallbackHandler`](/callback.html#CallbackHandler)\\]=`None`, `pbar`:`Union`\\[`MasterBar`, `ProgressBar`, `NoneType`\\]=`None`, `average`=`True`, `n_batch`:`Optional`\\[`int`\\]=`None`) → `Iterator`\\[`Tuple`\\[`IntOrTensor`, `Ellipsis`\\]\\]\n", "\n", "Calculate loss and metrics for the validation set. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(validate)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This is what [`fit`](/basic_train.html#fit) calls after each epoch. You can call it if you want to run inference on a [`DataLoader`](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader) manually." ] }, { "cell_type": "code", "execution_count": 34, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

get_preds[source]

\n", "\n", "> get_preds(`model`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module), `dl`:[`DataLoader`](https://pytorch.org/docs/stable/data.html#torch.utils.data.DataLoader), `pbar`:`Union`\\[`MasterBar`, `ProgressBar`, `NoneType`\\]=`None`, `cb_handler`:`Optional`\\[[`CallbackHandler`](/callback.html#CallbackHandler)\\]=`None`, `activ`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module)=`None`, `loss_func`:`OptLossFunc`=`None`, `n_batch`:`Optional`\\[`int`\\]=`None`) → `List`\\[`Tensor`\\]\n", "\n", "Tuple of predictions and targets, and optional losses (if `loss_func`) using `dl`, max batches `n_batch`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(get_preds)" ] }, { "cell_type": "code", "execution_count": 35, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

loss_batch[source]

\n", "\n", "> loss_batch(`model`:[`Module`](https://pytorch.org/docs/stable/nn.html#torch.nn.Module), `xb`:`Tensor`, `yb`:`Tensor`, `loss_func`:`OptLossFunc`=`None`, `opt`:`OptOptimizer`=`None`, `cb_handler`:`Optional`\\[[`CallbackHandler`](/callback.html#CallbackHandler)\\]=`None`) → `Tuple`\\[`Union`\\[`Tensor`, `int`, `float`, `str`\\]\\]\n", "\n", "Calculate loss and metrics for a batch, call out to callbacks as necessary. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(loss_batch)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You won't generally need to call this yourself - it's what [`fit`](/basic_train.html#fit) and [`validate`](/basic_train.html#validate) call for each batch. It only does a backward pass if you set `opt`." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Other classes" ] }, { "cell_type": "code", "execution_count": 36, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

class LearnerCallback[source]

\n", "\n", "> LearnerCallback(`learn`:[`Learner`](/basic_train.html#Learner)) :: [`Callback`](/callback.html#Callback)\n", "\n", "Base class for creating callbacks for a [`Learner`](/basic_train.html#Learner). " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(LearnerCallback, title_level=3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Undocumented Methods - Methods moved below this line will intentionally be hidden" ] }, { "cell_type": "code", "execution_count": 37, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

_tta_only[source]

\n", "\n", "> _tta_only(`learn`:[`Learner`](/basic_train.html#Learner), `ds_type`:[`DatasetType`](/basic_data.html#DatasetType)=``, `scale`:`float`=`1.35`) → `Iterator`\\[`List`\\[`Tensor`\\]\\]\n", "\n", "Computes the outputs for several augmented inputs for TTA " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.tta_only)" ] }, { "cell_type": "code", "execution_count": 38, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

get_preds[source]

\n", "\n", "> get_preds(`ds_type`:[`DatasetType`](/basic_data.html#DatasetType)=``, `with_loss`:`bool`=`False`, `n_batch`:`Optional`\\[`int`\\]=`None`, `pbar`:`Union`\\[`MasterBar`, `ProgressBar`, `NoneType`\\]=`None`) → `List`\\[`Tensor`\\]\n", "\n", "Return predictions and targets on the valid, train, or test set, depending on `ds_type`. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.get_preds)" ] }, { "cell_type": "code", "execution_count": 39, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

_TTA[source]

\n", "\n", "> _TTA(`learn`:[`Learner`](/basic_train.html#Learner), `beta`:`float`=`0.4`, `scale`:`float`=`1.35`, `ds_type`:[`DatasetType`](/basic_data.html#DatasetType)=``, `with_loss`:`bool`=`False`) → `Tensors`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Learner.TTA)" ] }, { "cell_type": "code", "execution_count": 40, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

format_stats[source]

\n", "\n", "> format_stats(`stats`:`MetricsList`)\n", "\n", "Format stats before printing. " ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.format_stats)" ] }, { "cell_type": "code", "execution_count": 41, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "

add_metrics[source]

\n", "\n", "> add_metrics(`metrics`)" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.add_metrics)" ] }, { "cell_type": "code", "execution_count": 42, "metadata": { "hide_input": false }, "outputs": [ { "data": { "text/markdown": [ "

add_metric_names[source]

\n", "\n", "> add_metric_names(`names`)" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Recorder.add_metric_names)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## New Methods - Please document or move to the undocumented section" ] } ], "metadata": { "jekyll": { "keywords": "fastai", "summary": "Learner class and training loop", "title": "basic_train" }, "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.6.6" }, "toc": { "base_numbering": 1, "nav_menu": {}, "number_sections": false, "sideBar": true, "skip_h1_title": false, "title_cell": "Table of Contents", "title_sidebar": "Contents", "toc_cell": false, "toc_position": {}, "toc_section_display": true, "toc_window_display": false } }, "nbformat": 4, "nbformat_minor": 2 }