Conversation
|
I believe the only relevant file from my other PR was the |
|
When we last met, you asked that I update the API of DaskClassifier to look like this:
I am have a few questions:
|
Does
Something like this: def initialize(self, X_train):
self._meta = {..., "num_examples": 0}
def _partial_fit(self, X, y):
self._meta["num_examples"] += len(X)
_epochs = self._meta["num_examples"] / len(X_train)
...
I think the easiest way is: class GeoDamp:
def __init__(self, delay=60, factor=5, initial=128):
self.delay = delay
self.factor = factor
self.initial = initial
def damp(self, meta: Dict[str, Any]) -> int:
# meta is DaskBaseDamper._meta
epochs = meta["epochs"]
return self.initial * (self.factor ** (epochs // self.delay))This will require some parsing of the arguments. |
|
I implemented the new API based on your description but had some questions:
|
stsievert
left a comment
There was a problem hiding this comment.
I'd put the dampers (BaseDamper, Damper, ...) in a new file, _dampers.py.
The current tests should pass. I'd make a new test to ensure that GeoDamp works as expected. I think test_damping.py has some code that will be useful.
| device: str = "cpu", | ||
| grads_per_worker: int=128, | ||
| max_epochs: int=20, | ||
| grads_per_worker=32, |
There was a problem hiding this comment.
| grads_per_worker=32, | |
| grads_per_worker: int = 128, |
adadamp/_dist.py
Outdated
| self.worker_max_batch_size = worker_max_batch_size | ||
| self.min_workers = min_workers | ||
| self.max_workers = max_workers | ||
| self.n_workers_ = min_workers |
There was a problem hiding this comment.
This should be set in initialize.
The Scikit-learn API says that parameters ending in underscores should only be set when fit is called (https://scikit-learn.org/stable/glossary.html#term-attributes)
adadamp/_dist.py
Outdated
| args = (X, y) if y is not None else (X,) | ||
| return TensorDataset(*args) | ||
|
|
||
| def get_batch_size(self, batch_size, kwargs: Dict[str, Any]) -> BaseDamper: |
There was a problem hiding this comment.
| def get_batch_size(self, batch_size, kwargs: Dict[str, Any]) -> BaseDamper: | |
| def _get_damper(self, batch_size, kwargs: Dict[str, Any]) -> BaseDamper: |
adadamp/_dist.py
Outdated
| self.batch_size_ = self.batch_size | ||
|
|
||
| if not isinstance(self.batch_size_, BaseDamper): | ||
| raise ValueError("BatchSize not subclass of BaseDamper") |
There was a problem hiding this comment.
This chunk of code should go in initialize.
adadamp/_dist.py
Outdated
| return self | ||
|
|
||
| def _run_single_epoch(self, X, y=None, **fit_params): | ||
| def run_single_epoch(self, X, y=None, **fit_params): |
There was a problem hiding this comment.
| def run_single_epoch(self, X, y=None, **fit_params): | |
| def _run_single_epoch(self, X, y=None, **fit_params): |
adadamp/__init__.py
Outdated
| ) | ||
| from .dampers import ( | ||
| SimpleBaseDamper, | ||
| SimpleGeoDamp |
There was a problem hiding this comment.
I see – there's already BaseDamper and GeoDamp. It might be okay to remove this from __init__.py. Users can always do from adadamp.dampers import GeoDamp.
adadamp/_dist.py
Outdated
| from torch.utils.data import Dataset, IterableDataset, TensorDataset | ||
| from torch.nn.modules.loss import _Loss as Loss | ||
| from torch.utils.data import Dataset, IterableDataset, TensorDataset, DataLoader | ||
| from adadamp.adadamp.dampers import SimpleBaseDamper, SimpleGeoDamp |
There was a problem hiding this comment.
| from adadamp.adadamp.dampers import SimpleBaseDamper, SimpleGeoDamp | |
| from .dampers import SimpleBaseDamper, SimpleGeoDamp |
There was a problem hiding this comment.
It helps to run pip install -e . in the root of this repo.
There was a problem hiding this comment.
What does this do?
There was a problem hiding this comment.
pip install -e /path/to/adadamp installs the AdaDamp package. It looks like from adadamp.adadamp.dampers import ... is not using the adadamp package; instead, it looks like it's using a relative path.
It might cleaner to do from adadamp.dampers import SimpleBaseDamper, SimpleGeoDamp. That's what from .dampers import is doing (but is relative, not absolute). Here's more detail: https://realpython.com/absolute-vs-relative-python-imports/
adadamp/_dist.py
Outdated
| } | ||
| self._initialized = True | ||
|
|
||
| if isinstance(self.batch_size, str): |
There was a problem hiding this comment.
Suggested change:
+ if not isinstance(self.batch_size, (str, int, np.integer, SimpleBaseDamper)):
+ raise ValueError("self.batch_size needs to be ...")
...
+ elif isinstance(self.batch_size, (int, np.integer)):
...
- if not isinstance(self.batch_size_, SimpleBaseDamper):
- raise ValueError("self.batch_size is not ...")
No description provided.