fix(solver): redo previous changes
1. let local epoch start from 1
2. deprecated `monitor` argument in solver.fit()
@@ -308,6 +308,7 @@ class BaseSolver(ABC):
loss.backward()
batch_loss = loss.item()
return loss
+
if key == 'train':
self._do_optimizer_step(closure=closure)
epoch_loss += batch_loss
@@ -342,7 +343,7 @@ class BaseSolver(ABC):
self.lowest_loss = current_loss
self.best_nets = deepcopy(self.nets)
- def fit(self, max_epochs, callbacks=None, monitor=None):
+ def fit(self, max_epochs, callbacks=(), **kwargs):
r"""Run multiple epochs of training and validation, update best loss at the end of each epoch.
If ``callbacks`` is passed, callbacks are run, one at a time,
@@ -350,10 +351,6 @@ class BaseSolver(ABC):
:param max_epochs: Number of epochs to run.
:type max_epochs: int
- :param monitor:
- **[DEPRECATED]** use a MonitorCallback instance instead.
- The monitor for visualizing solution and metrics.
- :rtype monitor: `neurodiffeq.pde_spherical.MonitorSpherical`
:param callbacks:
A list of callback functions.
Each function should accept the ``solver`` instance itself as its **only** argument.
@@ -366,26 +363,32 @@ class BaseSolver(ABC):
self._stop_training = False
self._max_local_epoch = max_epochs
+ monitor = kwargs.pop('monitor', None)
if monitor:
- warnings.warn("Passing `monitor` is deprecated, "
+ warnings.warn("Passing `monitor` is deprecated and ignored, "
"use a MonitorCallback and pass a list of callbacks instead")
+ if not getattr(monitor, 'check_every', None):
+ raise AttributeError(f'{monitor} doesn\'t have a `check_every` attribute')
+ if monitor.check_every is None:
+ monitor.check_every = 100 # legacy default `check_every` for monitors
+ if kwargs:
+ raise ValueError(f'Unknown keyword argument(s): {list(kwargs.keys())}')
for local_epoch in range(max_epochs):
- # stops training if self._stop_training is set to True by a callback
+ # stop training if self._stop_training is set to True by a callback
if self._stop_training:
break
- # register local epoch so it can be accessed by callbacks
- self.local_epoch = local_epoch
+ # register local epoch (starting from 1 instead of 0) so it can be accessed by callbacks
+ self.local_epoch = local_epoch + 1
self.run_train_epoch()
self.run_valid_epoch()
- if callbacks:
for cb in callbacks:
cb(self)
if monitor:
- if (local_epoch + 1) % monitor.check_every == 0 or local_epoch == max_epochs - 1:
+ if self.local_epoch % monitor.check_every == 0 or self.local_epoch == max_epochs:
monitor.check(
self.nets,
self.conditions,
@@ -416,13 +419,13 @@ class BaseSolver(ABC):
you should pass the coordinates vector(s) to the returned solution.
:rtype: BaseSolution
"""
- pass
+ pass # pragma: no cover
def _get_internal_variables(self):
r"""Get a dict of all available internal variables.
:return:
- All available interal parameters,
+ All available internal variables,
where keys are variable names and values are the corresponding variables.
:rtype: dict
@@ -520,7 +523,7 @@ class BaseSolution(ABC):
@abstractmethod
def _compute_u(self, net, condition, *coords):
- pass
+ pass # pragma: no cover
@deprecated_alias(as_type='to_numpy')
def __call__(self, *coords, to_numpy=False):
@@ -1104,4 +1107,3 @@ class Solver2D(BaseSolver):
'xy_max': self.xy_max,
})
return available_variables
-
