From b5e20f40e3e950a4e42b7bd64b9136c5ad8b44ff Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Wed, 9 Nov 2022 18:17:34 -0500 Subject: [PATCH 1/8] style(utils): modify warnings for deprecated keyword args --- neurodiffeq/_version_utils.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/neurodiffeq/_version_utils.py b/neurodiffeq/_version_utils.py index f884d89..d3d4542 100644 --- a/neurodiffeq/_version_utils.py +++ b/neurodiffeq/_version_utils.py @@ -9,6 +9,7 @@ def warn_deprecate_class(new_class): :return: a function that, when called, acts as if it is a class constructor :rtype: callable """ + @functools.wraps(new_class) def old_class_getter(*args, **kwargs): warnings.warn(f"This class name is deprecated, use {new_class} instead", FutureWarning) @@ -26,12 +27,15 @@ def deprecated_alias(**aliases): :return: A decorated function that can receive either `old_name` or `new_name` as input :rtype: function """ + def deco(f): @functools.wraps(f) # preserves signature and docstring def wrapper(*args, **kwargs): _rename_kwargs(f.__name__, kwargs, aliases) return f(*args, **kwargs) + return wrapper + return deco @@ -40,5 +44,5 @@ def _rename_kwargs(func_name, kwargs, aliases): if alias in kwargs: if new in kwargs: raise KeyError(f'{func_name} received both `{alias}` (deprecated) and `{new}` (recommended)') - warnings.warn(f'The argument `{alias}` is deprecated; use `{new}` instead for {func_name}.', FutureWarning) - kwargs[new] = kwargs.pop(alias) \ No newline at end of file + warnings.warn(f'The argument `{alias}` is deprecated for {func_name}; use `{new}` instead.', FutureWarning) + kwargs[new] = kwargs.pop(alias) From eb8edd41a20c993f598018be5f99cad44a7d9ce9 Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Thu, 10 Nov 2022 14:40:21 -0500 Subject: [PATCH 2/8] git(ignore): ignore tensorboard outputs --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 4a5399b..16c0301 100644 --- a/.gitignore +++ b/.gitignore @@ -122,3 +122,6 @@ docs/_build/ _test/ .DS_Store + +# Tensorboard +runs/ From ef2d035cea3120d7a842e4dbd9237a9cf332c2b9 Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Thu, 10 Nov 2022 14:42:26 -0500 Subject: [PATCH 3/8] refactor(solver): rename `criterion` to `loss_fn` and update test cases --- neurodiffeq/ode.py | 2 +- neurodiffeq/pde.py | 2 +- neurodiffeq/pde_spherical.py | 2 +- neurodiffeq/solvers.py | 65 +++++++++++++++++++++--------------- tests/test_solvers.py | 16 ++++++++- 5 files changed, 56 insertions(+), 31 deletions(-) diff --git a/neurodiffeq/ode.py b/neurodiffeq/ode.py index 776287f..b0e6619 100644 --- a/neurodiffeq/ode.py +++ b/neurodiffeq/ode.py @@ -296,7 +296,7 @@ class CustomSolver1D(Solver1D): train_generator=train_generator, valid_generator=valid_generator, optimizer=optimizer, - criterion=criterion, + loss_fn=criterion, n_batches_train=n_batches_train, n_batches_valid=n_batches_valid, metrics=metrics, diff --git a/neurodiffeq/pde.py b/neurodiffeq/pde.py index 102d82a..e676593 100644 --- a/neurodiffeq/pde.py +++ b/neurodiffeq/pde.py @@ -321,7 +321,7 @@ class CustomSolver2D(Solver2D): train_generator=train_generator, valid_generator=valid_generator, optimizer=optimizer, - criterion=criterion, + loss_fn=criterion, n_batches_train=n_batches_train, n_batches_valid=n_batches_valid, metrics=metrics, diff --git a/neurodiffeq/pde_spherical.py b/neurodiffeq/pde_spherical.py index 42018bb..830f919 100644 --- a/neurodiffeq/pde_spherical.py +++ b/neurodiffeq/pde_spherical.py @@ -263,7 +263,7 @@ def enforcer(net, cond, points): valid_generator=valid_generator, analytic_solutions=analytic_solutions, optimizer=optimizer, - criterion=criterion, + loss_fn=criterion, n_batches_train=1, n_batches_valid=1, enforcer=enforcer, diff --git a/neurodiffeq/solvers.py b/neurodiffeq/solvers.py index 30997f7..6055fa5 100644 --- a/neurodiffeq/solvers.py +++ b/neurodiffeq/solvers.py @@ -60,7 +60,7 @@ class BaseSolver(ABC, PretrainedSolver): :param optimizer: The optimizer to be used for training. :type optimizer: `torch.nn.optim.Optimizer`, optional - :param criterion: + :param loss_fn: The loss function used for training. - If a str, must be present in the keys of `neurodiffeq.losses._losses`. @@ -72,7 +72,7 @@ class BaseSolver(ABC, PretrainedSolver): to a tensor of empty shape (i.e. a scalar). The returned tensor must be connected to the computational graph, so that backpropagation can be performed. - :type criterion: + :type loss_fn: str or `torch.nn.moduesl.loss._Loss` or callable :param n_batches_train: Number of batches to train in every epoch, where batch-size equals ``train_generator.size``. @@ -107,9 +107,10 @@ class BaseSolver(ABC, PretrainedSolver): :type shuffle: bool """ + @deprecated_alias(criterion='loss_fn') def __init__(self, diff_eqs, conditions, nets=None, train_generator=None, valid_generator=None, analytic_solutions=None, - optimizer=None, criterion=None, n_batches_train=1, n_batches_valid=4, + optimizer=None, loss_fn=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_input_units=None, n_output_units=None, # deprecated arguments are listed below shuffle=None, batch_size=None): @@ -176,7 +177,7 @@ def analytic_mse(*args): self.metrics_history.update({'valid__' + name: [] for name in self.metrics_fn}) self.optimizer = optimizer if optimizer else Adam(set(chain.from_iterable(n.parameters() for n in self.nets))) - self._set_criterion(criterion) + self._set_loss_fn(loss_fn) def make_pair_dict(train=None, valid=None): return {'train': train, 'valid': valid} @@ -203,15 +204,15 @@ def make_pair_dict(train=None, valid=None): # the _phase variable is registered for callback functions to access self._phase = None - def _set_criterion(self, criterion): + def _set_loss_fn(self, criterion): if criterion is None: - self.criterion = lambda r, f, x: (r ** 2).mean() + self.loss_fn = lambda r, f, x: (r ** 2).mean() elif isinstance(criterion, nn.modules.loss._Loss): - self.criterion = lambda r, f, x: criterion(r, torch.zeros_like(r)) + self.loss_fn = lambda r, f, x: criterion(r, torch.zeros_like(r)) elif isinstance(criterion, str): - self.criterion = _losses[criterion.lower()] + self.loss_fn = _losses[criterion.lower()] elif callable(criterion): - self.criterion = criterion + self.loss_fn = criterion else: raise TypeError(f"Unknown type of criterion {type(criterion)}") @@ -236,6 +237,15 @@ def _batch_examples(self): ) return self._batch + @property + def criterion(self): + warnings.warn( + f'`{self.__class__.__name__}`.criterion is a deprecated alias for `{self.__class__.__name__}.loss_fn`.' + f'The alias is only meant to be accessed by certain functions in `neurodiffeq.solver_utils` ' + f'until proper fixes are made; by which time this alias will be removed.' + ) + return self.loss_fn + def compute_func_val(self, net, cond, *coordinates): r"""Compute the function value evaluated on the points specified by ``coordinates``. @@ -352,7 +362,7 @@ def closure(zero_grad=True): residuals = self.diff_eqs(*funcs, *batch) residuals = torch.cat(residuals, dim=1) try: - loss = self.criterion(residuals, funcs, batch) + self.additional_loss(residuals, funcs, batch) + loss = self.loss_fn(residuals, funcs, batch) + self.additional_loss(residuals, funcs, batch) except TypeError as e: warnings.warn( "You might need to update your code. " @@ -507,7 +517,8 @@ def _get_internal_variables(self): "metrics": self.metrics_fn, "n_batches": self.n_batches, "best_nets": self.best_nets, - "criterion": self.criterion, + "criterion": self.loss_fn, + "loss_fn": self.loss_fn, "conditions": self.conditions, "global_epoch": self.global_epoch, "lowest_loss": self.lowest_loss, @@ -766,7 +777,7 @@ class SolverSpherical(BaseSolver): Optimizer to be used for training. Defaults to a ``torch.optim.Adam`` instance that trains on all parameters of ``nets``. :type optimizer: ``torch.nn.optim.Optimizer``, optional - :param criterion: + :param loss_fn: The loss function used for training. - If a str, must be present in the keys of `neurodiffeq.losses._losses`. @@ -778,7 +789,7 @@ class SolverSpherical(BaseSolver): to a tensor of empty shape (i.e. a scalar). The returned tensor must be connected to the computational graph, so that backpropagation can be performed. - :type criterion: + :type loss_fn: str or `torch.nn.moduesl.loss._Loss` or callable :param n_batches_train: Number of batches to train in every epoch, where batch-size equals ``train_generator.size``. @@ -820,7 +831,7 @@ class SolverSpherical(BaseSolver): def __init__(self, pde_system, conditions, r_min=None, r_max=None, nets=None, train_generator=None, valid_generator=None, analytic_solutions=None, - optimizer=None, criterion=None, n_batches_train=1, n_batches_valid=4, metrics=None, enforcer=None, + optimizer=None, loss_fn=None, n_batches_train=1, n_batches_valid=4, metrics=None, enforcer=None, n_output_units=1, # deprecated arguments are listed below shuffle=None, batch_size=None): @@ -848,7 +859,7 @@ def __init__(self, pde_system, conditions, r_min=None, r_max=None, valid_generator=valid_generator, analytic_solutions=analytic_solutions, optimizer=optimizer, - criterion=criterion, + loss_fn=loss_fn, n_batches_train=n_batches_train, n_batches_valid=n_batches_valid, metrics=metrics, @@ -1025,7 +1036,7 @@ class Solver1D(BaseSolver): Optimizer to be used for training. Defaults to a ``torch.optim.Adam`` instance that trains on all parameters of ``nets``. :type optimizer: ``torch.nn.optim.Optimizer``, optional - :param criterion: + :param loss_fn: The loss function used for training. - If a str, must be present in the keys of `neurodiffeq.losses._losses`. @@ -1037,7 +1048,7 @@ class Solver1D(BaseSolver): to a tensor of empty shape (i.e. a scalar). The returned tensor must be connected to the computational graph, so that backpropagation can be performed. - :type criterion: + :type loss_fn: str or `torch.nn.moduesl.loss._Loss` or callable :param n_batches_train: Number of batches to train in every epoch, where batch-size equals ``train_generator.size``. @@ -1073,7 +1084,7 @@ class Solver1D(BaseSolver): def __init__(self, ode_system, conditions, t_min=None, t_max=None, nets=None, train_generator=None, valid_generator=None, analytic_solutions=None, optimizer=None, - criterion=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_output_units=1, + loss_fn=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_output_units=1, # deprecated arguments are listed below batch_size=None, shuffle=None): @@ -1098,7 +1109,7 @@ def __init__(self, ode_system, conditions, t_min=None, t_max=None, valid_generator=valid_generator, analytic_solutions=analytic_solutions, optimizer=optimizer, - criterion=criterion, + loss_fn=loss_fn, n_batches_train=n_batches_train, n_batches_valid=n_batches_valid, metrics=metrics, @@ -1209,7 +1220,7 @@ class BundleSolver1D(BaseSolver): Optimizer to be used for training. Defaults to a ``torch.optim.Adam`` instance that trains on all parameters of ``nets``. :type optimizer: ``torch.nn.optim.Optimizer``, optional - :param criterion: + :param loss_fn: The loss function used for training. - If a str, must be present in the keys of `neurodiffeq.losses._losses`. @@ -1221,7 +1232,7 @@ class BundleSolver1D(BaseSolver): to a tensor of empty shape (i.e. a scalar). The returned tensor must be connected to the computational graph, so that backpropagation can be performed. - :type criterion: + :type loss_fn: str or `torch.nn.moduesl.loss._Loss` or callable :param n_batches_train: Number of batches to train in every epoch, where batch-size equals ``train_generator.size``. @@ -1258,7 +1269,7 @@ class BundleSolver1D(BaseSolver): def __init__(self, ode_system, conditions, t_min, t_max, theta_min=None, theta_max=None, nets=None, train_generator=None, valid_generator=None, analytic_solutions=None, optimizer=None, - criterion=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_output_units=1, + loss_fn=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_output_units=1, # deprecated arguments are listed below batch_size=None, shuffle=None): @@ -1319,7 +1330,7 @@ def non_var_filter(*variables): valid_generator=valid_generator, analytic_solutions=analytic_solutions, optimizer=optimizer, - criterion=criterion, + loss_fn=loss_fn, n_batches_train=n_batches_train, n_batches_valid=n_batches_valid, metrics=metrics, @@ -1420,7 +1431,7 @@ class Solver2D(BaseSolver): Optimizer to be used for training. Defaults to a ``torch.optim.Adam`` instance that trains on all parameters of ``nets``. :type optimizer: ``torch.nn.optim.Optimizer``, optional - :param criterion: + :param loss_fn: The loss function used for training. - If a str, must be present in the keys of `neurodiffeq.losses._losses`. @@ -1432,7 +1443,7 @@ class Solver2D(BaseSolver): to a tensor of empty shape (i.e. a scalar). The returned tensor must be connected to the computational graph, so that backpropagation can be performed. - :type criterion: + :type loss_fn: str or `torch.nn.moduesl.loss._Loss` or callable :param n_batches_train: Number of batches to train in every epoch, where batch-size equals ``train_generator.size``. @@ -1468,7 +1479,7 @@ class Solver2D(BaseSolver): def __init__(self, pde_system, conditions, xy_min=None, xy_max=None, nets=None, train_generator=None, valid_generator=None, analytic_solutions=None, optimizer=None, - criterion=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_output_units=1, + loss_fn=None, n_batches_train=1, n_batches_valid=4, metrics=None, n_output_units=1, # deprecated arguments are listed below batch_size=None, shuffle=None): @@ -1493,7 +1504,7 @@ def __init__(self, pde_system, conditions, xy_min=None, xy_max=None, valid_generator=valid_generator, analytic_solutions=analytic_solutions, optimizer=optimizer, - criterion=criterion, + loss_fn=loss_fn, n_batches_train=n_batches_train, n_batches_valid=n_batches_valid, metrics=metrics, diff --git a/tests/test_solvers.py b/tests/test_solvers.py index 5f0776e..97b6fb4 100644 --- a/tests/test_solvers.py +++ b/tests/test_solvers.py @@ -46,6 +46,7 @@ def test_legacies(solver, generators): with pytest.warns(FutureWarning): assert solver._batch_examples == solver._batch + # criterion with only two arguments (r, x) are deprecated with pytest.raises(TypeError), pytest.warns(FutureWarning): GenericSolver( diff_eqs=DIFF_EQS, @@ -60,7 +61,7 @@ def test_legacies(solver, generators): class SolverWithLegacyAdditionalLoss(BaseSolver): def additional_loss(self, funcs, key): return 0 - + # overriding additional loss is deprecated with pytest.raises(TypeError), pytest.warns(FutureWarning): SolverWithLegacyAdditionalLoss( diff_eqs=DIFF_EQS, @@ -71,6 +72,7 @@ def additional_loss(self, funcs, key): n_output_units=1, ).fit(1) + # the keyword shuffle is deprecated with pytest.warns(FutureWarning): GenericSolver( diff_eqs=DIFF_EQS, @@ -82,6 +84,18 @@ def additional_loss(self, funcs, key): shuffle=True, ) + # the keyword criterion is deprecated + with pytest.warns(FutureWarning): + GenericSolver( + diff_eqs=DIFF_EQS, + conditions=CONDITIONS, + train_generator=generators['train'], + valid_generator=generators['valid'], + n_input_units=1, + n_output_units=1, + criterion='l2', + ) + def test_missing_generator(generators): with pytest.raises(ValueError): From 1b36d74cff0e416a41a7ddaa19135861bd81960c Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Thu, 10 Nov 2022 14:43:50 -0500 Subject: [PATCH 4/8] refactor(callback): rename callback about `loss_fn`s & update test cases --- neurodiffeq/callbacks.py | 17 ++++++++------- tests/test_callbacks.py | 45 ++++++++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/neurodiffeq/callbacks.py b/neurodiffeq/callbacks.py index f1ee6e6..d1f61d6 100644 --- a/neurodiffeq/callbacks.py +++ b/neurodiffeq/callbacks.py @@ -262,11 +262,11 @@ def __call__(self, solver): ) -class SetCriterion(ActionCallback): +class SetLossFn(ActionCallback): r"""A callback that sets the ``criterion`` (a.k.a. loss function) of the solver. Best used together with a condition callback. - :param criterion: + :param loss_fn: The loss function to be set for the solver. It can be - An instance of ``torch.nn.modules.loss._Loss`` @@ -274,7 +274,7 @@ class SetCriterion(ActionCallback): - A callable object which maps residuals, function values, and input coordinates to a scalar loss; or - A str which is present in ``neurodiffeq.losses._losses.keys()``. - :type criterion: ``torch.nn.modules.loss._Loss`` or callable or str. + :type loss_fn: ``torch.nn.modules.loss._Loss`` or callable or str. :param reset: If True, the criterion will be reset every time the callback is called. Otherwise, the criterion will only be set once. @@ -284,9 +284,10 @@ class SetCriterion(ActionCallback): :type logger: str or ``logging.Logger`` """ - def __init__(self, criterion, reset=False, logger=None): - super(SetCriterion, self).__init__(logger=logger) - self.criterion = criterion + @deprecated_alias(criterion='loss_fn') + def __init__(self, loss_fn, reset=False, logger=None): + super(SetLossFn, self).__init__(logger=logger) + self.loss_fn = loss_fn self.reset = reset self.called = False @@ -294,9 +295,11 @@ def __call__(self, solver): if self.reset or (not self.called): self.called = True # noinspection PyProtectedMember - solver._set_criterion(self.criterion) + solver._set_loss_fn(self.loss_fn) +SetCriterion = warn_deprecate_class(SetLossFn) + class SetOptimizer(ActionCallback): r"""A callback that sets the optimizer of the solver. Best used together with a condition callback. diff --git a/tests/test_callbacks.py b/tests/test_callbacks.py index 9400df2..5b67487 100644 --- a/tests/test_callbacks.py +++ b/tests/test_callbacks.py @@ -18,7 +18,7 @@ from neurodiffeq.callbacks import ClosedIntervalGlobal, ClosedIntervalLocal, Random from neurodiffeq.callbacks import RepeatedMetricDown, RepeatedMetricUp, RepeatedMetricDiverge, RepeatedMetricConverge from neurodiffeq.callbacks import _RepeatedMetricChange -from neurodiffeq.callbacks import SetCriterion, SetOptimizer +from neurodiffeq.callbacks import SetLossFn, SetOptimizer from neurodiffeq.callbacks import EveCallback, StopCallback, ProgressBarCallBack from neurodiffeq.hypersolver import Hypersolver, Euler @@ -38,7 +38,7 @@ def solver(): conditions=[NoCondition()], t_min=0.0, t_max=1.0, - criterion='l2', + loss_fn='l2', ) @@ -349,41 +349,56 @@ def test_tensorboard_callback(solver, tmp_dir): @pytest.mark.parametrize( - argnames='criterion', + argnames='loss_fn', argvalues=['l1', torch.nn.modules.loss.L1Loss(), lambda r, f, x: torch.abs(r).mean()] ) -def test_set_criterion_callback_polymorphism(solver, criterion): +def test_set_loss_fn_callback_polymorphism(solver, loss_fn): coords = torch.rand(10, 1, requires_grad=True) funcs = torch.exp(coords * 1.01) residuals = diff(funcs, coords) - funcs - callback = SetCriterion(criterion=criterion) + callback = SetLossFn(loss_fn=loss_fn) callback(solver) - assert torch.allclose(solver.criterion(residuals, funcs, coords), torch.abs(residuals).mean()) + assert torch.allclose(solver.loss_fn(residuals, funcs, coords), torch.abs(residuals).mean()) -def test_set_criterion_callback_reset(solver): +def test_set_loss_fn_callback_reset(solver): coords = torch.rand(10, 1, requires_grad=True) funcs = torch.exp(coords * 1.01) residuals = diff(funcs, coords) - funcs # w/o resetting - callback = SetCriterion(criterion='l1', reset=False) + callback = SetLossFn(loss_fn='l1', reset=False) callback(solver) - assert torch.allclose(solver.criterion(residuals, funcs, coords), torch.abs(residuals).mean()) + assert torch.allclose(solver.loss_fn(residuals, funcs, coords), torch.abs(residuals).mean()) - solver._set_criterion('l2') + solver._set_loss_fn('l2') callback(solver) - assert torch.allclose(solver.criterion(residuals, funcs, coords), (residuals ** 2).mean()) + assert torch.allclose(solver.loss_fn(residuals, funcs, coords), (residuals ** 2).mean()) # w/ resetting - callback = SetCriterion(criterion='l1', reset=True) + callback = SetLossFn(loss_fn='l1', reset=True) callback(solver) - assert torch.allclose(solver.criterion(residuals, funcs, coords), torch.abs(residuals).mean()) + assert torch.allclose(solver.loss_fn(residuals, funcs, coords), torch.abs(residuals).mean()) - solver._set_criterion('l2') + solver._set_loss_fn('l2') callback(solver) - assert torch.allclose(solver.criterion(residuals, funcs, coords), torch.abs(residuals).mean()) + assert torch.allclose(solver.loss_fn(residuals, funcs, coords), torch.abs(residuals).mean()) + + +def test_set_loss_fn_callback_legacy_names(solver): + from neurodiffeq.callbacks import SetCriterion + + with pytest.warns(FutureWarning): + callback = SetCriterion(loss_fn='l1', reset=False) + assert isinstance(callback, SetLossFn) + + with pytest.warns(FutureWarning): + _ = SetLossFn(criterion='l1', reset=False) + + with pytest.warns(FutureWarning): + callback = SetCriterion(criterion='l1', reset=False) + assert isinstance(callback, SetLossFn) def test_set_optimizer_polymorphism(solver): From f5eb21ad35d31471b18cdee8fe3857a1e74b1d0d Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Thu, 10 Nov 2022 14:46:38 -0500 Subject: [PATCH 5/8] fix(solver): fix an issue where solver_utils cannot update loss_fn --- neurodiffeq/solvers.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/neurodiffeq/solvers.py b/neurodiffeq/solvers.py index 6055fa5..f10bd18 100644 --- a/neurodiffeq/solvers.py +++ b/neurodiffeq/solvers.py @@ -246,6 +246,15 @@ def criterion(self): ) return self.loss_fn + @criterion.setter + def criterion(self, loss_fn): + warnings.warn( + f'`{self.__class__.__name__}`.criterion is a deprecated alias for `{self.__class__.__name__}.loss_fn`.' + f'The alias is only meant to be accessed by certain functions in `neurodiffeq.solver_utils` ' + f'until proper fixes are made; by which time this alias will be removed.' + ) + self.loss_fn = loss_fn + def compute_func_val(self, net, cond, *coordinates): r"""Compute the function value evaluated on the points specified by ``coordinates``. From 2820ae6fcb09d3cfb5d94e57e1e1a6d1556ba540 Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Wed, 16 Nov 2022 15:56:11 -0500 Subject: [PATCH 6/8] docs(generators): fix a typo in generator documentation --- neurodiffeq/generators.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/neurodiffeq/generators.py b/neurodiffeq/generators.py index 9f6e058..c2264cc 100644 --- a/neurodiffeq/generators.py +++ b/neurodiffeq/generators.py @@ -671,10 +671,8 @@ def _internal_vars(self) -> dict: class PredefinedGenerator(BaseGenerator): """A generator for generating points that are fixed and predefined. - :param xs: The x-dimension of the trianing points - :type xs: `torch.Tensor` - :param ys: The y-dimension of the training points - :type ys: `torch.Tensor` + :param xs: training points that will be returned + :type xs: Tuple[`torch.Tensor`] """ def __init__(self, *xs): From 5051f566ae12dd010402849563dcac2e2bad17f4 Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Wed, 7 Dec 2022 18:42:55 -0500 Subject: [PATCH 7/8] fix(solver): fix a compatability issue with torch v1.13 --- neurodiffeq/solvers.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/neurodiffeq/solvers.py b/neurodiffeq/solvers.py index f10bd18..13f03f6 100644 --- a/neurodiffeq/solvers.py +++ b/neurodiffeq/solvers.py @@ -26,7 +26,9 @@ def _requires_closure(optimizer): - return inspect.signature(optimizer.step).parameters.get('closure').default == inspect._empty + # starting from torch v1.13, simple optimizers no longer have a `closure` argument + closure_param = inspect.signature(optimizer.step).parameters.get('closure') + return closure_param and closure_param.default == inspect._empty class BaseSolver(ABC, PretrainedSolver): From 36966e8e855d821e48b24eb6207a3f360c002c2e Mon Sep 17 00:00:00 2001 From: Shuheng Liu Date: Wed, 7 Dec 2022 18:44:07 -0500 Subject: [PATCH 8/8] prepare for release of v0.6.1 --- setup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index a3742b1..535437f 100644 --- a/setup.py +++ b/setup.py @@ -17,14 +17,14 @@ def func(m): setuptools.setup( name="neurodiffeq", - version="0.6.0", + version="0.6.1", author="neurodiffgym", author_email="shuheng_liu@g.harvard.edu", description="A light-weight & flexible library for solving differential equations using neural networks based on PyTorch. ", long_description=long_description, long_description_content_type="text/markdown", url="https://github.com/NeuroDiffGym/neurodiffeq", - download_url="https://github.com/NeuroDiffGym/neurodiffeq/archive/v0.6.0.tar.gz", + download_url="https://github.com/NeuroDiffGym/neurodiffeq/archive/v0.6.1.tar.gz", keywords=[ "neural network", "deep learning",