Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autoencoder in fastai

I'm trying to build an autoencoder with fast.ai version 1.0.52 and struggling with how to set labels to be equal to original images. I was following this blog post: https://alanbertl.com/autoencoder-with-fast-ai/

I replaced ImageItemList in the original code with ImageList since it was changed in the latest fastai versions.

%reload_ext autoreload
%autoreload 2
%matplotlib inline

from fastai.imports import *
from fastai.vision import *
from fastai.data_block import *
from fastai.basic_train import *

import pandas as pd

x = np.random.randint(256, size=(1000, 16384))
x = x/255
x = x.reshape(-1,128,128)
x = np.stack([x,x,x],1)
x.shape

class ArraysImageList(ImageList,FloatList):
    def __init__(self, items:Iterator, log:bool=False, **kwargs):
        if isinstance(items, ItemList):
            items = items.items
        super(FloatList,self).__init__(items,**kwargs)

    def get(self,i):
        return Tensor(super(FloatList,self).get(i).astype('float32'))

x_il = ArraysImageList(x)
x_ils = x_il.split_by_rand_pct()
lls = x_ils.label_from_lists(x_ils.train, x_ils.valid)

Here's the error message I get.

---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-33-cbada9e18af9> in <module>
----> 1 lls = x_ils.label_from_lists(x_ils.train, x_ils.valid)

~/.local/lib/python3.6/site-packages/fastai/data_block.py in label_from_lists(self, train_labels, valid_labels, label_cls, **kwargs)
    484         self.valid = self.valid._label_list(x=self.valid, y=self.train.y.new(valid_labels, **kwargs))
    485         self.__class__ = LabelLists
--> 486         self.process()
    487         return self
    488 

~/.local/lib/python3.6/site-packages/fastai/data_block.py in process(self)
    520         "Process the inner datasets."
    521         xp,yp = self.get_processors()
--> 522         for ds,n in zip(self.lists, ['train','valid','test']): ds.process(xp, yp, name=n)
    523         #progress_bar clear the outputs so in some case warnings issued during processing disappear.
    524         for ds in self.lists:

~/.local/lib/python3.6/site-packages/fastai/data_block.py in process(self, xp, yp, name)
    683     def process(self, xp:PreProcessor=None, yp:PreProcessor=None, name:str=None):
    684         "Launch the processing on `self.x` and `self.y` with `xp` and `yp`."
--> 685         self.y.process(yp)
    686         if getattr(self.y, 'filter_missing_y', False):
    687             filt = array([o is None for o in self.y.items])

~/.local/lib/python3.6/site-packages/fastai/data_block.py in process(self, processor)
     73         if processor is not None: self.processor = processor
     74         self.processor = listify(self.processor)
---> 75         for p in self.processor: p.process(self)
     76         return self
     77 

~/.local/lib/python3.6/site-packages/fastai/data_block.py in process(self, ds)
    334 
    335     def process(self, ds):
--> 336         if self.classes is None: self.create_classes(self.generate_classes(ds.items))
    337         ds.classes = self.classes
    338         ds.c2i = self.c2i

~/.local/lib/python3.6/site-packages/fastai/data_block.py in generate_classes(self, items)
    391         for c in items: classes = classes.union(set(c))
    392         classes = list(classes)
--> 393         classes.sort()
    394         return classes
    395 

RuntimeError: bool value of Tensor with more than one value is ambiguous

Ultimately, I want to read images using a dataframe with image paths. So I also tried the following:

import sklearn

cv = sklearn.model_selection.GroupKFold(n_splits=5)
train_inds, valid_inds = next(cv.split(iso_image_df.group, groups=iso_image_df.group))

img_lists = (ImageList.from_df(iso_image_df, resized_img_path, cols=0).split_by_idxs(train_inds, valid_inds))
src = img_lists.label_from_lists(img_lists.train, img_lists.valid)

data = (src.databunch(bs = 32).normalize(imagenet_stats))

data.show_batch(rows=3, figsize=(10, 10))

Here I get the following error message:

---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-146-2514de511e64> in <module>
----> 1 data.show_batch(rows=3, figsize=(10, 10))

~/.local/lib/python3.6/site-packages/fastai/basic_data.py in show_batch(self, rows, ds_type, reverse, **kwargs)
    190         #TODO: get rid of has_arg if possible
    191         if has_arg(self.train_ds.y.reconstruct, 'x'):
--> 192             ys = [self.train_ds.y.reconstruct(grab_idx(y, i), x=x) for i,x in enumerate(xs)]
    193         else : ys = [self.train_ds.y.reconstruct(grab_idx(y, i)) for i in range(n_items)]
    194         self.train_ds.x.show_xys(xs, ys, **kwargs)

~/.local/lib/python3.6/site-packages/fastai/basic_data.py in <listcomp>(.0)
    190         #TODO: get rid of has_arg if possible
    191         if has_arg(self.train_ds.y.reconstruct, 'x'):
--> 192             ys = [self.train_ds.y.reconstruct(grab_idx(y, i), x=x) for i,x in enumerate(xs)]
    193         else : ys = [self.train_ds.y.reconstruct(grab_idx(y, i)) for i in range(n_items)]
    194         self.train_ds.x.show_xys(xs, ys, **kwargs)

~/.local/lib/python3.6/site-packages/fastai/data_block.py in reconstruct(self, t, x)
     89     def reconstruct(self, t:Tensor, x:Tensor=None):
     90         "Reconstruct one of the underlying item for its data `t`."
---> 91         return self[0].reconstruct(t,x) if has_arg(self[0].reconstruct, 'x') else self[0].reconstruct(t)
     92 
     93     def new(self, items:Iterator, processor:PreProcessors=None, **kwargs)->'ItemList':

AttributeError: 'Image' object has no attribute 'reconstruct'

Any help is highly appreciated!

like image 979
Katja Avatar asked Nov 06 '22 17:11

Katja


1 Answers

The lls are being used to create the databunch.

I've looked at it and given the API change in fastai libs I created the databunch without using the lls that were causing the error:

bs = 64
db = (ImageImageList.from_folder(mnist)
        .split_by_folder()          
        .label_from_func(get_y_fn)
        .databunch(bs=bs,num_workers=4))

EDIT: you'll need the get_y_fn; it is very simply defined

def get_y_fn(x): return x

the lls aren't used for anything else anyway

This should fix your problem, let me know if this worked for you.

like image 176
Vlad Ilie Avatar answered Nov 27 '22 18:11

Vlad Ilie