{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a Learner for inference" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide_input": true }, "outputs": [], "source": [ "from fastai.gen_doc.nbdoc import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial, we'll see how the same API allows you to create an empty [`DataBunch`](/basic_data.html#DataBunch) for a [`Learner`](/basic_train.html#Learner) at inference time (once you have trained your model) and how to call the `predict` method to get the predictions on a single item." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "hide_input": true }, "outputs": [ { "data": { "text/markdown": [ "
Note: As usual, this page is generated from a notebook that you can find in the docs_src folder of the\n", "fastai repo. We use the saved models from this tutorial to\n", "have this notebook run quickly.
" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "jekyll_note(\"\"\"As usual, this page is generated from a notebook that you can find in the docs_src folder of the\n", "fastai repo. We use the saved models from this tutorial to\n", "have this notebook run quickly.\"\"\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Vision" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To quickly get acces to all the vision functionality inside fastai, we use the usual import statements." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from fastai.vision import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A classification problem" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's begin with our sample of the MNIST dataset." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mnist = untar_data(URLs.MNIST_TINY)\n", "tfms = get_transforms(do_flip=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It's set up with an imagenet structure so we use it to split our training and validation set, then labelling." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = (ImageItemList.from_folder(mnist)\n", " .split_by_folder() \n", " .label_from_folder()\n", " .add_test_folder('test')\n", " .transform(tfms, size=32)\n", " .databunch()\n", " .normalize(imagenet_stats)) " ] }, { "cell_type": "markdown", "metadata": { "hide_input": true }, "source": [ "Now that our data has been properly set up, we can train a model. We already did in the [look at your data tutorial](/tutorial.data.html) so we'll just load our saved results here." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = create_cnn(data, models.resnet18).load('mini_train')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Once everything is ready for inference, we just have to call `learn.export` to save all the information of our [`Learner`](/basic_train.html#Learner) object for inference: the stuff we need in the [`DataBunch`](/basic_data.html#DataBunch) (transforms, classes, normalization...), the model with its weights and all the callbacks our [`Learner`](/basic_train.html#Learner) was using. Everything will be in a file named `export.pkl` in the folder `learn.path`. If you deploy your model on a different machine, this is the file you'll need to copy." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.export()" ] }, { "cell_type": "markdown", "metadata": { "hide_input": false }, "source": [ "To create the [`Learner`](/basic_train.html#Learner) for inference, you'll need to use the [`load_learner`](/basic_train.html#load_learner) function. Note that you don't have to specify anything: it remembers the classes, the transforms you used or the normalization in the data, the model, its weigths... The only argument needed is the folder where the 'export.pkl' file is." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(mnist)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can now get the predictions on any image via `learn.predict`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Category 3, tensor(0), tensor([0.9015, 0.0985]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "img = data.train_ds[0][0]\n", "learn.predict(img)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It returns a tuple of three things: the object predicted (with the class in this instance), the underlying data (here the corresponding index) and the raw probabilities. You can also do inference on a larger set of data by adding a *test set*. This is done by passing an [`ItemList`](/data_block.html#ItemList) to [`load_learner`](/basic_train.html#load_learner)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(mnist, test=ImageItemList.from_folder(mnist/'test'))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "tensor([[9.9978e-01, 2.2008e-04],\n", " [3.1552e-02, 9.6845e-01],\n", " [9.9515e-01, 4.8547e-03],\n", " [7.1560e-02, 9.2844e-01],\n", " [1.0000e+00, 1.2721e-06]])" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "preds,y = learn.get_preds(ds_type=DatasetType.Test)\n", "preds[:5]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A multi-label problem" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's try these on the planet dataset, which is a little bit different in the sense that each image can have multiple tags (and not just one label)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "planet = untar_data(URLs.PLANET_TINY)\n", "planet_tfms = get_transforms(flip_vert=True, max_lighting=0.1, max_zoom=1.05, max_warp=0.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here each images is labelled in a file named `labels.csv`. We have to add [`train`](/train.html#train) as a prefix to the filenames, `.jpg` as a suffix and indicate that the labels are separated by spaces." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = (ImageItemList.from_csv(planet, 'labels.csv', folder='train', suffix='.jpg')\n", " .random_split_by_pct()\n", " .label_from_df(label_delim=' ')\n", " .transform(planet_tfms, size=128)\n", " .databunch()\n", " .normalize(imagenet_stats))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again, we load the model we saved in [look at your data tutorial](/tutorial.data.html)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = create_cnn(data, models.resnet18).load('mini_train')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we can export it before loading it for inference." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.export()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(planet)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we get the predictions on any image via `learn.predict`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(MultiCategory bare_ground;blooming;cloudy;habitation;partly_cloudy;primary;road;water,\n", " tensor([0., 0., 1., 1., 0., 1., 0., 1., 0., 1., 1., 1., 0., 1.]),\n", " tensor([0.3854, 0.3561, 0.5048, 0.6472, 0.0455, 0.6449, 0.1848, 0.8743, 0.2392,\n", " 0.9379, 0.5506, 0.8288, 0.4949, 0.7091]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "img = data.train_ds[0][0]\n", "learn.predict(img)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Here we can specify a particular threshold to consider the predictions to be correct or not. The default is `0.5`, but we can change it." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(MultiCategory agriculture;artisinal_mine;bare_ground;blooming;cloudy;habitation;partly_cloudy;primary;road;selective_logging;water,\n", " tensor([1., 1., 1., 1., 0., 1., 0., 1., 0., 1., 1., 1., 1., 1.]),\n", " tensor([0.3854, 0.3561, 0.5048, 0.6472, 0.0455, 0.6449, 0.1848, 0.8743, 0.2392,\n", " 0.9379, 0.5506, 0.8288, 0.4949, 0.7091]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.predict(img, thresh=0.3)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A regression example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For the next example, we are going to use the [BIWI head pose](https://data.vision.ee.ethz.ch/cvl/gfanelli/head_pose/head_forest.html#db) dataset. On pictures of persons, we have to find the center of their face. For the fastai docs, we have built a small subsample of the dataset (200 images) and prepared a dictionary for the correspondance filename to center." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "biwi = untar_data(URLs.BIWI_SAMPLE)\n", "fn2ctr = pickle.load(open(biwi/'centers.pkl', 'rb'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To grab our data, we use this dictionary to label our items. We also use the [`PointsItemList`](/vision.data.html#PointsItemList) class to have the targets be of type [`ImagePoints`](/vision.image.html#ImagePoints) (which will make sure the data augmentation is properly applied to them). When calling [`transform`](/tabular.transform.html#tabular.transform) we make sure to set `tfm_y=True`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = (PointsItemList.from_folder(biwi)\n", " .random_split_by_pct(seed=42)\n", " .label_from_func(lambda o:fn2ctr[o.name])\n", " .transform(get_transforms(), tfm_y=True, size=(120,160))\n", " .databunch()\n", " .normalize(imagenet_stats))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As before, the road to inference is pretty straightforward: load the model we trained before, export the [`Learner`](/basic_train.html#Learner) then load it for production." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = create_cnn(data, models.resnet18, lin_ftrs=[100], ps=0.05).load('mini_train');" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.export()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(biwi)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now we can a prediction on an image." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(ImagePoints (120, 160),\n", " tensor([[-0.0006, 0.2947]]),\n", " tensor([-0.0006, 0.2947]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "img = data.valid_ds[0][0]\n", "learn.predict(img)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To visualize the predictions, we can use the [`Image.show`](/vision.image.html#Image.show) method." ] }, { "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": [ "img.show(y=learn.predict(img)[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A segmentation example" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we are going to look at the [camvid dataset](http://mi.eng.cam.ac.uk/research/projects/VideoRec/CamVid/) (at least a small sample of it), where we have to predict the class of each pixel in an image. Each image in the 'images' subfolder as an equivalent in 'labels' that is its segmentations mask." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "camvid = untar_data(URLs.CAMVID_TINY)\n", "path_lbl = camvid/'labels'\n", "path_img = camvid/'images'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We read the classes in 'codes.txt' and the function maps each image filename with its corresponding mask filename." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "codes = np.loadtxt(camvid/'codes.txt', dtype=str)\n", "get_y_fn = lambda x: path_lbl/f'{x.stem}_P{x.suffix}'" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The data block API allows us to uickly get everything in a [`DataBunch`](/basic_data.html#DataBunch) and then we can have a look with `show_batch`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = (SegmentationItemList.from_folder(path_img)\n", " .random_split_by_pct()\n", " .label_from_func(get_y_fn, classes=codes)\n", " .transform(get_transforms(), tfm_y=True, size=128)\n", " .databunch(bs=16, path=camvid)\n", " .normalize(imagenet_stats))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As before, we load our model, export the [`Learner`](/basic_train.html#Learner) then create a new one with [`load_learner`](/basic_train.html#load_learner)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = unet_learner(data, models.resnet18).load('mini_train');\n", "learn.export()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(camvid)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And now we can a prediction on an image." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "img = data.train_ds[0][0]\n", "learn.predict(img);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To visualize the predictions, we can use the [`Image.show`](/vision.image.html#Image.show) method." ] }, { "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": [ "img.show(y=learn.predict(img)[0])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Text" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next application is text, so let's start by importing everything we'll need." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from fastai.text import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Language modelling" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First let's look a how to get a language model ready for inference. Since we'll load the model trained in the [visualize data tutorial](/tutorial.data.html), we load the vocabulary used there." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "imdb = untar_data(URLs.IMDB_SAMPLE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "vocab = Vocab(pickle.load(open(imdb/'tmp'/'itos.pkl', 'rb')))\n", "data_lm = (TextList.from_csv(imdb, 'texts.csv', cols='text', vocab=vocab)\n", " .random_split_by_pct()\n", " .label_for_lm()\n", " .databunch())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Like in vision, we just have to type `learn.export()` after loading our pretrained model to save all the information inside the [`Learner`](/basic_train.html#Learner) we'll need. In this case, this includes all the vocabulary we created. The only difference is that we will specify a filename, since we have several model in the same path (language model and classifier)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = language_model_learner(data_lm, AWD_LSTM, pretrained=False).load('mini_train_lm', with_opt=False);" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.export(fname = 'export_lm.pkl')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's define our inference learner." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(imdb, fname = 'export_lm.pkl')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we can predict with the usual method, here we can specify how many words we want the model to predict." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'This is a simple test of the ideas trade with fill promised public time . Current , its performs may be performed by either anyone'" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.predict('This is a simple test of', n_words=20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can also use beam search to generate text." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "'This is a simple test of New York City and Los Angeles and Los Angeles . Although the'" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.beam_search('This is a simple test of', n_words=20, beam_sz=200)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Classification" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's see a classification example. We have to use the same vocabulary as for the language model if we want to be able to use the encoder we saved." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data_clas = (TextList.from_csv(imdb, 'texts.csv', cols='text', vocab=vocab)\n", " .split_from_df(col='is_valid')\n", " .label_from_df(cols='label')\n", " .databunch(bs=42))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Again we export the [`Learner`](/basic_train.html#Learner) where we load our pretrained model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = text_classifier_learner(data_clas, AWD_LSTM, pretrained=False).load('mini_train_clas', with_opt=False);\n", "learn.export(fname = 'export_clas.pkl')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now let's use [`load_learner`](/basic_train.html#load_learner)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(imdb, fname = 'export_clas.pkl')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we can predict with the usual method." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Category negative, tensor(0), tensor([0.5483, 0.4517]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.predict('I really loved that movie!')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Tabular" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Last application brings us to tabular data. First let's import everything we'll need." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from fastai.tabular import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We'll use a sample of the [adult dataset](https://archive.ics.uci.edu/ml/datasets/adult) here. Once we read the csv file, we'll need to specify the dependant variable, the categorical variables, the continuous variables and the processors we want to use." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "adult = untar_data(URLs.ADULT_SAMPLE)\n", "df = pd.read_csv(adult/'adult.csv')\n", "dep_var = 'salary'\n", "cat_names = ['workclass', 'education', 'marital-status', 'occupation', 'relationship', 'race', 'sex', 'native-country']\n", "cont_names = ['education-num', 'hours-per-week', 'age', 'capital-loss', 'fnlwgt', 'capital-gain']\n", "procs = [FillMissing, Categorify, Normalize]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we can use the data block API to grab everything together." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = (TabularList.from_df(df, path=adult, cat_names=cat_names, cont_names=cont_names, procs=procs)\n", " .split_by_idx(valid_idx=range(800,1000))\n", " .label_from_df(cols=dep_var)\n", " .databunch())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We define a [`Learner`](/basic_train.html#Learner) object that we fit and then save the model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/html": [ "Total time: 00:04

\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
epochtrain_lossvalid_lossaccuracy
10.3283250.3675150.845000
\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "learn = tabular_learner(data, layers=[200,100], metrics=accuracy)\n", "learn.fit(1, 1e-2)\n", "learn.save('mini_train')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As in the other applications, we just have to type `learn.export()` to save everything we'll need for inference (here it includes the inner state of each processor)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn.export()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we create a [`Learner`](/basic_train.html#Learner) for inference like before." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "learn = load_learner(adult)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we can predict on a row of dataframe that has the right `cat_names` and `cont_names`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(Category >=50k, tensor(1), tensor([0.3528, 0.6472]))" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "learn.predict(df.iloc[0])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "jekyll": { "keywords": "fastai", "summary": "Intermediate tutorial, explains how to create a Learner for inference", "title": "Inference Learner" }, "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 2 }