{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Create a Learner for inference" ] }, { "cell_type": "code", "execution_count": 1, "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": [ "
docs_src folder of the\n",
"fastai repo. We use the saved models from this tutorial to\n",
"have this notebook run quickly.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": 2,
"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 = (ImageList.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 = cnn_learner(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.5275, 0.4725]))"
]
},
"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=ImageList.from_folder(mnist/'test'))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"tensor([[0.9866, 0.0134],\n",
" [0.0019, 0.9981],\n",
" [0.9721, 0.0279],\n",
" [0.0067, 0.9933],\n",
" [0.9966, 0.0034]])"
]
},
"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 = (ImageList.from_csv(planet, 'labels.csv', folder='train', suffix='.jpg')\n",
" .split_by_rand_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 = cnn_learner(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 blooming;clear;habitation;haze;primary,\n",
" tensor([0., 0., 0., 1., 1., 0., 0., 1., 1., 0., 1., 0., 0., 0.]),\n",
" tensor([0.1906, 0.3646, 0.3146, 0.6931, 0.6352, 0.3982, 0.3114, 0.5396, 0.5245,\n",
" 0.3933, 0.6069, 0.1630, 0.4260, 0.2641]))"
]
},
"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 artisinal_mine;bare_ground;blooming;clear;cloudy;cultivation;habitation;haze;partly_cloudy;primary;selective_logging,\n",
" tensor([0., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 0., 1., 0.]),\n",
" tensor([0.1906, 0.3646, 0.3146, 0.6931, 0.6352, 0.3982, 0.3114, 0.5396, 0.5245,\n",
" 0.3933, 0.6069, 0.1630, 0.4260, 0.2641]))"
]
},
"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",
" .split_by_rand_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 = cnn_learner(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([[ 2.2184, -0.3693]]),\n",
" tensor([ 2.2184, -0.3693]))"
]
},
"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": [
"| epoch | \n", "train_loss | \n", "valid_loss | \n", "accuracy | \n", "time | \n", "
|---|---|---|---|---|
| 0 | \n", "0.337445 | \n", "0.360488 | \n", "0.845000 | \n", "00:04 | \n", "