{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#default_exp core.transform" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "from local.core.imports import *\n", "from local.core.foundation import *\n", "from local.core.utils import *\n", "from local.core.dispatch import *\n", "from local.test import *\n", "from local.notebook.showdoc import show_doc" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from PIL import Image\n", "import torch" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Transforms\n", "\n", "> Definition of `Transform` and `Pipeline`" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The classes here provide functionality for creating a composition of *partially reversible functions*. By \"partially reversible\" we mean that a transform can be `decode`d, creating a form suitable for display. This is not necessarily identical to the original form (e.g. a transform that changes a byte tensor to a float tensor does not recreate a byte tensor when decoded, since that may lose precision, and a float tensor can be displayed already).\n", "\n", "Classes are also provided and for composing transforms, and mapping them over collections. `Pipeline` is a transform which composes several `Transform`, knowing how to decode them or show an encoded item." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Types" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`ArrayImage`, `ArrayImageBW` and `ArrayMask` are subclasses of `ndarray` that know how to show themselves." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ArrayBase(ndarray):\n", " def __new__(cls, x, *args, **kwargs):\n", " if isinstance(x,tuple): super().__new__(cls, x, *args, **kwargs)\n", " if args or kwargs: raise RuntimeError('Unknown array init args')\n", " if not isinstance(x,ndarray): x = array(x)\n", " return x.view(cls)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ArrayImageBase(ArrayBase):\n", " _show_args = {'cmap':'viridis'}\n", " def show(self, ctx=None, **kwargs):\n", " return show_image(self, ctx=ctx, **{**self._show_args, **kwargs})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ArrayImage(ArrayImageBase): pass" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ArrayImageBW(ArrayImage): _show_args = {'cmap':'Greys'}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ArrayMask(ArrayImageBase): _show_args = {'alpha':0.5, 'cmap':'tab20'}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "im = Image.open(TEST_IMAGE)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "im_t = ArrayImage(im)\n", "test_eq(type(im_t), ArrayImage)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "im_t2 = ArrayMask(1)\n", "test_eq(type(im_t2), ArrayMask)\n", "test_eq(im_t2, array(1))" ] }, { "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": [ "ax = im_t.show(figsize=(2,2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_fig_exists(ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Transform -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "_tfm_methods = 'encodes','decodes','setups'\n", "\n", "class _TfmDict(dict):\n", " def __setitem__(self,k,v):\n", " if k not in _tfm_methods or not callable(v): return super().__setitem__(k,v)\n", " if k not in self: super().__setitem__(k,TypeDispatch())\n", " self[k].add(v)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class _TfmMeta(type):\n", " def __new__(cls, name, bases, dict):\n", " res = super().__new__(cls, name, bases, dict)\n", " res.__signature__ = inspect.signature(res.__init__)\n", " return res\n", "\n", " def __call__(cls, *args, **kwargs):\n", " f = args[0] if args else None\n", " n = getattr(f,'__name__',None)\n", " for nm in _tfm_methods:\n", " if not hasattr(cls,nm): setattr(cls, nm, TypeDispatch())\n", " if callable(f) and n in _tfm_methods:\n", " getattr(cls,n).add(f)\n", " return f\n", " return super().__call__(*args, **kwargs)\n", "\n", " @classmethod\n", " def __prepare__(cls, name, bases): return _TfmDict()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class Transform(metaclass=_TfmMeta):\n", " \"Delegates (`__call__`,`decode`,`setup`) to (`encodes`,`decodes`,`setups`) if `split_idx` matches\"\n", " split_idx,init_enc,as_item_force,as_item,order = None,False,None,True,0\n", " def __init__(self, enc=None, dec=None, split_idx=None, as_item=False, order=None):\n", " self.split_idx,self.as_item = ifnone(split_idx, self.split_idx),as_item\n", " if order is not None: self.order=order\n", " self.init_enc = enc or dec\n", " if not self.init_enc: return\n", "\n", " # Passing enc/dec, so need to remove (base) class level enc/dec\n", " del(self.__class__.encodes,self.__class__.decodes,self.__class__.setups)\n", " self.encodes,self.decodes,self.setups = TypeDispatch(),TypeDispatch(),TypeDispatch()\n", " if enc:\n", " self.encodes.add(enc)\n", " self.order = getattr(enc,'order',self.order)\n", " if dec: self.decodes.add(dec)\n", "\n", " @property\n", " def use_as_item(self): return ifnone(self.as_item_force, self.as_item)\n", " def __call__(self, x, **kwargs): return self._call('encodes', x, **kwargs)\n", " def decode (self, x, **kwargs): return self._call('decodes', x, **kwargs)\n", " def setup(self, items=None): return self.setups(items)\n", " def __repr__(self): return f'{self.__class__.__name__}: {self.use_as_item} {self.encodes} {self.decodes}'\n", "\n", " def _call(self, fn, x, split_idx=None, **kwargs):\n", " if split_idx!=self.split_idx and self.split_idx is not None: return x\n", " f = getattr(self, fn)\n", " if self.use_as_item or not is_listy(x): return self._do_call(f, x, **kwargs)\n", " res = tuple(self._do_call(f, x_, **kwargs) for x_ in x)\n", " return retain_type(res, x)\n", "\n", " def _do_call(self, f, x, **kwargs):\n", " return x if f is None else retain_type(f(x, **kwargs), x, f.returns_none(x))\n", "\n", "add_docs(Transform, decode=\"Delegate to `decodes` to undo transform\", setup=\"Delegate to `setups` to set up transform\")" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

class Transform[source]

\n", "\n", "> Transform(**`enc`**=*`None`*, **`dec`**=*`None`*, **`split_idx`**=*`None`*, **`as_item`**=*`False`*)\n", "\n", "Delegates (`__call__`,`decode`,`setup`) to ([`encodes`](/tabular.rapids.html#encodes),`decodes`,[`setups`](/tabular.rapids.html#setups)) if `split_idx` matches" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Transform)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A `Transform` is the main building block of the fastai data pipelines. In the most general terms a transform can be any function you want to apply to your data, however the `Transform` class provides several mechanisms that make the process of building them easy and flexible.\n", "\n", "### The main `Transform` features:\n", "\n", "- **Type dispatch** - Type annotations are used to determine if a transform should be applied to the given argument. It also gives an option to provide several implementations and it choses the one to run based on the type. This is useful for example when running both independent and dependent variables through the pipeline where some transforms only make sense for one and not the other. Another usecase is designing a transform that handles different data formats. Note that if a transform takes multiple arguments only the type of the first one is used for dispatch. \n", "- **Handling of tuples** - When a tuple (or another collection satisfying `is_listy`) of data is passed to a transform it will get applied to each element separately. Most comonly it will be a *(x,y)* tuple, but it can be anything for example a list of images. You can opt out of this behavior by setting the flag `as_item=True`. For transforms that must always operate on the tuple level you can set `as_item_force=True` which takes precedence over `as_item`, an example of that is `PointScaler`.\n", "- **Reversability** - A transform can be made reversible by implementing the `decodes` method. This is mainly used to turn something like a category which is encoded as a number back into a label understandable by humans for showing purposes.\n", "- **Type propagation** - Whenever possible a transform tries to return data of the same type it received. Mainly used to maintain semantics of things like `ArrayImage` which is a thin wrapper of pytorches `Tensor`. You can opt out of this behavior by adding `->None` return type annotation.\n", "- **Preprocessing** - The `setup` method can be used to perform any one-time calculations to be later used by the transform, for example generating a vocabulary to encode categorical data.\n", "- **Filtering based on the dataset type** - By setting the `split_idx` flag you can make the transform be used only in a specific `DataSource` subset like in training, but not validation.\n", "- **Ordering** - You can set the `order` attribute which the `Pipeline` uses when it needs to merge two lists of transforms.\n", "- **Appending new behavior with decorators** - You can easily extend an existing `Transform` by creating `encodes` or `decodes` methods for new data types. You can put those new methods outside the original transform definition and decorate them with the class you wish them patched into. This can be used by the fastai library users to add their own behavior, or multiple modules contributing to the same transform.\n", "\n", "### Defining a `Transform`\n", "There are a few ways to create a transform with different ratios of simplicity to flexibility.\n", "- **Extending the `Transform` class** - Use inheritence to implement the methods you want.\n", "- **Passing methods to the constructor** - Instantiate the `Transform` class and pass your functions as `enc` and `dec` arguments.\n", "- **@Transform decorator** - Turn any function into a `Transform` by just adding a decorator - very straightforward if all you need is a single `encodes` implementation.\n", "- **Passing a function to fastai APIs** - Same as above, but when passing a function to other transform aware classes like `Pipeline` or `TfmdDS` you don't even need a decorator. Your function will get converted to a `Transform` automatically." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform): pass\n", "@A\n", "def encodes(self, x): return x+1\n", "f1 = A()\n", "test_eq(f1(1), 2)\n", "\n", "class B(A): pass\n", "f2 = B()\n", "test_eq(f2(1), 2)\n", "\n", "class A(Transform): pass\n", "f3 = A()\n", "test_eq_type(f3(2), 2)\n", "test_eq_type(f3.decode(2.0), 2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Transform` can be used as a decorator, to turn a function into a `Transform`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f = Transform(lambda o:o//2)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq_type(f(2), 1)\n", "test_eq_type(f.decode(2.0), 2.0)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@Transform\n", "def f(x): return x//2\n", "test_eq_type(f(2), 1)\n", "test_eq_type(f.decode(2.0), 2.0)\n", "\n", "@Transform\n", "def f(x): return x*2\n", "test_eq_type(f(2), 4)\n", "test_eq_type(f.decode(2.0), 2.0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can derive from `Transform` and use `encodes` for your encoding function." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "A: False (ArrayImage,object) -> encodes (ArrayImage,object) -> decodes" ] }, "execution_count": null, "metadata": {}, "output_type": "execute_result" } ], "source": [ "class A(Transform):\n", " def encodes(self, x:ArrayImage): return -x\n", " def decodes(self, x:ArrayImage): return x+1\n", " def setups (self, x:ArrayImage): x.foo = 'a'\n", "f = A()\n", "t = f(im_t)\n", "test_eq(t, -im_t)\n", "test_eq(f(1), 1)\n", "test_eq(type(t), ArrayImage)\n", "test_eq(f.decode(t), -im_t+1)\n", "test_eq(f.decode(1), 1)\n", "f.setup(im_t)\n", "test_eq(im_t.foo, 'a')\n", "t2 = array(1)\n", "f.setup(t2)\n", "assert not hasattr(f2,'foo')\n", "f" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Without return annotation we get an `Int` back since that's what was passed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform): pass\n", "@A\n", "def encodes(self, x:Int): return x//2\n", "@A\n", "def encodes(self, x:float): return x+1\n", "\n", "f = A()\n", "test_eq_type(f(Int(2)), Int(1))\n", "test_eq_type(f(2), 2)\n", "test_eq_type(f(2.), 3.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Without return annotation we don't cast if we're not a subclass of the input type. If the annotation is a tuple, then any type in the tuple will match." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform):\n", " def encodes(self, x:(Int,float)): return x/2\n", " def encodes(self, x:(str,list)): return str(x)+'1'\n", "\n", "f = A()\n", "test_eq_type(f(Int(2)), 1.)\n", "test_eq_type(f(2), 2)\n", "test_eq_type(f(Float(2.)), Float(1.))\n", "test_eq_type(f('a'), 'a1')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "With return annotation `None` we get back whatever Python creates usually." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def func(x)->None: return x/2\n", "f = Transform(func)\n", "test_eq_type(f(2), 1.)\n", "test_eq_type(f(2.), 1.)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Since `decodes` has no return annotation, but `encodes` created an `Int` and we pass that result here to `decode`, we end up with an `Int`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def func(x): return Int(x+1)\n", "def dec (x): return x-1\n", "f = Transform(func,dec)\n", "t = f(1)\n", "test_eq_type(t, Int(2))\n", "test_eq_type(f.decode(t), Int(1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If the transform has `split_idx` then it's only applied if `split_idx` param matches." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f.split_idx = 1\n", "test_eq(f(1, split_idx=1),2)\n", "test_eq_type(f(1, split_idx=0), 1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If `as_item=True` the transform takes tuples as a whole and is applied to them." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform): \n", " def encodes(self, xy): x,y=xy; return (x+y,y)\n", " def decodes(self, xy): x,y=xy; return (x-y,y)\n", "\n", "f = A(as_item=True)\n", "t = f((1,2))\n", "test_eq(t, (3,2))\n", "test_eq(f.decode(t), (1,2))\n", "f.split_idx = 1\n", "test_eq(f((1,2), split_idx=1), (3,2))\n", "test_eq(f((1,2), split_idx=0), (1,2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class AL(Transform): pass\n", "@AL\n", "def encodes(self, x): return L(x_+1 for x_ in x)\n", "@AL\n", "def decodes(self, x): return L(x_-1 for x_ in x)\n", "\n", "f = AL(as_item=True)\n", "t = f([1,2])\n", "test_eq(t, [2,3])\n", "test_eq(f.decode(t), [1,2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If `as_item=False` the transform is applied to each element of a listy input." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def neg_int(x:numbers.Integral): return -x\n", "\n", "f = Transform(neg_int, as_item=False)\n", "test_eq(f([1]), (-1,))\n", "test_eq(f([1.]), (1.,))\n", "test_eq(f([1.,2,3.]), (1.,-2,3.))\n", "test_eq(f.decode([1,2]), (1,2))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class InplaceTransform(Transform):\n", " \"A `Transform` that modifies in-place and just returns whatever it's passed\"\n", " def _call(self, fn, x, split_idx=None, **kwargs):\n", " super()._call(fn,x,split_idx,**kwargs)\n", " return x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(InplaceTransform): pass\n", "@A\n", "def encodes(self, x:pd.Series): x.fillna(10, inplace=True)\n", "f = A()\n", "test_eq_type(f(pd.Series([1,2,None])),pd.Series([1,2,10]))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### TupleTransform" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class TupleTransform(Transform):\n", " \"`Transform` that always treats `as_item` as `False`\"\n", " as_item_force=False" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class ItemTransform (Transform):\n", " \"`Transform` that always treats `as_item` as `True`\"\n", " as_item_force=True" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def float_to_int(x:(float,int)): return Int(x)\n", "\n", "f = TupleTransform(float_to_int)\n", "test_eq_type(f([1.]), (Int(1),))\n", "test_eq_type(f([1]), (Int(1),))\n", "test_eq_type(f(['1']), ('1',))\n", "test_eq_type(f([1,'1']), (Int(1),'1'))\n", "test_eq(f.decode([1]), [1])\n", "\n", "test_eq_type(f(Tuple(1.)), Tuple(Int(1)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class B(TupleTransform): pass\n", "class C(TupleTransform): pass\n", "f = B()\n", "test_eq(f([1]), [1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@B\n", "def encodes(self, x:int): return x+1\n", "@B\n", "def encodes(self, x:str): return x+'1'\n", "@B\n", "def encodes(self, x)->None: return str(x)+'!'\n", "\n", "b,c = B(),C()\n", "test_eq(b([1]), [2])\n", "test_eq(b(['1']), ('11',))\n", "test_eq(b([1.0]), ('1.0!',))\n", "test_eq(c([1]), [1])\n", "test_eq(b([1,2]), (2,3))\n", "test_eq(b.decode([2]), [2])\n", "assert pickle.loads(pickle.dumps(b))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "@B\n", "def decodes(self, x:int): return x-1\n", "test_eq(b.decode([2]), [1])\n", "test_eq(b.decode(('2',)), ('2',))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Non-type-constrained functions are applied to all elements of a tuple." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(TupleTransform): pass\n", "@A\n", "def encodes(self, x): return x+1\n", "@A\n", "def decodes(self, x): return x-1\n", "\n", "f = A()\n", "t = f((1,2.0))\n", "test_eq_type(t, (2,3.0))\n", "test_eq_type(f.decode(t), (1,2.0))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Type-constrained functions are applied to only matching elements of a tuple, and return annotations are only applied where matching." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class B(TupleTransform):\n", " def encodes(self, x:int): return Int(x+1)\n", " def encodes(self, x:str): return x+'1'\n", " def decodes(self, x:Int): return x//2\n", "\n", "f = B()\n", "start = (1.,2,'3')\n", "t = f(start)\n", "test_eq_type(t, (1.,Int(3),'31'))\n", "test_eq(f.decode(t), (1.,Int(1),'31'))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The same behavior also works with `typing` module type classes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform): pass\n", "@A\n", "def encodes(self, x:numbers.Integral): return x+1\n", "@A\n", "def encodes(self, x:float): return x*3\n", "@A\n", "def decodes(self, x:int): return x-1\n", "\n", "f = A()\n", "start = 1.0\n", "t = f(start)\n", "test_eq(t, 3.)\n", "test_eq(f.decode(t), 3)\n", "\n", "f = A(as_item=False)\n", "start = (1.,2,3.)\n", "t = f(start)\n", "test_eq(t, (3.,3,9.))\n", "test_eq(f.decode(t), (3.,2,9.))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Transform accepts lists" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def a(x): return L(x_+1 for x_ in x)\n", "def b(x): return L(x_-1 for x_ in x)\n", "f = TupleTransform(a,b)\n", "\n", "t = f((L(1,2),))\n", "test_eq(t, (L(2,3),))\n", "test_eq(f.decode(t), (L(1,2),))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Func -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def get_func(t, name, *args, **kwargs):\n", " \"Get the `t.name` (potentially partial-ized with `args` and `kwargs`) or `noop` if not defined\"\n", " f = getattr(t, name, noop)\n", " return f if not (args or kwargs) else partial(f, *args, **kwargs)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This works for any kind of `t` supporting `getattr`, so a class or a module." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq(get_func(operator, 'neg', 2)(), -2)\n", "test_eq(get_func(operator.neg, '__call__')(2), -2)\n", "test_eq(get_func(list, 'foobar')([2]), [2])\n", "t = get_func(torch, 'zeros', dtype=torch.int64)(5)\n", "test_eq(t.dtype, torch.int64)\n", "a = [2,1]\n", "get_func(list, 'sort')(a)\n", "test_eq(a, [1,2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Transforms are built with multiple-dispatch: a given function can have several methods depending on the type of the object received. This is done directly with the `TypeDispatch` module and type-annotation in `Transform`, but you can also use the following class." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class Func():\n", " \"Basic wrapper around a `name` with `args` and `kwargs` to call on a given type\"\n", " def __init__(self, name, *args, **kwargs): self.name,self.args,self.kwargs = name,args,kwargs\n", " def __repr__(self): return f'sig: {self.name}({self.args}, {self.kwargs})'\n", " def _get(self, t): return get_func(t, self.name, *self.args, **self.kwargs)\n", " def __call__(self,t): return mapped(self._get, t)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "You can call the `Func` object on any module name or type, even a list of types. It will return the corresponding function (with a default to `noop` if nothing is found) or list of functions." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq(Func('sqrt')(math), math.sqrt)\n", "test_eq(Func('sqrt')(torch), torch.sqrt)\n", "\n", "@patch\n", "def powx(x:math, a): return math.pow(x,a)\n", "@patch\n", "def powx(x:torch, a): return torch.pow(x,a)\n", "tst = Func('powx',a=2)([math, torch])\n", "test_eq([f.func for f in tst], [math.powx, torch.powx])\n", "for t in tst: test_eq(t.keywords, {'a': 2})" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class _Sig():\n", " def __getattr__(self,k):\n", " def _inner(*args, **kwargs): return Func(k, *args, **kwargs)\n", " return _inner\n", "\n", "Sig = _Sig()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Sig[source]

\n", "\n", "> Sig(**\\*`args`**, **\\*\\*`kwargs`**)\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Sig, name=\"Sig\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Sig` is just sugar-syntax to create a `Func` object more easily with the syntax `Sig.name(*args, **kwargs)`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "f = Sig.sqrt()\n", "test_eq(f(math), math.sqrt)\n", "test_eq(f(torch), torch.sqrt)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Pipeline -" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def compose_tfms(x, tfms, is_enc=True, reverse=False, **kwargs):\n", " \"Apply all `func_nm` attribute of `tfms` on `x`, maybe in `reverse` order\"\n", " if reverse: tfms = reversed(tfms)\n", " for f in tfms:\n", " if not is_enc: f = f.decode\n", " x = f(x, **kwargs)\n", " return x" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def to_int (x): return Int(x)\n", "def to_float(x): return Float(x)\n", "def double (x): return x*2\n", "def half(x)->None: return x/2" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def test_compose(a, b, *fs): test_eq_type(compose_tfms(a, tfms=map(Transform,fs)), b)\n", "\n", "test_compose(1, Int(1), to_int)\n", "test_compose(1, Float(1), to_int,to_float)\n", "test_compose(1, Float(2), to_int,to_float,double)\n", "test_compose(2.0, 2.0, to_int,double,half)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform):\n", " def encodes(self, x:float): return Float(x+1)\n", " def decodes(self, x): return x-1\n", " \n", "tfms = [A(), Transform(math.sqrt)]\n", "t = compose_tfms(3., tfms=tfms)\n", "test_eq_type(t, Float(2.))\n", "test_eq(compose_tfms(t, tfms=tfms, is_enc=False), 1.)\n", "test_eq(compose_tfms(4., tfms=tfms, reverse=True), 3.)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "tfms = [A(as_item=False), Transform(math.sqrt, as_item=False)]\n", "test_eq(compose_tfms((9,3.), tfms=tfms), (3,2.))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def mk_transform(f, as_item=True):\n", " \"Convert function `f` to `Transform` if it isn't already one\"\n", " f = instantiate(f)\n", " return f if isinstance(f,Transform) else Transform(f, as_item=as_item)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "def neg(x): return -x\n", "test_eq(type(mk_transform(neg)), Transform)\n", "test_eq(type(mk_transform(math.sqrt)), Transform)\n", "test_eq(type(mk_transform(lambda a:a*2)), Transform)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def gather_attrs(o, k, nm):\n", " \"Used in __getattr__ to collect all attrs `k` from `self.{nm}`\"\n", " if k.startswith('_') or k==nm: raise AttributeError(k)\n", " att = getattr(o,nm)\n", " res = [t for t in att.attrgot(k) if t is not None]\n", " if not res: raise AttributeError(k)\n", " return res[0] if len(res)==1 else L(res)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "def gather_attr_names(o, nm):\n", " \"Used in __dir__ to collect all attrs `k` from `self.{nm}`\"\n", " return L(getattr(o,nm)).map(dir).concat().unique()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#export\n", "class Pipeline:\n", " \"A pipeline of composed (for encode/decode) transforms, setup with types\"\n", " def __init__(self, funcs=None, as_item=False, split_idx=None):\n", " self.split_idx,self.default = split_idx,None\n", " if isinstance(funcs, Pipeline): self.fs = funcs.fs\n", " else:\n", " if isinstance(funcs, Transform): funcs = [funcs]\n", " self.fs = L(ifnone(funcs,[noop])).map(mk_transform).sorted(key='order')\n", " for f in self.fs:\n", " name = camel2snake(type(f).__name__)\n", " a = getattr(self,name,None)\n", " if a is not None: f = L(a)+f\n", " setattr(self, name, f)\n", " self.set_as_item(as_item)\n", "\n", " def set_as_item(self, as_item):\n", " self.as_item = as_item\n", " for f in self.fs: f.as_item = as_item\n", "\n", " def setup(self, items=None):\n", " tfms = self.fs[:]\n", " self.fs.clear()\n", " for t in tfms: self.add(t,items)\n", "\n", " def add(self,t, items=None):\n", " t.setup(items)\n", " self.fs.append(t)\n", "\n", " def __call__(self, o): return compose_tfms(o, tfms=self.fs, split_idx=self.split_idx)\n", " def __repr__(self): return f\"Pipeline: {self.fs}\"\n", " def __getitem__(self,i): return self.fs[i]\n", " def __setstate__(self,data): self.__dict__.update(data)\n", " def __getattr__(self,k): return gather_attrs(self, k, 'fs')\n", " def __dir__(self): return super().__dir__() + gather_attr_names(self, 'fs')\n", "\n", " def decode (self, o, full=True):\n", " if full: return compose_tfms(o, tfms=self.fs, is_enc=False, reverse=True, split_idx=self.split_idx)\n", " #Not full means we decode up to the point the item knows how to show itself.\n", " for f in reversed(self.fs):\n", " if self._is_showable(o): return o\n", " o = f.decode(o, split_idx=self.split_idx)\n", " return o\n", "\n", " def show(self, o, ctx=None, **kwargs):\n", " o = self.decode(o, full=False)\n", " o1 = [o] if self.as_item or not is_listy(o) else o\n", " for o_ in o1:\n", " if hasattr(o_, 'show'): ctx = o_.show(ctx=ctx, **kwargs)\n", " return ctx\n", "\n", " def _is_showable(self, o):\n", " return all(hasattr(o_, 'show') for o_ in o) if is_listy(o) else hasattr(o, 'show')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "add_docs(Pipeline,\n", " __call__=\"Compose `__call__` of all `fs` on `o`\",\n", " decode=\"Compose `decode` of all `fs` on `o`\",\n", " show=\"Show `o`, a single item from a tuple, decoding as needed\",\n", " add=\"Add transform `t`\",\n", " set_as_item=\"Set value of `as_item` for all transforms\",\n", " setup=\"Call each tfm's `setup` in order\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "`Pipeline` is a wrapper for `compose_tfm`. You can pass instances of `Transform` or regular functions in `funcs`, the `Pipeline` will wrap them all in `Transform` (and instantiate them if needed) during the initialization. It handles the transform `setup` by adding them one at a time and calling setup on each, goes through them in order in `__call__` or `decode` and can `show` an object by applying decoding the transforms up until the point it gets an object that knows how to show itself." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Empty pipeline is noop\n", "pipe = Pipeline()\n", "test_eq(pipe(1), 1)\n", "pipe.set_as_item(False)\n", "test_eq(pipe((1,)), (1,))\n", "# Check pickle works\n", "assert pickle.loads(pickle.dumps(pipe))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class IntFloatTfm(Transform):\n", " def encodes(self, x): return Int(x)\n", " def decodes(self, x): return Float(x)\n", " foo=1\n", "\n", "int_tfm=IntFloatTfm()\n", "\n", "def neg(x): return -x\n", "neg_tfm = Transform(neg, neg)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pipe = Pipeline([neg_tfm, int_tfm])\n", "\n", "start = 2.0\n", "t = pipe(start)\n", "test_eq_type(t, Int(-2))\n", "test_eq_type(pipe.decode(t), Float(start))\n", "test_stdout(lambda:pipe.show(t), '-2')\n", "\n", "pipe.set_as_item(False)\n", "test_stdout(lambda:pipe.show(pipe((1.,2.))), '-1\\n-2')\n", "test_eq(pipe.foo, 1)\n", "assert 'foo' in dir(pipe)\n", "assert 'int_float_tfm' in dir(pipe)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Transforms are available as attributes named with the snake_case version of the names of their types. Attributes in transforms can be directly accessed as attributes of the pipeline." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_eq(pipe.int_float_tfm, int_tfm)\n", "test_eq(pipe.foo, 1)\n", "\n", "pipe = Pipeline([int_tfm, int_tfm])\n", "pipe.int_float_tfm\n", "test_eq(pipe.int_float_tfm[0], int_tfm)\n", "test_eq(pipe.foo, [1,1])" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Check opposite order\n", "pipe = Pipeline([int_tfm,neg_tfm])\n", "t = pipe(start)\n", "test_eq(t, -2)\n", "test_stdout(lambda:pipe.show(t), '-2')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class A(Transform):\n", " def encodes(self, x): return int(x)\n", " def decodes(self, x): return Float(x)\n", " \n", "pipe = Pipeline([neg_tfm, A])\n", "t = pipe(start)\n", "test_eq_type(t, -2)\n", "test_eq_type(pipe.decode(t), Float(start))\n", "test_stdout(lambda:pipe.show(t), '-2.0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "s2 = (1,2)\n", "pipe.set_as_item(False)\n", "t = pipe(s2)\n", "test_eq_type(t, (-1,-2))\n", "test_eq_type(pipe.decode(t), (Float(1.),Float(2.)))\n", "test_stdout(lambda:pipe.show(t), '-1.0\\n-2.0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "class B(Transform):\n", " def encodes(self, x): return x+1\n", " def decodes(self, x): return x-1" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from PIL import Image\n", "\n", "def f1(x:ArrayImage): return -x\n", "def f2(x): return Image.open(x).resize((128,128))\n", "def f3(x:Image.Image): return(ArrayImage(array(x)))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pipe = Pipeline([f2,f3,f1])\n", "t = pipe(TEST_IMAGE)\n", "test_eq(type(t), ArrayImage)\n", "test_eq(t, -array(f3(f2(TEST_IMAGE))))" ] }, { "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": [ "pipe = Pipeline([f2,f3])\n", "t = pipe(TEST_IMAGE)\n", "ax = pipe.show(t)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "test_fig_exists(ax)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#Check filtering is properly applied\n", "add1 = B()\n", "add1.split_idx = 1\n", "pipe = Pipeline([neg_tfm, A(), add1])\n", "test_eq(pipe(start), -2)\n", "pipe.split_idx=1\n", "test_eq(pipe(start), -1)\n", "pipe.split_idx=0\n", "test_eq(pipe(start), -2)\n", "for t in [None, 0, 1]:\n", " pipe.split_idx=t\n", " test_eq(pipe.decode(pipe(start)), start)\n", " test_stdout(lambda: pipe.show(pipe(start)), \"-2.0\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Methods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#TODO: method examples" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Pipeline.__call__[source]

\n", "\n", "> Pipeline.__call__(**`o`**)\n", "\n", "Compose `__call__` of all `fs` on `o`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Pipeline.__call__)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Pipeline.decode[source]

\n", "\n", "> Pipeline.decode(**`o`**, **`full`**=*`True`*)\n", "\n", "Compose `decode` of all `fs` on `o`" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Pipeline.decode)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [ { "data": { "text/markdown": [ "

Pipeline.setup[source]

\n", "\n", "> Pipeline.setup(**`items`**=*`None`*)\n", "\n", "Call each tfm's `setup` in order" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "show_doc(Pipeline.setup)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "During the setup, the `Pipeline` starts with no transform and adds them one at a time, so that during its setup, each transform gets the items processed up to its point and not after." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "#hide\n", "#Test is with TfmdList" ] }, { "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" ] } ], "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 }