We’ve added inference to the library (before if you used learn.predict
you had to manually extract the spectrogram to pass it in, and you had to handle preprocessing yourself).
New functions are:
audio_predict(learn, item)
- takes a learner and an AudioItem and preprocesses it using the same config of your learner including valid/test transformsaudio_predict_all(learn, audiolist)
- takes a learner and an AudioList and returns preds for all items in the AudioList (preprocessed based on the audiolist’s config)
Edit: Sylvain gave us the fix, crossposting solution below here and leaving the original post, export now works
From Sylvain:
That’s because the
ItemList
you’re using doesn’t have areconstruct
method, so it tries to grab the one on the first element of the dataset. You should implement this method (just returnx
if you don’t have any postprocessing) to avoid the issue.
Problem:
Calling audio_predict_all
on a test set with an imported learner causes the following problem (full stack trace at bottom):
372 ds = self.data.single_ds
373 pred = ds.y.analyze_pred(raw_pred, **kwargs)
--> 374 x = ds.x.reconstruct(grab_idx(x, 0))
375 y = ds.y.reconstruct(pred, x) if has_arg(ds.y.reconstruct, 'x') else ds.y.reconstruct(pred)
376 return (x, y, pred, raw_pred) if return_x else (y, pred, raw_pred)
single_ds
calls single_dl
which pulls data from the validation set. (this line is from DataBunch init)
self.single_dl = _create_dl(DataLoader(valid_dl.dataset, batch_size=1, num_workers=0))
But since we have an empty validation set, when it tries to get 1 item from there it gets an IndexError. Any ideas?
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-84-ae0665b3b9f3> in <module>
----> 1 audio_predict_all(new_learn, test)
~/rob/fastai_audio/audio/learner.py in audio_predict_all(learn, al)
17 al = al.split_none().label_empty()
18 data = [AudioList.open(al, ai[0].path).spectro for ai in al.train]
---> 19 preds = [learn.predict(spectro) for spectro in progress_bar(data)]
20 return [o for o in zip(*preds)]
~/rob/fastai_audio/audio/learner.py in <listcomp>(.0)
17 al = al.split_none().label_empty()
18 data = [AudioList.open(al, ai[0].path).spectro for ai in al.train]
---> 19 preds = [learn.predict(spectro) for spectro in progress_bar(data)]
20 return [o for o in zip(*preds)]
/opt/anaconda3/lib/python3.7/site-packages/fastai/basic_train.py in predict(self, item, return_x, batch_first, with_dropout, **kwargs)
372 ds = self.data.single_ds
373 pred = ds.y.analyze_pred(raw_pred, **kwargs)
--> 374 x = ds.x.reconstruct(grab_idx(x, 0))
375 y = ds.y.reconstruct(pred, x) if has_arg(ds.y.reconstruct, 'x') else ds.y.reconstruct(pred)
376 return (x, y, pred, raw_pred) if return_x else (y, pred, raw_pred)
/opt/anaconda3/lib/python3.7/site-packages/fastai/data_block.py in reconstruct(self, t, x)
97 def reconstruct(self, t:Tensor, x:Tensor=None):
98 "Reconstruct one of the underlying item for its data `t`."
---> 99 return self[0].reconstruct(t,x) if has_arg(self[0].reconstruct, 'x') else self[0].reconstruct(t)
100
101 def new(self, items:Iterator, processor:PreProcessors=None, **kwargs)->'ItemList':
/opt/anaconda3/lib/python3.7/site-packages/fastai/data_block.py in __getitem__(self, idxs)
116 "returns a single item based if `idxs` is an integer or a new `ItemList` object if `idxs` is a range."
117 idxs = try_int(idxs)
--> 118 if isinstance(idxs, Integral): return self.get(idxs)
119 else: return self.new(self.items[idxs], inner_df=index_row(self.inner_df, idxs))
120
~/rob/fastai_audio/audio/data.py in get(self, i)
312
313 def get(self, i):
--> 314 item = self.items[i]
315 if isinstance(item, AudioItem): return item
316 if isinstance(item, (str, PosixPath, Path)):
IndexError: index 0 is out of bounds for axis 0 with size 0