This notebook describes how to perform Scalar regression on images
Installing the library:
!pip install fastai -q --upgrade
from fastai.vision.all import *
url = 'https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/wiki_crop.tar'
!wget {url}
--2020-08-12 12:39:18-- https://data.vision.ee.ethz.ch/cvl/rrothe/imdb-wiki/static/wiki_crop.tar Resolving data.vision.ee.ethz.ch (data.vision.ee.ethz.ch)... 129.132.52.162 Connecting to data.vision.ee.ethz.ch (data.vision.ee.ethz.ch)|129.132.52.162|:443... connected. HTTP request sent, awaiting response... 200 OK Length: 811315200 (774M) [application/x-tar] Saving to: ‘wiki_crop.tar’ wiki_crop.tar 3%[ ] 25.97M 3.52MB/s eta 3m 46s ^C
!tar -xvf 'wiki_crop.tar'
Now the dataset itself is pretty easy, the images are in folders by their age.
def to_num(x:str): return int(x)
block = DataBlock(blocks=(ImageBlock, RegressionBlock()),
get_items=get_image_files,
splitter=RandomSplitter(),
get_y=Pipeline([parent_label, to_num]),
item_tfms=Resize(460, method='squish'),
batch_tfms=[*aug_transforms(size=224, max_warp=0)])
BUT we cannot show a batch of this data
dls = block.dataloaders('')
dls.show_batch()
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-16-90634fcc3c9e> in <module>() ----> 1 dls.show_batch() /usr/local/lib/python3.6/dist-packages/fastai2/data/core.py in show_batch(self, b, max_n, ctxs, show, **kwargs) 90 if b is None: b = self.one_batch() 91 if not show: return self._pre_show_batch(b, max_n=max_n) ---> 92 show_batch(*self._pre_show_batch(b, max_n=max_n), ctxs=ctxs, max_n=max_n, **kwargs) 93 94 def show_results(self, b, out, max_n=9, ctxs=None, show=True, **kwargs): /usr/local/lib/python3.6/dist-packages/fastcore/dispatch.py in __call__(self, *args, **kwargs) 96 if not f: return args[0] 97 if self.inst is not None: f = MethodType(f, self.inst) ---> 98 return f(*args, **kwargs) 99 100 def __get__(self, inst, owner): /usr/local/lib/python3.6/dist-packages/fastai2/vision/data.py in show_batch(x, y, samples, ctxs, max_n, rows, cols, figsize, **kwargs) 132 def show_batch(x:TensorImage, y, samples, ctxs=None, max_n=10, rows=None, cols=None, figsize=None, **kwargs): 133 if ctxs is None: ctxs = get_grid(min(len(samples), max_n), rows=rows, cols=cols, figsize=figsize) --> 134 ctxs = show_batch[object](x, y, samples, ctxs=ctxs, max_n=max_n, **kwargs) 135 return ctxs 136 /usr/local/lib/python3.6/dist-packages/fastai2/data/core.py in show_batch(x, y, samples, ctxs, max_n, **kwargs) 13 if ctxs is None: ctxs = Inf.nones 14 for i in range_of(samples[0]): ---> 15 ctxs = [b.show(ctx=c, **kwargs) for b,c,_ in zip(samples.itemgot(i),ctxs,range(max_n))] 16 return ctxs 17 /usr/local/lib/python3.6/dist-packages/fastai2/data/core.py in <listcomp>(.0) 13 if ctxs is None: ctxs = Inf.nones 14 for i in range_of(samples[0]): ---> 15 ctxs = [b.show(ctx=c, **kwargs) for b,c,_ in zip(samples.itemgot(i),ctxs,range(max_n))] 16 return ctxs 17 AttributeError: 'Tensor' object has no attribute 'show'
Let's rework this into a different transform
class TitledNumberShort(Int, ShowTitle):
_show_args = {'label': 'text'}
def show(self, ctx=None, **kwargs):
"Show self"
return show_title(f'{self:.2f}', ctx=ctx, **merge(self._show_args, kwargs))
class ToIntTensor(Transform):
"Transform to int tensor"
order = 10 #Need to run after PIL transforms on the GPU
_show_args = {'label': 'text'}
def __init__(self, split_idx=None, as_item=True):
super().__init__(split_idx=split_idx,as_item=as_item)
def encodes(self, o): return o.int()
def decodes(self, o): return TitledFloatShort(o)
block = DataBlock(blocks=(ImageBlock, RegressionBlock()),
get_items=get_image_files,
splitter=RandomSplitter(),
get_y=Pipeline([parent_label, to_num, ToFloatTensor]),
item_tfms=Resize(460, method='squish'),
batch_tfms=[Flip(), Rotate(), Zoom(), Warp()])
dls = block.dataloaders('')
dls.show_batch()
dls.c
1
And now we can run this through cnn_learner
learn = cnn_learner(dls, resnet18, loss_func=MSELossFlat(), y_range=(0,100))
learn.fit_one_cycle(1, 1e-2)
epoch | train_loss | valid_loss | time |
---|---|---|---|
0 | 853.149658 | 833.676636 | 06:37 |
imgs = get_image_files('wiki_crop/50')
imgs[0]
Path('wiki_crop/50/13079650_1925-01-08_1952.jpg')
learn.predict(imgs[0])
(47.467430114746094, tensor([47.4674]), tensor([47.4674]))