Got it. Just wanted to be sure. Thank you!
Hi everyone,
Iām following Camvid Image Segmentation tutorial but on a different binary dataset, which has mask labels that are still in [0; 255] scale. I want to normalize it to [0; 1] so that I can continue the workflow in the tutorial. Is there any way to do it?
I guess you just need to divide the values in the mask by 255.
Yes but I donāt know yet how to insert this step to the workflow of DataBlock
Can you share a link to your dataset? I will try.
I was looking at the differences between the new versions of xresnet and noticed something that seemed a bit odd. The Self-Attention Layer gets placed in the same location for xresnet50 and xresnet101, despite the models varying in length. However, the Self-Attention Layer is placed in different locations in xresnet50, xresnet50_deep and xresnet50_deeper due to sa=sa and i==len(layers)-4
in lines 33-35 in xresnet.py:
blocks = [self._make_layer(ni=block_szs[i], nf=block_szs[i+1], blocks=l,
stride=1 if i==0 else 2, sa=sa and i==len(layers)-4, **kwargs)
for i,l in enumerate(layers)]
For the non-deep versions of xresnet50 & 101 the Self-Attention Layer is placed after the third ResBlock, and if I counted correctly itās placed after the 13th ResBlock in xresnet50_deep. Is that correct?
Hello. What is the easiest way of swapping a standard pytorch dataloader into the DataBunch format? I have tried a couple of ways (documented in issues on Github) but all of them ran into a wall
Hi @muellerzr thank you so much for your help.
I have replicated an element of the DataLoader using MNIST, but I still cannot e.g. show_batch
on neither the DataBunch
nor any of its attributes. I would like to see if the data is loaded correctly.
Can you show your code along with the error?
So I tried a bunch of variants:
import torchvision ast tv
kwargs = {'num_workers': 1, 'pin_memory': True}
train_loader = torch.utils.data.DataLoader(
tv.datasets.MNIST('../data', train=True, download=True, transform=tv.transforms.Compose([
tv.transforms.ToTensor(), tv.transforms.Normalize((0.1307,), (0.3081,))
])),
batch_size=32, shuffle=True, **kwargs)
db_mnist = DataBunch(train_loader).cuda()
Most naively: db_mnist.show_batch()
But I have also tried running it on db_mnist.train_ds
and train_dl
.
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-51-bc9d47422ad9> in <module>
----> 1 db_mnist.show_batch()
~/daisy-gan/venv/lib/python3.6/site-packages/fastcore/foundation.py in __getattr__(self, k)
221 attr = getattr(self,self._default,None)
222 if attr is not None: return getattr(attr, k)
--> 223 raise AttributeError(k)
224 def __dir__(self): return custom_dir(self, self._dir() if self._xtra is None else self._dir())
225 # def __getstate__(self): return self.__dict__
AttributeError: show_batch
I will try running other examples in that part of repo and will report back.
EDIT 2:
When I try to load the data this way:
db_mnist = DataBlock(blocks=(ImageBlock))
db_mnist.databunch(train_loader)
I get the following error:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-61-48884d511190> in <module>
1 db_mnist = DataBlock(blocks=(ImageBlock))
----> 2 db_mnist.databunch(train_loader)
3 dir(db_mnist)
~/daisy-gan/venv/lib/python3.6/site-packages/fastai2/data/block.py in databunch(self, source, path, type_tfms, item_tfms, batch_tfms, **kwargs)
80
81 def databunch(self, source, path='.', type_tfms=None, item_tfms=None, batch_tfms=None, **kwargs):
---> 82 dsrc = self.datasource(source, type_tfms=type_tfms)
83 item_tfms = _merge_tfms(self.default_item_tfms, item_tfms)
84 batch_tfms = _merge_tfms(self.default_batch_tfms, batch_tfms)
~/daisy-gan/venv/lib/python3.6/site-packages/fastai2/data/block.py in datasource(self, source, type_tfms)
77 type_tfms = L([self.default_type_tfms, type_tfms, labellers]).map_zip(
78 lambda tt,tfm,l: L(l) + _merge_tfms(tt, tfm))
---> 79 return DataSource(items, tfms=type_tfms, splits=splits, dl_type=self.dl_type, n_inp=self.n_inp)
80
81 def databunch(self, source, path='.', type_tfms=None, item_tfms=None, batch_tfms=None, **kwargs):
~/daisy-gan/venv/lib/python3.6/site-packages/fastai2/data/core.py in __init__(self, items, tfms, tls, n_inp, dl_type, **kwargs)
233 def __init__(self, items=None, tfms=None, tls=None, n_inp=None, dl_type=None, **kwargs):
234 super().__init__(dl_type=dl_type)
--> 235 self.tls = L(tls if tls else [TfmdList(items, t, **kwargs) for t in L(ifnone(tfms,[None]))])
236 self.n_inp = (1 if len(self.tls)==1 else len(self.tls)-1) if n_inp is None else n_inp
237
~/daisy-gan/venv/lib/python3.6/site-packages/fastai2/data/core.py in <listcomp>(.0)
233 def __init__(self, items=None, tfms=None, tls=None, n_inp=None, dl_type=None, **kwargs):
234 super().__init__(dl_type=dl_type)
--> 235 self.tls = L(tls if tls else [TfmdList(items, t, **kwargs) for t in L(ifnone(tfms,[None]))])
236 self.n_inp = (1 if len(self.tls)==1 else len(self.tls)-1) if n_inp is None else n_inp
237
~/daisy-gan/venv/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
~/daisy-gan/venv/lib/python3.6/site-packages/fastai2/data/core.py in __init__(self, items, tfms, use_list, do_setup, as_item, split_idx, train_setup, splits, types)
169 splits=None, types=None):
170 super().__init__(items, use_list=use_list)
--> 171 self.splits = L([slice(None),[]] if splits is None else splits).map(mask2idxs)
172 if isinstance(tfms,TfmdList): tfms = tfms.tfms
173 if isinstance(tfms,Pipeline): do_setup=False
~/daisy-gan/venv/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):
~/daisy-gan/venv/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())
~/daisy-gan/venv/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
~/daisy-gan/venv/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)
~/daisy-gan/venv/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
~/daisy-gan/venv/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
~/daisy-gan/venv/lib/python3.6/site-packages/fastcore/foundation.py in mask2idxs(mask)
256 if len(mask)==0: return []
257 it = mask[0]
--> 258 if hasattr(it,'item'): it = it.item()
259 if isinstance(it,(bool,NoneType,np.bool_)): return [i for i,m in enumerate(mask) if m]
260 return [int(i) for i in mask]
ValueError: only one element tensors can be converted to Python scalars
Which is an error I got a bunch of times, so I reckon maybe that is an issue.
@sgugger I think I need some advice on what to do here. (back to the heatmap issue). So say I want my image to go through and transform, adjust the TensorPointās accordingly, and then go from there. I currently have my setup to be afterwards (in the PointScaler
) to add a generateMaps
call. However if I try this and grab a batch it doesnāt seem to apply the scaling (and heatmap generation)? What is the behavior supposed to be?
IE something like this:
#export
class HeatmapScaler(Transform):
"Scale a tensor representing points"
order = 1
def __init__(self, do_scale=True, y_first=False):
self.do_scale,self.y_first = do_scale,y_first
self.sig = 1
def _grab_sz(self, x):
self.sz = [x.shape[-1], x.shape[-2]] if isinstance(x, Tensor) else x.size
return x
def _get_sz(self, x):
sz = x.get_meta('img_size')
assert sz is not None or self.sz is not None, "Size could not be inferred, pass it in the init of your TensorPoint with `img_size=...`"
return self.sz if sz is None else sz
def setups(self, dl):
its = dl.do_item(0)
for t in its:
if isinstance(t, TensorPoint): self.c = t.numel()
def encodes(self, x:(PILBase,TensorImageBase)): return self._grab_sz(x)
def decodes(self, x:(PILBase,TensorImageBase)): return self._grab_sz(x)
def encodes(self, x:TensorPoint): return _scale_pnts(x, self._get_sz(x), self.do_scale, self.y_first)
def decodes(self, x:TensorPoint): return _unscale_pnts(x.view(-1, 2), self._get_sz(x))
def encodes(self, x:TensorHeatmap): return generateMaps(x, self.sig, self._get_sz(x))
def decodes(self, x:TensorHeatmap): return generateMaps(x, self.sig, self._get_sz(x))
Would one_batch
not show this change/transform due to it possibly going back as soon as something is visible? And if not, where would I need to go to see this
@leaf The show_batch
method only works with DataBunch
built using the fastai library. We canāt magically know those tensors represent images and categories here. This DataBunch
will work for training, but not the visualization methods.
For the second way, you should simply look at the examples in this notebook, there is one that loads MNIST. In general, a DataBlock
needs more information than that.
@muellerzr
I donāt understand your problem.
So I set it up to where my GuassianBlock
looks like so:
GaussianBlock = TransformBlock(type_tfms=TensorPoint.create, item_tfms=HeatmapScaler)
When I then datablock and bunch it and look at the yās of my batch, I just see the scaled points, not the heatmaps. Did I set up my encodes/decodes correctly above to where it should be generating them upon a call to batch? As it seems to not be doing so (generating the heatmaps)
This also is dynamically generating my y
's (take new points and make a new heatmap each time we transform the image) - which I think may be the issue
Edit: I also tried doing as_item
=False
I donāt see any TensorHeatMap
type so Iām not sure how you expect this particular encodes/decodes function to be called.
Ah, so if I want it to go (off of a TensorPoint
) I should change the encodes/decodes to be x:TensorPoint
so it will call it?
Yes, the encodes/decodes method called is the one corresponding to the type of the object passed.
Thank you! How do I ensure itās grabbing what the new transformed image size is? As if I do something like so (assume GaussianBlock
is now just with type_tfms=TensorPoint.create
, hence why I call HeatmapScaler())
dblock.databunch(path, item_tfms=[Resize(224), HeatmapScaler()]
It doesnāt seem to be using the newly transformed size but instead the original image size. (Iām using self.get_sz
)
I can get around this by passing in a size to HeatmapScaler
but it would be nice to know if there is a way to get this without doing so