{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#default_exp vision.data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "from local.test import *\n", "from local.torch_basics import *\n", "from local.data.all import *\n", "\n", "from local.vision.core import *" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from local.notebook.showdoc import *" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Vision data\n", "\n", "> Helper functions to get data in a `DataBunch` un the vision applicaiton and higher class `ImageDataBunch`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## ImageDataBunch -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ImageDataBunch(DataBunch): \n", " \n", " @classmethod\n", " @delegates(DataBunch.from_dblock)\n", " def from_folder(cls, path, train='train', valid='valid', valid_pct=None, seed=None, vocab=None, **kwargs):\n", " \"Create from imagenet style dataset in `path` with `train`,`valid`,`test` subfolders (or provide `valid_pct`).\"\n", " splitter = GrandparentSplitter(train_name=train, valid_name=valid) if valid_pct is None else RandomSplitter(valid_pct, seed=seed)\n", " dblock = DataBlock(blocks=(ImageBlock, CategoryBlock(vocab=vocab)),\n", " get_items=get_image_files,\n", " splitter=splitter,\n", " get_y=parent_label)\n", " return cls.from_dblock(dblock, path, path=path, **kwargs)\n", "\n", " @classmethod\n", " @delegates(DataBunch.from_dblock)\n", " def from_name_func(cls, path, fnames, label_func, valid_pct=0.2, seed=None, **kwargs):\n", " \"Create from list of `fnames` in `path`s with `label_func`.\"\n", " dblock = DataBlock(blocks=(ImageBlock, CategoryBlock),\n", " splitter=RandomSplitter(valid_pct, seed=seed),\n", " get_y=label_func)\n", " return cls.from_dblock(dblock, fnames, path=path, **kwargs)\n", " \n", " @classmethod\n", " @delegates(DataBunch.from_dblock)\n", " def from_name_re(cls, path, fnames, pat, **kwargs):\n", " \"Create from list of `fnames` in `path`s with re expression `pat`.\"\n", " return cls.from_name_func(path, fnames, RegexLabeller(pat), **kwargs)\n", " \n", " @classmethod\n", " @delegates(DataBunch.from_dblock)\n", " def from_df(cls, df, path='.', valid_pct=0.2, seed=None, fn_col=0, folder=None, suff='', label_col=1, label_delim=None, y_block=None, **kwargs):\n", " pref = f'{Path(path) if folder is None else Path(path)/folder}{os.path.sep}'\n", " if y_block is None: y_block = MultiCategoryBlock if is_listy(label_col) and len(label_col) > 1 else CategoryBlock\n", " dblock = DataBlock(blocks=(ImageBlock, y_block),\n", " get_x=ColReader(fn_col, pref=pref, suff=suff),\n", " get_y=ColReader(label_col, label_delim=label_delim),\n", " splitter=RandomSplitter(valid_pct, seed=seed))\n", " return cls.from_dblock(dblock, df, path=path, **kwargs)\n", " \n", " @classmethod\n", " def from_csv(cls, path, csv_fname='labels.csv', header='infer', delimiter=None, **kwargs):\n", " df = pd.read_csv(Path(path)/csv_fname, header=header, delimiter=delimiter)\n", " return cls.from_df(df, path=path, **kwargs)\n", " \n", " @classmethod\n", " @delegates(DataBunch.from_dblock)\n", " def from_lists(cls, path, fnames, labels, valid_pct=0.2, seed:int=None, y_block=None, **kwargs):\n", " \"Create from list of `fnames` in `path`.\"\n", " if y_block is None:\n", " y_block = MultiCategoryBlock if is_listy(labels[0]) and len(labels[0]) > 1 else (TransformBlock if isinstance(labels[0], float) else CategoryBlock)\n", " dblock = DataBlock(blocks=(ImageBlock, y_block),\n", " splitter=RandomSplitter(valid_pct, seed=seed))\n", " return cls.from_dblock(dblock, (fnames, labels), path=path, **kwargs)\n", " \n", "ImageDataBunch.from_csv = delegates(to=ImageDataBunch.from_df)(ImageDataBunch.from_csv)\n", "ImageDataBunch.from_name_re = delegates(to=ImageDataBunch.from_name_func)(ImageDataBunch.from_name_re)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ImageDataBunch.from_folder[source]

\n", "\n", "> ImageDataBunch.from_folder(**`path`**, **`train`**=*`'train'`*, **`valid`**=*`'valid'`*, **`valid_pct`**=*`None`*, **`seed`**=*`None`*, **`vocab`**=*`None`*, **`type_tfms`**=*`None`*, **`item_tfms`**=*`None`*, **`batch_tfms`**=*`None`*, **`bs`**=*`16`*, **`shuffle`**=*`False`*, **`num_workers`**=*`None`*, **`pin_memory`**=*`False`*, **`timeout`**=*`0`*, **`drop_last`**=*`False`*, **`indexed`**=*`None`*, **`n`**=*`None`*, **`wif`**=*`None`*, **`before_iter`**=*`None`*, **`create_batches`**=*`None`*, **`create_item`**=*`None`*, **`after_item`**=*`None`*, **`before_batch`**=*`None`*, **`create_batch`**=*`None`*, **`retain`**=*`None`*, **`after_batch`**=*`None`*, **`after_iter`**=*`None`*)\n", "\n", "Create from imagenet style dataset in `path` with `train`,`valid`,[`test`](/test.html) subfolders (or provide `valid_pct`)." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ImageDataBunch.from_folder)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ImageDataBunch.from_name_func[source]

\n", "\n", "> ImageDataBunch.from_name_func(**`path`**, **`fnames`**, **`label_func`**, **`valid_pct`**=*`0.2`*, **`seed`**=*`None`*, **`type_tfms`**=*`None`*, **`item_tfms`**=*`None`*, **`batch_tfms`**=*`None`*, **`bs`**=*`16`*, **`shuffle`**=*`False`*, **`num_workers`**=*`None`*, **`pin_memory`**=*`False`*, **`timeout`**=*`0`*, **`drop_last`**=*`False`*, **`indexed`**=*`None`*, **`n`**=*`None`*, **`wif`**=*`None`*, **`before_iter`**=*`None`*, **`create_batches`**=*`None`*, **`create_item`**=*`None`*, **`after_item`**=*`None`*, **`before_batch`**=*`None`*, **`create_batch`**=*`None`*, **`retain`**=*`None`*, **`after_batch`**=*`None`*, **`after_iter`**=*`None`*)\n", "\n", "Create from list of `fnames` in `path`s with `label_func`." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ImageDataBunch.from_name_func)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ImageDataBunch.from_name_re[source]

\n", "\n", "> ImageDataBunch.from_name_re(**`path`**, **`fnames`**, **`pat`**, **`valid_pct`**=*`0.2`*, **`seed`**=*`None`*, **`type_tfms`**=*`None`*, **`item_tfms`**=*`None`*, **`batch_tfms`**=*`None`*, **`bs`**=*`16`*, **`shuffle`**=*`False`*, **`num_workers`**=*`None`*, **`pin_memory`**=*`False`*, **`timeout`**=*`0`*, **`drop_last`**=*`False`*, **`indexed`**=*`None`*, **`n`**=*`None`*, **`wif`**=*`None`*, **`before_iter`**=*`None`*, **`create_batches`**=*`None`*, **`create_item`**=*`None`*, **`after_item`**=*`None`*, **`before_batch`**=*`None`*, **`create_batch`**=*`None`*, **`retain`**=*`None`*, **`after_batch`**=*`None`*, **`after_iter`**=*`None`*)\n", "\n", "Create from list of `fnames` in `path`s with re expression `pat`." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ImageDataBunch.from_name_re)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ImageDataBunch.from_df[source]

\n", "\n", "> ImageDataBunch.from_df(**`df`**, **`path`**=*`'.'`*, **`valid_pct`**=*`0.2`*, **`seed`**=*`None`*, **`fn_col`**=*`0`*, **`pref`**=*`''`*, **`suff`**=*`''`*, **`label_col`**=*`1`*, **`label_delim`**=*`None`*, **`type_tfms`**=*`None`*, **`item_tfms`**=*`None`*, **`batch_tfms`**=*`None`*, **`bs`**=*`16`*, **`shuffle`**=*`False`*, **`num_workers`**=*`None`*, **`pin_memory`**=*`False`*, **`timeout`**=*`0`*, **`drop_last`**=*`False`*, **`indexed`**=*`None`*, **`n`**=*`None`*, **`wif`**=*`None`*, **`before_iter`**=*`None`*, **`create_batches`**=*`None`*, **`create_item`**=*`None`*, **`after_item`**=*`None`*, **`before_batch`**=*`None`*, **`create_batch`**=*`None`*, **`retain`**=*`None`*, **`after_batch`**=*`None`*, **`after_iter`**=*`None`*)\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ImageDataBunch.from_df)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ImageDataBunch.from_csv[source]

\n", "\n", "> ImageDataBunch.from_csv(**`path`**, **`csv_fname`**=*`'labels.csv'`*, **`header`**=*`'infer'`*, **`delimiter`**=*`None`*, **`valid_pct`**=*`0.2`*, **`seed`**=*`None`*, **`fn_col`**=*`0`*, **`pref`**=*`''`*, **`suff`**=*`''`*, **`label_col`**=*`1`*, **`label_delim`**=*`None`*, **`type_tfms`**=*`None`*, **`item_tfms`**=*`None`*, **`batch_tfms`**=*`None`*, **`bs`**=*`16`*, **`shuffle`**=*`False`*, **`num_workers`**=*`None`*, **`pin_memory`**=*`False`*, **`timeout`**=*`0`*, **`drop_last`**=*`False`*, **`indexed`**=*`None`*, **`n`**=*`None`*, **`wif`**=*`None`*, **`before_iter`**=*`None`*, **`create_batches`**=*`None`*, **`create_item`**=*`None`*, **`after_item`**=*`None`*, **`before_batch`**=*`None`*, **`create_batch`**=*`None`*, **`retain`**=*`None`*, **`after_batch`**=*`None`*, **`after_iter`**=*`None`*)\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ImageDataBunch.from_csv)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

ImageDataBunch.from_lists[source]

\n", "\n", "> ImageDataBunch.from_lists(**`path`**, **`fnames`**, **`labels`**, **`valid_pct`**=*`0.2`*, **`seed`**:`int`=*`None`*, **`y_block`**=*`None`*, **`type_tfms`**=*`None`*, **`item_tfms`**=*`None`*, **`batch_tfms`**=*`None`*, **`bs`**=*`16`*, **`shuffle`**=*`False`*, **`num_workers`**=*`None`*, **`pin_memory`**=*`False`*, **`timeout`**=*`0`*, **`drop_last`**=*`False`*, **`indexed`**=*`None`*, **`n`**=*`None`*, **`wif`**=*`None`*, **`before_iter`**=*`None`*, **`create_batches`**=*`None`*, **`create_item`**=*`None`*, **`after_item`**=*`None`*, **`before_batch`**=*`None`*, **`create_batch`**=*`None`*, **`retain`**=*`None`*, **`after_batch`**=*`None`*, **`after_iter`**=*`None`*)\n", "\n", "Create from list of `fnames` in `path`." ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(ImageDataBunch.from_lists)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Show methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def get_grid(n, rows=None, cols=None, add_vert=0, figsize=None, double=False, title=None, return_fig=False):\n", " rows = rows or int(np.ceil(math.sqrt(n)))\n", " cols = cols or int(np.ceil(n/rows))\n", " if double: cols*=2 ; n*=2\n", " figsize = (cols*3, rows*3+add_vert) if figsize is None else figsize\n", " fig,axs = subplots(rows, cols, figsize=figsize)\n", " axs = axs.flatten()\n", " for ax in axs[n:]: ax.set_axis_off()\n", " if title is not None: fig.suptitle(title, weight='bold', size=14)\n", " return (fig,axs) if return_fig else axs" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "@typedispatch\n", "def show_batch(x:TensorImage, y, samples, ctxs=None, max_n=10, rows=None, cols=None, figsize=None, **kwargs):\n", " if ctxs is None: ctxs = get_grid(min(len(samples), max_n), rows=rows, cols=cols, figsize=figsize)\n", " ctxs = show_batch[object](x, y, samples, ctxs=ctxs, max_n=max_n, **kwargs)\n", " return ctxs" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Helper functions for object detection" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# export\n", "def clip_remove_empty(bbox, label):\n", " \"Clip bounding boxes with image border and label background the empty ones.\"\n", " bbox = torch.clamp(bbox, -1, 1)\n", " empty = ((bbox[...,2] - bbox[...,0])*(bbox[...,3] - bbox[...,1]) < 0.)\n", " return (bbox[~empty], label[~empty])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bb = tensor([[-2,-0.5,0.5,1.5], [-0.5,-0.5,0.5,0.5], [1,0.5,0.5,0.75], [-0.5,-0.5,0.5,0.5]])\n", "bb,lbl = clip_remove_empty(bb, tensor([1,2,3,2]))\n", "test_eq(bb, tensor([[-1,-0.5,0.5,1.], [-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5]]))\n", "test_eq(lbl, tensor([1,2,2]))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def bb_pad(samples, pad_idx=0):\n", " \"Function that collect `samples` of labelled bboxes and adds padding with `pad_idx`.\"\n", " samples = [(s[0], *clip_remove_empty(*s[1:])) for s in samples]\n", " max_len = max([len(s[2]) for s in samples])\n", " def _f(img,bbox,lbl):\n", " bbox = torch.cat([bbox,bbox.new_zeros(max_len-bbox.shape[0], 4)])\n", " lbl = torch.cat([lbl, lbl .new_zeros(max_len-lbl .shape[0])+pad_idx])\n", " return img,bbox,lbl\n", " return [_f(*s) for s in samples]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "img1,img2 = TensorImage(torch.randn(16,16,3)),TensorImage(torch.randn(16,16,3))\n", "bb1 = tensor([[-2,-0.5,0.5,1.5], [-0.5,-0.5,0.5,0.5], [1,0.5,0.5,0.75], [-0.5,-0.5,0.5,0.5]])\n", "lbl1 = tensor([1, 2, 3, 2])\n", "bb2 = tensor([[-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5]])\n", "lbl2 = tensor([2, 2])\n", "samples = [(img1, bb1, lbl1), (img2, bb2, lbl2)]\n", "res = bb_pad(samples)\n", "non_empty = tensor([True,True,False,True])\n", "test_eq(res[0][0], img1)\n", "test_eq(res[0][1], tensor([[-1,-0.5,0.5,1.], [-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5]]))\n", "test_eq(res[0][2], tensor([1,2,2]))\n", "test_eq(res[1][0], img2)\n", "test_eq(res[1][1], tensor([[-0.5,-0.5,0.5,0.5], [-0.5,-0.5,0.5,0.5], [0,0,0,0]]))\n", "test_eq(res[1][2], tensor([2,2,0])) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## `TransformBlock`s for vision" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def ImageBlock(cls=PILImage): return TransformBlock(type_tfms=cls.create, batch_tfms=IntToFloatTensor)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "MaskBlock = TransformBlock(type_tfms=PILMask.create, batch_tfms=IntToFloatTensor)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "PointBlock = TransformBlock(type_tfms=TensorPoint.create, item_tfms=PointScaler)\n", "BBoxBlock = TransformBlock(type_tfms=TensorBBox.create, item_tfms=PointScaler, dbunch_kwargs = {'before_batch': bb_pad})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "BBoxBlock = TransformBlock(type_tfms=TensorBBox.create, item_tfms=PointScaler, dbunch_kwargs = {'before_batch': bb_pad})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def BBoxLblBlock(vocab=None, add_na=True):\n", " return TransformBlock(type_tfms=MultiCategorize(vocab=vocab, add_na=add_na), item_tfms=BBoxLabeler)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Export -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Converted 00_test.ipynb.\n", "Converted 01_core_foundation.ipynb.\n", "Converted 01a_core_utils.ipynb.\n", "Converted 01b_core_dispatch.ipynb.\n", "Converted 01c_core_transform.ipynb.\n", "Converted 02_core_script.ipynb.\n", "Converted 03_torchcore.ipynb.\n", "Converted 03a_layers.ipynb.\n", "Converted 04_data_load.ipynb.\n", "Converted 05_data_core.ipynb.\n", "Converted 06_data_transforms.ipynb.\n", "Converted 07_data_block.ipynb.\n", "Converted 08_vision_core.ipynb.\n", "Converted 09_vision_augment.ipynb.\n", "Converted 09a_vision_data.ipynb.\n", "Converted 10_pets_tutorial.ipynb.\n", "Converted 11_vision_models_xresnet.ipynb.\n", "Converted 12_optimizer.ipynb.\n", "Converted 13_learner.ipynb.\n", "Converted 13a_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 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_transfer_learning.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_ulmfit.ipynb.\n", "Converted 40_tabular_core.ipynb.\n", "Converted 41_tabular_model.ipynb.\n", "Converted 42_tabular_rapids.ipynb.\n", "Converted 50_data_block_examples.ipynb.\n", "Converted 60_medical_imaging.ipynb.\n", "Converted 65_medical_text.ipynb.\n", "Converted 70_callback_wandb.ipynb.\n", "Converted 71_callback_tensorboard.ipynb.\n", "Converted 90_notebook_core.ipynb.\n", "Converted 91_notebook_export.ipynb.\n", "Converted 92_notebook_showdoc.ipynb.\n", "Converted 93_notebook_export2html.ipynb.\n", "Converted 94_notebook_test.ipynb.\n", "Converted 95_index.ipynb.\n", "Converted 96_data_external.ipynb.\n", "Converted 97_utils_test.ipynb.\n", "Converted notebook2jekyll.ipynb.\n", "Converted xse_resnext.ipynb.\n" ] } ], "source": [ "#hide\n", "from local.notebook.export import notebook2script\n", "notebook2script(all_fs=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" } }, "nbformat": 4, "nbformat_minor": 2 }