{
"cells": [
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#hide\n",
"#skip\n",
"! [ -e /content ] && pip install -Uqq fastai # upgrade fastai on colab"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#default_exp vision.augment\n",
"#default_cls_lvl 3"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Data augmentation in computer vision\n",
"\n",
"> Transforms to apply data augmentation in Computer Vision"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"/home/kai/miniconda/envs/masterthesis_dev/lib/python3.8/site-packages/torch/cuda/__init__.py:52: UserWarning: CUDA initialization: Found no NVIDIA driver on your system. Please check that you have an NVIDIA GPU and installed a driver from http://www.nvidia.com/Download/index.aspx (Triggered internally at /opt/conda/conda-bld/pytorch_1603729009598/work/c10/cuda/CUDAFunctions.cpp:100.)\n",
" return torch._C._cuda_getDeviceCount() > 0\n"
]
}
],
"source": [
"#export\n",
"from fastai.data.all import *\n",
"from fastai.vision.core import *\n",
"from fastai.vision.data 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": [
"# export\n",
"from torch import stack, zeros_like as t0, ones_like as t1\n",
"from torch.distributions.bernoulli import Bernoulli"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"img = PILImage(PILImage.create(TEST_IMAGE).resize((600,400)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## RandTransform-"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"# export\n",
"class RandTransform(DisplayedTransform):\n",
" \"A transform that before_call its state at each `__call__`\"\n",
" do,nm,supports,split_idx = True,None,[],0\n",
" def __init__(self, p=1., nm=None, before_call=None, **kwargs):\n",
" store_attr('p')\n",
" super().__init__(**kwargs)\n",
" self.before_call = ifnone(before_call,self.before_call)\n",
"\n",
" def before_call(self, b, split_idx):\n",
" \"Set `self.do` based on `self.p`\"\n",
" self.do = self.p==1. or random.random() < self.p\n",
"\n",
" def __call__(self, b, split_idx=None, **kwargs):\n",
" self.before_call(b, split_idx=split_idx)\n",
" return super().__call__(b, split_idx=split_idx, **kwargs) if self.do else b"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"As for all `Transform` you can pass encodes
and decodes
at init or subclass and implement them. You can do the same for the `before_call` method that is called at each `__call__`. Note that to have a consistent state for inputs and targets, a `RandTransform` must be applied at the tuple level. \n",
"\n",
"By default the before_call behavior is to execute the transform with probability `p` (if subclassing and wanting to tweak that behavior, the attribute `self.do`, if it exists, is looked for to decide if the transform is executed or not).\n",
"\n",
"> Note: A RandTransform
is only applied to the training set by default, so you have to pass `split_idx=0` if you are calling it directly and not through a Datasets
. That behavior can be changed by setting the attr `split_idx` of the transform to `None`."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [
{
"data": {
"text/markdown": [
"
RandTransform.before_call
[source]RandTransform.before_call
(**`b`**, **`split_idx`**)\n",
"\n",
"Set `self.do` based on `self.p`"
],
"text/plain": [
"