A walk with fastai2 - Vision - Study Group and Online Lectures Megathread

let me try this
thanks @muellerzr
downloading and uploading will take forever i guess haha

Hi!

Trying to follow apply 03_Cross_validation in SIIM pneumotorax kaggle dataset for classification (not segmentation). Following the tutorial for medical imaging from fastai2 nbs I generate a dataframe like this:

However I am stucked at the generation of Datasets, I do not know how to add a tranform to get the labels using df. My code so far:

items = get_dicom_files(pneumothorax_source/f"dicom-images-train/")
start_val = len(items) - int(len(items)*.2)
idxs = list(range(start_val, len(items)))
splits = IndexSplitter(idxs)
split = splits(items)
split_list = [split[0], split[1]]
dsrc = Datasets(items, tfms=[[PILDicom.create][???, Categorize]],
                splits = split_list)

Any ideas?

Hi Joan!

Why are you using Datasets instead of DataBlock?

I think if you use DataBlock with Getters get_x and get_y you can read the labels from a df.

2 Likes

Also, Cross Validation can be done in the DataBlock like so:

dblock = DataBlock(blocks=(ImageBlock, CategoryBlock),
                   get_items=get_image_files,
                   get_y=parent_label,
                   splitter=IndexSplitter(val_idx),

(if looking at the CV code)

2 Likes

Hi all,
I was following the excellent notebook from Zachary:

And wanted to give it a try with my own data. Unfortunately, despite matching the format of the bboxes, I think exactly, I run into misalignment issues: I try to replicate the format displayed below:


So the coordinate system seems to be [Upper Left (x,y), Lower Right (x,y) ], but when I put any other data into this format, the show_batch method puts the bounding boxes all over the place. I have tried number of different ways and even wrote my own plotting function, but was unable to get the same results as in the notebook. Any ideas on how this might be fixed?

I am using fastai 0.0.12.

Also when I run learn.show_results() on Zachary’s original notebook, I get the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in to_concat(xs, dim)
    216     #   in this case we return a big list
--> 217     try:    return retain_type(torch.cat(xs, dim=dim), xs[0])
    218     except: return sum([L(retain_type(o_.index_select(dim, tensor(i)).squeeze(dim), xs[0])

TypeError: expected Tensor as element 0 in argument 0, but got int

During handling of the above exception, another exception occurred:

TypeError                                 Traceback (most recent call last)
<ipython-input-38-c3b657dcc9ae> in <module>()
----> 1 learn.show_results()

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in show_results(self, ds_idx, dl, max_n, shuffle, **kwargs)
    224         if dl is None: dl = self.dls[ds_idx].new(shuffle=shuffle)
    225         b = dl.one_batch()
--> 226         _,_,preds = self.get_preds(dl=[b], with_decoded=True)
    227         self.dls.show_results(b, preds, max_n=max_n, **kwargs)
    228 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in get_preds(self, ds_idx, dl, with_input, with_decoded, with_loss, act, inner, **kwargs)
    202             self(event.begin_epoch if inner else _before_epoch)
    203             self._do_epoch_validate(dl=dl)
--> 204             self(event.after_epoch if inner else _after_epoch)
    205             if act is None: act = getattr(self.loss_func, 'activation', noop)
    206             res = cb.all_tensors()

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in __call__(self, event_name)
    106     def ordered_cbs(self, cb_func): return [cb for cb in sort_by_run(self.cbs) if hasattr(cb, cb_func)]
    107 
--> 108     def __call__(self, event_name): L(event_name).map(self._call_one)
    109     def _call_one(self, event_name):
    110         assert hasattr(event, event_name)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in map(self, f, *args, **kwargs)
    360              else f.format if isinstance(f,str)
    361              else f.__getitem__)
--> 362         return self._new(map(g, self))
    363 
    364     def filter(self, f, negate=False, **kwargs):

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in _new(self, items, *args, **kwargs)
    313     @property
    314     def _xtra(self): return None
--> 315     def _new(self, items, *args, **kwargs): return type(self)(items, *args, use_list=None, **kwargs)
    316     def __getitem__(self, idx): return self._get(idx) if is_indexer(idx) else L(self._get(idx), use_list=None)
    317     def copy(self): return self._new(self.items.copy())

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in __call__(cls, x, *args, **kwargs)
     39             return x
     40 
---> 41         res = super().__call__(*((x,) + args), **kwargs)
     42         res._newchk = 0
     43         return res

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in __init__(self, items, use_list, match, *rest)
    304         if items is None: items = []
    305         if (use_list is not None) or not _is_array(items):
--> 306             items = list(items) if use_list else _listify(items)
    307         if match is not None:
    308             if is_coll(match): match = len(match)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in _listify(o)
    240     if isinstance(o, list): return o
    241     if isinstance(o, str) or _is_array(o): return [o]
--> 242     if is_iter(o): return list(o)
    243     return [o]
    244 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in __call__(self, *args, **kwargs)
    206             if isinstance(v,_Arg): kwargs[k] = args.pop(v.i)
    207         fargs = [args[x.i] if isinstance(x, _Arg) else x for x in self.pargs] + args[self.maxi+1:]
--> 208         return self.fn(*fargs, **kwargs)
    209 
    210 # Cell

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in _call_one(self, event_name)
    109     def _call_one(self, event_name):
    110         assert hasattr(event, event_name)
--> 111         [cb(event_name) for cb in sort_by_run(self.cbs)]
    112 
    113     def _bn_bias_state(self, with_bias): return bn_bias_params(self.model, with_bias).map(self.opt.state)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in <listcomp>(.0)
    109     def _call_one(self, event_name):
    110         assert hasattr(event, event_name)
--> 111         [cb(event_name) for cb in sort_by_run(self.cbs)]
    112 
    113     def _bn_bias_state(self, with_bias): return bn_bias_params(self.model, with_bias).map(self.opt.state)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/callback/core.py in __call__(self, event_name)
     21         _run = (event_name not in _inner_loop or (self.run_train and getattr(self, 'training', True)) or
     22                (self.run_valid and not getattr(self, 'training', False)))
---> 23         if self.run and _run: getattr(self, event_name, noop)()
     24         if event_name=='after_fit': self.run=True #Reset self.run to True at each end of fit
     25 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/callback/core.py in after_fit(self)
     93         "Concatenate all recorded tensors"
     94         if self.with_input:     self.inputs  = detuplify(to_concat(self.inputs, dim=self.concat_dim))
---> 95         if not self.save_preds: self.preds   = detuplify(to_concat(self.preds, dim=self.concat_dim))
     96         if not self.save_targs: self.targets = detuplify(to_concat(self.targets, dim=self.concat_dim))
     97         if self.with_loss:      self.losses  = to_concat(self.losses)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in to_concat(xs, dim)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs.keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in <listcomp>(.0)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs.keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in to_concat(xs, dim)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs.keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in <listcomp>(.0)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs.keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in to_concat(xs, dim)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs.keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in <listcomp>(.0)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs.keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in to_concat(xs, dim)
    217     try:    return retain_type(torch.cat(xs, dim=dim), xs[0])
    218     except: return sum([L(retain_type(o_.index_select(dim, tensor(i)).squeeze(dim), xs[0])
--> 219                           for i in range_of(o_)) for o_ in xs], L())
    220 
    221 # Cell

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in <listcomp>(.0)
    217     try:    return retain_type(torch.cat(xs, dim=dim), xs[0])
    218     except: return sum([L(retain_type(o_.index_select(dim, tensor(i)).squeeze(dim), xs[0])
--> 219                           for i in range_of(o_)) for o_ in xs], L())
    220 
    221 # Cell

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/utils.py in range_of(x)
    162 def range_of(x):
    163     "All indices of collection `x` (i.e. `list(range(len(x)))`)"
--> 164     return list(range(len(x)))
    165 
    166 # Cell

TypeError: object of type 'int' has no len()

If you notice I never called show_results. Object detection and all its bugs is still in the works. Earlier in the thread I posted a link to where more people are working on it but show results, predict, etc won’t work OOTB

1 Like

Siamese twins notebook

Hi Zachary according to the siamese twins notebook I would like to ask, how I could use the dataloader?

Would I create a model that takes a tuple of two images as input and returns 0,1 whether they are the same or not?

Sorry for the basic question but I could follow your steps on creating all the stuff but now I feel kind of stuck.

There’s a fuller example here, it happened to come out a few weeks after the lesson:

1 Like

Fair enough.

But I even get an error when trying to predict one of the images:

test_img = plt.imread("/home/ubuntu/.fastai/data/pascal_2007/train/000012.jpg") and learn.predict(test_img) gives:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in _do_epoch_validate(self, ds_idx, dl)
    174             self.dl = dl;                                    self('begin_validate')
--> 175             with torch.no_grad(): self.all_batches()
    176         except CancelValidException:                         self('after_cancel_validate')

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in all_batches(self)
    142         self.n_iter = len(self.dl)
--> 143         for o in enumerate(self.dl): self.one_batch(*o)
    144 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/data/load.py in __iter__(self)
     96         self.before_iter()
---> 97         for b in _loaders[self.fake_l.num_workers==0](self.fake_l):
     98             if self.device is not None: b = to_device(b, self.device)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/utils/data/dataloader.py in __next__(self)
    344     def __next__(self):
--> 345         data = self._next_data()
    346         self._num_yielded += 1

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/utils/data/dataloader.py in _next_data(self)
    855                 del self._task_info[idx]
--> 856                 return self._process_data(data)
    857 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/utils/data/dataloader.py in _process_data(self, data)
    880         if isinstance(data, ExceptionWrapper):
--> 881             data.reraise()
    882         return data

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/_utils.py in reraise(self)
    393             msg = KeyErrorMessage(msg)
--> 394         raise self.exc_type(msg)

TypeError: Caught TypeError in DataLoader worker process 0.
Original Traceback (most recent call last):
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/utils/data/_utils/worker.py", line 178, in _worker_loop
    data = fetcher.fetch(index)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/torch/utils/data/_utils/fetch.py", line 34, in fetch
    data = next(self.dataset_iter)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/data/load.py", line 106, in create_batches
    yield from map(self.do_batch, self.chunkify(res))
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/data/load.py", line 127, in do_batch
    def do_batch(self, b): return self.retain(self.create_batch(self.before_batch(b)), b)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/transform.py", line 185, in __call__
    def __call__(self, o): return compose_tfms(o, tfms=self.fs, split_idx=self.split_idx)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/transform.py", line 138, in compose_tfms
    x = f(x, **kwargs)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/transform.py", line 72, in __call__
    def __call__(self, x, **kwargs): return self._call('encodes', x, **kwargs)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/transform.py", line 82, in _call
    return self._do_call(getattr(self, fn), x, **kwargs)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/transform.py", line 86, in _do_call
    return x if f is None else retain_type(f(x, **kwargs), x, f.returns_none(x))
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/dispatch.py", line 98, in __call__
    return f(*args, **kwargs)
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/vision/data.py", line 33, in bb_pad
    samples = [(s[0], *clip_remove_empty(*s[1:])) for s in samples]
  File "/home/ubuntu/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/vision/data.py", line 33, in <listcomp>
    samples = [(s[0], *clip_remove_empty(*s[1:])) for s in samples]
TypeError: clip_remove_empty() missing 2 required positional arguments: 'bbox' and 'label'


During handling of the above exception, another exception occurred:

IndexError                                Traceback (most recent call last)
<ipython-input-43-2a654fbc7b08> in <module>()
----> 1 learn.predict(test_img)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in predict(self, item, rm_type_tfms, with_input)
    229     def predict(self, item, rm_type_tfms=None, with_input=False):
    230         dl = self.dls.test_dl([item], rm_type_tfms=rm_type_tfms)
--> 231         inp,preds,_,dec_preds = self.get_preds(dl=dl, with_input=True, with_decoded=True)
    232         dec = self.dls.decode_batch((*tuplify(inp),*tuplify(dec_preds)))[0]
    233         i = getattr(self.dls, 'n_inp', -1)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in get_preds(self, ds_idx, dl, with_input, with_decoded, with_loss, act, inner, **kwargs)
    217             for mgr in ctx_mgrs: stack.enter_context(mgr)
    218             self(event.begin_epoch if inner else _before_epoch)
--> 219             self._do_epoch_validate(dl=dl)
    220             self(event.after_epoch if inner else _after_epoch)
    221             if act is None: act = getattr(self.loss_func, 'activation', noop)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in _do_epoch_validate(self, ds_idx, dl)
    176         except CancelValidException:                         self('after_cancel_validate')
    177         finally:
--> 178             dl,*_ = change_attrs(dl, names, old, has);       self('after_validate')
    179 
    180     def fit(self, n_epoch, lr=None, wd=None, cbs=None, reset_opt=False):

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in __call__(self, event_name)
    122     def ordered_cbs(self, cb_func): return [cb for cb in sort_by_run(self.cbs) if hasattr(cb, cb_func)]
    123 
--> 124     def __call__(self, event_name): L(event_name).map(self._call_one)
    125     def _call_one(self, event_name):
    126         assert hasattr(event, event_name)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in map(self, f, *args, **kwargs)
    370              else f.format if isinstance(f,str)
    371              else f.__getitem__)
--> 372         return self._new(map(g, self))
    373 
    374     def filter(self, f, negate=False, **kwargs):

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in _new(self, items, *args, **kwargs)
    321     @property
    322     def _xtra(self): return None
--> 323     def _new(self, items, *args, **kwargs): return type(self)(items, *args, use_list=None, **kwargs)
    324     def __getitem__(self, idx): return self._get(idx) if is_indexer(idx) else L(self._get(idx), use_list=None)
    325     def copy(self): return self._new(self.items.copy())

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in __call__(cls, x, *args, **kwargs)
     39             return x
     40 
---> 41         res = super().__call__(*((x,) + args), **kwargs)
     42         res._newchk = 0
     43         return res

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in __init__(self, items, use_list, match, *rest)
    312         if items is None: items = []
    313         if (use_list is not None) or not _is_array(items):
--> 314             items = list(items) if use_list else _listify(items)
    315         if match is not None:
    316             if is_coll(match): match = len(match)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in _listify(o)
    248     if isinstance(o, list): return o
    249     if isinstance(o, str) or _is_array(o): return [o]
--> 250     if is_iter(o): return list(o)
    251     return [o]
    252 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastcore/foundation.py in __call__(self, *args, **kwargs)
    214             if isinstance(v,_Arg): kwargs[k] = args.pop(v.i)
    215         fargs = [args[x.i] if isinstance(x, _Arg) else x for x in self.pargs] + args[self.maxi+1:]
--> 216         return self.fn(*fargs, **kwargs)
    217 
    218 # Cell

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in _call_one(self, event_name)
    125     def _call_one(self, event_name):
    126         assert hasattr(event, event_name)
--> 127         [cb(event_name) for cb in sort_by_run(self.cbs)]
    128 
    129     def _bn_bias_state(self, with_bias): return bn_bias_params(self.model, with_bias).map(self.opt.state)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/learner.py in <listcomp>(.0)
    125     def _call_one(self, event_name):
    126         assert hasattr(event, event_name)
--> 127         [cb(event_name) for cb in sort_by_run(self.cbs)]
    128 
    129     def _bn_bias_state(self, with_bias): return bn_bias_params(self.model, with_bias).map(self.opt.state)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/callback/core.py in __call__(self, event_name)
     21         _run = (event_name not in _inner_loop or (self.run_train and getattr(self, 'training', True)) or
     22                (self.run_valid and not getattr(self, 'training', False)))
---> 23         if self.run and _run: getattr(self, event_name, noop)()
     24         if event_name=='after_fit': self.run=True #Reset self.run to True at each end of fit
     25 

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/callback/core.py in after_validate(self)
     93         "Concatenate all recorded tensors"
     94         if self.with_input:     self.inputs  = detuplify(to_concat(self.inputs, dim=self.concat_dim))
---> 95         if not self.save_preds: self.preds   = detuplify(to_concat(self.preds, dim=self.concat_dim))
     96         if not self.save_targs: self.targets = detuplify(to_concat(self.targets, dim=self.concat_dim))
     97         if self.with_loss:      self.losses  = to_concat(self.losses)

~/anaconda3/envs/pytorch_p36/lib/python3.6/site-packages/fastai2/torch_core.py in to_concat(xs, dim)
    211 def to_concat(xs, dim=0):
    212     "Concat the element in `xs` (recursively if they are tuples/lists of tensors)"
--> 213     if is_listy(xs[0]): return type(xs[0])([to_concat([x[i] for x in xs], dim=dim) for i in range_of(xs[0])])
    214     if isinstance(xs[0],dict):  return {k: to_concat([x[k] for x in xs], dim=dim) for k in xs[0].keys()}
    215     #We may receives xs that are not concatenatable (inputs of a text classifier for instance),

IndexError: list index out of range

What is the correct procedure here? should I raise an issue somewhere (your repo? fastai2?)? Something else? I am sure I am not the only one struggling with this issue. I’ve been stuck on this for a couple of days, so I doubt I will get much further by myself.

As I said earlier, predict will not work. You can read a few workarounds here: Object detection using fastai v2

2 Likes

Hi @muellerzr and @Saioa,
Thanks for the feedback
Still trying this but I cannot make it work. Using Datablock approach I end up with a dimension issue:

pneumothorax_source = Path('/home/jg/DeepLearning/Datasets/siim/')
items = get_dicom_files(pneumothorax_source/f"dicom-images-train_real/")
df = pd.read_csv(pneumothorax_source/f"train_rle_real.csv")
df['ImageId'] = 'dicom-images-train_real/' + df['ImageId'].astype(str) + ".dcm"

def replace_lambda_getx(x): return pneumothorax_source/x[0]
def replace_lambda_gety(x): return x[1]

pneumothorax = DataBlock(blocks=(ImageBlock(cls=PILDicom), CategoryBlock),
                   get_x=replace_lambda_getx,
                   get_y=replace_lambda_gety, splitter=RandomSplitter(),
                   batch_tfms=aug_transforms(size=224))
dls = pneumothorax.dataloaders(df.values, bs=32)

train_labels = L()
for i in range(len(dls.train_ds)):
    train_labels.append(dls.train_ds[i][1])
for i in range(len(dls.valid_ds)):
    train_labels.append(dls.valid_ds[i][1])

val_pct = []
tst_preds = []
skf = StratifiedKFold(n_splits=10, shuffle=True)
for _, val_idx in skf.split(np.array(items), train_labels):
    splits = IndexSplitter(val_idx)
    split = splits(items)
    split_list = [split[0], split[1]]
    def replace_lambda_getx(x): return pneumothorax_source/x[0]
    def replace_lambda_gety(x): return x[1]
    pneumothorax = DataBlock(blocks=(ImageBlock(cls=PILDicom), CategoryBlock),
                   get_x=replace_lambda_getx,
                   get_y=replace_lambda_gety, splitter=IndexSplitter(val_idx),
                   batch_tfms=aug_transforms(size=224))
    dls = pneumothorax.dataloaders(df.values, bs=32)
    learn = cnn_learner(dls, resnet50, pretrained=False, metrics=accuracy)
    learn.fit_one_cycle(1)
    val_pct.append(learn.validate()[1])
    a,b = learn.get_preds(ds_idx=1)
    tst_preds.append(a)

epoch	train_loss	valid_loss	accuracy	time
0	0.000000	00:01
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-49-3f8dcca8de26> in <module>
     14     dls = pneumothorax.dataloaders(df.values, bs=32)
     15     learn = cnn_learner(dls, resnet50, pretrained=False, metrics=accuracy)
---> 16     learn.fit_one_cycle(1)
     17     val_pct.append(learn.validate()[1])
     18     a,b = learn.get_preds(ds_idx=2)

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/fastai2/callback/schedule.py in fit_one_cycle(self, n_epoch, lr_max, div, div_final, pct_start, wd, moms, cbs, reset_opt)
    110     scheds = {'lr': combined_cos(pct_start, lr_max/div, lr_max, lr_max/div_final),
    111               'mom': combined_cos(pct_start, *(self.moms if moms is None else moms))}
--> 112     self.fit(n_epoch, cbs=ParamScheduler(scheds)+L(cbs), reset_opt=reset_opt, wd=wd)
    113 
    114 # Cell

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/fastai2/learner.py in fit(self, n_epoch, lr, wd, cbs, reset_opt)
    190                     try:
    191                         self.epoch=epoch;          self('begin_epoch')
--> 192                         self._do_epoch_train()
    193                         self._do_epoch_validate()
    194                     except CancelEpochException:   self('after_cancel_epoch')

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/fastai2/learner.py in _do_epoch_train(self)
    163         try:
    164             self.dl = self.dls.train;                        self('begin_train')
--> 165             self.all_batches()
    166         except CancelTrainException:                         self('after_cancel_train')
    167         finally:                                             self('after_train')

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/fastai2/learner.py in all_batches(self)
    141     def all_batches(self):
    142         self.n_iter = len(self.dl)
--> 143         for o in enumerate(self.dl): self.one_batch(*o)
    144 
    145     def one_batch(self, i, b):

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/fastai2/learner.py in one_batch(self, i, b)
    147         try:
    148             self._split(b);                                  self('begin_batch')
--> 149             self.pred = self.model(*self.xb);                self('after_pred')
    150             if len(self.yb) == 0: return
    151             self.loss = self.loss_func(self.pred, *self.yb); self('after_loss')

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    530             result = self._slow_forward(*input, **kwargs)
    531         else:
--> 532             result = self.forward(*input, **kwargs)
    533         for hook in self._forward_hooks.values():
    534             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/container.py in forward(self, input)
     98     def forward(self, input):
     99         for module in self:
--> 100             input = module(input)
    101         return input
    102 

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    530             result = self._slow_forward(*input, **kwargs)
    531         else:
--> 532             result = self.forward(*input, **kwargs)
    533         for hook in self._forward_hooks.values():
    534             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/container.py in forward(self, input)
     98     def forward(self, input):
     99         for module in self:
--> 100             input = module(input)
    101         return input
    102 

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/module.py in __call__(self, *input, **kwargs)
    530             result = self._slow_forward(*input, **kwargs)
    531         else:
--> 532             result = self.forward(*input, **kwargs)
    533         for hook in self._forward_hooks.values():
    534             hook_result = hook(self, input, result)

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/conv.py in forward(self, input)
    343 
    344     def forward(self, input):
--> 345         return self.conv2d_forward(input, self.weight)
    346 
    347 class Conv3d(_ConvNd):

~/anaconda3/envs/fastai2/lib/python3.7/site-packages/torch/nn/modules/conv.py in conv2d_forward(self, input, weight)
    340                             _pair(0), self.dilation, self.groups)
    341         return F.conv2d(input, weight, self.bias, self.stride,
--> 342                         self.padding, self.dilation, self.groups)
    343 
    344     def forward(self, input):

RuntimeError: Given groups=1, weight of size 64 3 7 7, expected input[32, 1, 224, 224] to have 3 channels, but got 1 channels instead

However, if I recreate the dataset to use Datasets it works:

pneumothorax_source = Path('/home/jg/DeepLearning/Datasets/SIIM_reshaped/')
train_imgs = get_dicom_files(pneumothorax_source)

random.shuffle(train_imgs)
start_val = len(train_imgs) - int(len(train_imgs)*.2)
idxs = list(range(start_val, len(train_imgs)))
splits = IndexSplitter(idxs)
split = splits(train_imgs)
split_list = [split[0], split[1]] 
dsrc = Datasets(train_imgs, tfms=[[PILDicom.create], [parent_label, Categorize]],
                splits = split_list) 

batch_tfms = [IntToFloatTensor(), *aug_transforms(size=224), Normalize.from_stats(*imagenet_stats)]
item_tfms = [ToTensor(), RandomResizedCrop(460, min_scale=0.75, ratio=(1.,1.))]
bs=64
dls = dsrc.dataloaders(bs=bs, after_item=item_tfms, after_batch=batch_tfms)

train_labels = L()
for i in range(len(dsrc.train)):
    train_labels.append(dsrc.train[i][1])
for i in range(len(dsrc.valid)):
    train_labels.append(dsrc.valid[i][1])

val_pct = []
skf = StratifiedKFold(n_splits=10, shuffle=True)
for _, val_idx in skf.split(np.array(train_imgs), train_labels):
    splits = IndexSplitter(val_idx)
    split = splits(train_imgs)
    split_list = [split[0], split[1]]
    dsrc = Datasets(train_imgs, tfms=[[PILDicom.create], [parent_label, Categorize]], splits=split_list)
    dls = dsrc.dataloaders(bs=bs, after_item=item_tfms, after_batch=batch_tfms)
    learn = cnn_learner(dls, resnet34, pretrained=False, metrics=accuracy)
    learn.fit_one_cycle(1)
    val_pct.append(learn.validate()[1])

Any idea where is the problem? Thanks!

Hi Joan!

I don’t know much about Cross Validation, but I will try to understand a little more what you are doing.

I think your images only have one channel, while your network is asking for RGB channels. Is that so?

That brings me to the next question: why when you use Datasets do you add transformations (batch_tfms / item_tfms) that when you use DataBlocks you don’t add? Could it be that your images are not normalized in the first case?

2 Likes

@Joan also the two codes aren’t the exact same, you have some item transforms that aren’t being done on the first set that you do in Datasets

1 Like

Uhm… Thanks for the feedback. You nailed it.
I got confused by different things. First DICOM images are RGB.

patient = 4
xray_sample = dcmread(items[patient])
xray_sample.show()

image

But they become grayscale after DataBlock:

And yes, I recall somewhere that Normalize was automatic from vision since last update but I have to admit I didn’t double check it. So, after adding normalize to batch_tfms everything works nicely.
Thanks again.

3 Likes

Awesome! Glad we got it working :slight_smile: Yes if you don’t include normalize say by accident then it’ll automatically be done with cnn_learner or unet_learner (but I’d personally just declare it to double check myself each time)

1 Like

Hi @muellerzr
Has the get_transforms() function been totally removed? That was handy to add a set of default transformations.
Is there any other way to add default transforms?

It seems that in the audio notebook, the out_features of the model isn’t changed to the number of classes of the data.

image

Yes this is now aug_transforms, this should be in a notebook somewhere.

1 Like

Oh okay, and can we use the defaults of aug_tranforms for item_tfms also?
If not where to get the list of item transformation functions?

Aug_transforms is a batch transform to be run efficiently. Any transform that affects only augmentation should be run as a batch transform. Item transforms should only be resizing your image to fit into a batch so your transforms can be run more efficiently. Look at vision.augmentation notebook or docs for more information on augmentation.

1 Like