Files
2026-07-13 13:21:43 +08:00

75 lines
3.2 KiB
Python

"""Callbacks which work with a learner's data
Docs: https://docs.fast.ai/callback.data.html.md"""
# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/14a_callback.data.ipynb.
# %% auto #0
__all__ = ['CollectDataCallback', 'WeightedDL', 'PartialDL']
# %% ../../nbs/14a_callback.data.ipynb #c2788e1e
from ..basics import *
# %% ../../nbs/14a_callback.data.ipynb #b150daae
class CollectDataCallback(Callback):
"Collect all batches, along with `pred` and `loss`, into `self.data`. Mainly for testing"
def before_fit(self): self.data = L()
def after_batch(self):
self.data.append(self.learn.to_detach((self.xb,self.yb,self.pred,self.loss)))
# %% ../../nbs/14a_callback.data.ipynb #a4c10cf9
@delegates()
class WeightedDL(TfmdDL):
"Weighted dataloader where `wgts` is used for the training set only"
def __init__(self, dataset=None, bs=None, wgts=None, **kwargs):
wgts = array([1.]*len(dataset) if wgts is None else wgts)
self.wgts = wgts/wgts.sum()
super().__init__(dataset=dataset, bs=bs, **kwargs)
def get_idxs(self):
if self.n==0: return []
if not self.shuffle: return super().get_idxs()
return list(np.random.choice(self.n, self.n, p=self.wgts))
# %% ../../nbs/14a_callback.data.ipynb #bf8e3b65
@patch
@delegates(Datasets.dataloaders)
def weighted_dataloaders(self:Datasets, wgts, bs=64, **kwargs):
"Create a weighted dataloader `WeightedDL` with `wgts` for the training set"
xtra_kwargs = [{}] * (self.n_subsets-1)
return self.dataloaders(bs=bs, dl_type=WeightedDL, dl_kwargs=({'wgts':wgts}, *xtra_kwargs), **kwargs)
# %% ../../nbs/14a_callback.data.ipynb #40be0e77
@patch
@delegates(Datasets.weighted_dataloaders)
def weighted_dataloaders(self:DataBlock, source, wgts, bs=64, verbose:bool=False, **kwargs):
"Create a weighted dataloader `WeightedDL` with `wgts` for the dataset"
dss = self.datasets(source, verbose=verbose)
if not hasattr(wgts, '__array__'): wgts = np.array(wgts)
trn_wgts = wgts[dss.splits[0]]
return dss.weighted_dataloaders(trn_wgts, bs=bs, after_batch=self.batch_tfms, after_item=self.item_tfms, **kwargs)
# %% ../../nbs/14a_callback.data.ipynb #1d7456fa
@delegates()
class PartialDL(TfmdDL):
"Select randomly partial quantity of data at each epoch"
def __init__(self, dataset=None, bs=None, partial_n=None, **kwargs):
super().__init__(dataset=dataset, bs=bs, **kwargs)
self.partial_n = min(partial_n, self.n) if partial_n else None
def get_idxs(self):
if self.partial_n is None: return super().get_idxs()
return list(np.random.choice(self.n, self.partial_n, replace=False))
def __len__(self):
if self.partial_n is None: return super().__len__()
return self.partial_n//self.bs + (0 if self.drop_last or self.partial_n%self.bs==0 else 1)
# %% ../../nbs/14a_callback.data.ipynb #cad5ed07
@patch
@delegates(Datasets.dataloaders)
def partial_dataloaders(self:FilteredBase, partial_n, bs=64, **kwargs):
"Create a partial dataloader `PartialDL` for the training set"
xtra_kwargs = [{}] * (self.n_subsets-1)
return self.dataloaders(bs=bs, dl_type=PartialDL, dl_kwargs=({'partial_n':partial_n}, *xtra_kwargs), **kwargs)