I recently started using Fastai library, im trying to create a DataBunch from pytorch DataLoaders, simply like this
data = DataBunch(train_dl=train_dl, valid_dl=val_dl)
where variable train_dl and val_dl is regular pytorch Dataloader object created from my custom pytorch Dataset MyDataset.
I got this error:
AttributeError: 'MyDataset' object has no attribute 'init_kwargs'
based on the doc, this way of creating a DataBunch should be okay. I'm not sure if I'm missing something obvious.
fastai version: '1.0.57'
pytorch version: '1.2.0'
The complete trace back:
AttributeError Traceback (most recent call last)
<ipython-input-25-a5760aecf61f> in <module>
----> 1 data = DataBunch(train_dl=train_dl, valid_dl=val_dl)
~/anaconda3/lib/python3.6/site-packages/fastai/basic_data.py in __init__(self, train_dl, valid_dl, fix_dl, test_dl, device, dl_tfms, path, collate_fn, no_check)
95 return DeviceDataLoader(dl, self.device, self.dl_tfms, collate_fn, **kwargs)
96 self.train_dl,self.valid_dl,self.fix_dl,self.test_dl = map(_create_dl, [train_dl,valid_dl,fix_dl,test_dl])
---> 97 if fix_dl is None: self.fix_dl = self.train_dl.new(shuffle=False, drop_last=False)
98 self.single_dl = _create_dl(DataLoader(valid_dl.dataset, batch_size=1, num_workers=0))
99 self.path = Path(path)
~/anaconda3/lib/python3.6/site-packages/fastai/basic_data.py in new(self, **kwargs)
61 def new(self, **kwargs):
62 "Create a new copy of `self` with `kwargs` replacing current values."
---> 63 new_kwargs = {**self.dl.init_kwargs, **kwargs}
64 return DeviceDataLoader(self.dl.__class__(self.dl.dataset, **new_kwargs), self.device, self.tfms,
65 self.collate_fn)
~/anaconda3/lib/python3.6/site-packages/fastai/basic_data.py in DataLoader___getattr__(dl, k)
18 torch.utils.data.DataLoader.__init__ = intercept_args
19
---> 20 def DataLoader___getattr__(dl, k:str)->Any: return getattr(dl.dataset, k)
21 DataLoader.__getattr__ = DataLoader___getattr__
22
DataBunch init needs to get DeviceDataLoader, not PyTorch DataLoader. If you have datasets, the easiest way to build a DataBunch is to use DataBunch.create(train_ds, valids_ds,...), otherwise you need to wrap your dataloaders in DeviceDataLoader (that will put things on the GPU if needed) to get rid of this bug.
I guess the library could wrap them up automatically for you, will look if it's easy to add on Monday.
I see, I thought it was pytorch dataloader because in the definition of the class DataBunch, the type of train_dl gives direct link to pytorch dataloader page.
thanks for the reply.
I just tried to reproduce your bug and couldn't do it. I made a mistake in my previous comment: the init does take regular PyTorch dataloaders and converts them to DeviceDataLoader.
I suspect you create your dataloaders before importing fastai, which has some monkey-patching on PyTorch to add functionality, and that is why you had the bug. Please let me know if that's not the case and you can give me a minimal reproducer while reopening this issue, and I'll dig into it more.
Most helpful comment
I just tried to reproduce your bug and couldn't do it. I made a mistake in my previous comment: the init does take regular PyTorch dataloaders and converts them to
DeviceDataLoader.I suspect you create your dataloaders before importing fastai, which has some monkey-patching on PyTorch to add functionality, and that is why you had the bug. Please let me know if that's not the case and you can give me a minimal reproducer while reopening this issue, and I'll dig into it more.