-
Notifications
You must be signed in to change notification settings - Fork 3.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add tests for single scalar return from training #2587
Changes from all commits
89d061d
33367e2
7567ec9
899d83f
76c5e95
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
""" | ||
Tests to ensure that the training loop works with a scalar | ||
""" | ||
from pytorch_lightning import Trainer | ||
from tests.base.deterministic_model import DeterministicModel | ||
import torch | ||
|
||
|
||
def test_training_step_scalar(tmpdir): | ||
""" | ||
Tests that only training_step that returns a single scalar can be used | ||
""" | ||
model = DeterministicModel() | ||
model.training_step = model.training_step_scalar_return | ||
model.val_dataloader = None | ||
|
||
trainer = Trainer( | ||
default_root_dir=tmpdir, | ||
fast_dev_run=True, | ||
weights_summary=None, | ||
) | ||
trainer.fit(model) | ||
|
||
# make sure correct steps were called | ||
assert model.training_step_called | ||
assert not model.training_step_end_called | ||
assert not model.training_epoch_end_called | ||
|
||
# make sure training outputs what is expected | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. all these asserts bellow seems to be the same in all three functions... rather wrap into single assert block, otherwise, it takes some time to check what is the difference... |
||
for batch_idx, batch in enumerate(model.train_dataloader()): | ||
break | ||
|
||
out = trainer.run_training_batch(batch, batch_idx) | ||
assert out.signal == 0 | ||
assert len(out.batch_log_metrics) == 0 and isinstance(out.batch_log_metrics, dict) | ||
assert len(out.grad_norm_dic) == 0 and isinstance(out.grad_norm_dic, dict) | ||
|
||
train_step_out = out.training_step_output_for_epoch_end | ||
assert isinstance(train_step_out, torch.Tensor) | ||
assert train_step_out.item() == 171 | ||
|
||
# make sure the optimizer closure returns the correct things | ||
opt_closure_result = trainer.optimizer_closure(batch, batch_idx, 0, trainer.optimizers[0], trainer.hiddens) | ||
assert opt_closure_result['loss'].item() == 171 | ||
|
||
|
||
def training_step_scalar_with_step_end(tmpdir): | ||
""" | ||
Checks train_step with scalar only + training_step_end | ||
""" | ||
model = DeterministicModel() | ||
model.training_step = model.training_step_scalar_return | ||
model.training_step_end = model.training_step_end_scalar | ||
model.val_dataloader = None | ||
|
||
trainer = Trainer(fast_dev_run=True, weights_summary=None) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing |
||
trainer.fit(model) | ||
|
||
# make sure correct steps were called | ||
assert model.training_step_called | ||
assert model.training_step_end_called | ||
assert not model.training_epoch_end_called | ||
|
||
# make sure training outputs what is expected | ||
for batch_idx, batch in enumerate(model.train_dataloader()): | ||
break | ||
|
||
out = trainer.run_training_batch(batch, batch_idx) | ||
assert out.signal == 0 | ||
assert len(out.batch_log_metrics) == 0 and isinstance(out.batch_log_metrics, dict) | ||
assert len(out.grad_norm_dic) == 0 and isinstance(out.grad_norm_dic, dict) | ||
|
||
train_step_out = out.training_step_output_for_epoch_end | ||
assert isinstance(train_step_out, torch.Tensor) | ||
assert train_step_out.item() == 171 | ||
|
||
# make sure the optimizer closure returns the correct things | ||
opt_closure_result = trainer.optimizer_closure(batch, batch_idx, 0, trainer.optimizers[0], trainer.hiddens) | ||
assert opt_closure_result['loss'].item() == 171 | ||
|
||
|
||
def test_full_training_loop_scalar(tmpdir): | ||
""" | ||
Checks train_step + training_step_end + training_epoch_end | ||
(all with scalar return from train_step) | ||
""" | ||
model = DeterministicModel() | ||
model.training_step = model.training_step_scalar_return | ||
model.training_step_end = model.training_step_end_scalar | ||
model.training_epoch_end = model.training_epoch_end_scalar | ||
model.val_dataloader = None | ||
|
||
trainer = Trainer( | ||
default_root_dir=tmpdir, | ||
max_epochs=1, | ||
weights_summary=None, | ||
) | ||
trainer.fit(model) | ||
|
||
# make sure correct steps were called | ||
assert model.training_step_called | ||
assert model.training_step_end_called | ||
assert model.training_epoch_end_called | ||
|
||
# assert epoch end metrics were added | ||
assert 'epoch' in trainer.callback_metrics and len(trainer.callback_metrics) == 1 | ||
assert len(trainer.progress_bar_metrics) == 0 | ||
|
||
# make sure training outputs what is expected | ||
for batch_idx, batch in enumerate(model.train_dataloader()): | ||
break | ||
|
||
out = trainer.run_training_batch(batch, batch_idx) | ||
assert out.signal == 0 | ||
assert len(out.batch_log_metrics) == 0 and isinstance(out.batch_log_metrics, dict) | ||
assert len(out.grad_norm_dic) == 0 and isinstance(out.grad_norm_dic, dict) | ||
|
||
train_step_out = out.training_step_output_for_epoch_end | ||
assert isinstance(train_step_out, torch.Tensor) | ||
assert train_step_out.item() == 171 | ||
|
||
# make sure the optimizer closure returns the correct things | ||
opt_closure_result = trainer.optimizer_closure(batch, batch_idx, 0, trainer.optimizers[0], trainer.hiddens) | ||
assert opt_closure_result['loss'].item() == 171 | ||
|
||
|
||
def test_train_step_epoch_end_scalar(tmpdir): | ||
""" | ||
Checks train_step + training_epoch_end (NO training_step_end) | ||
(with scalar return) | ||
""" | ||
model = DeterministicModel() | ||
model.training_step = model.training_step_scalar_return | ||
model.training_step_end = None | ||
model.training_epoch_end = model.training_epoch_end_scalar | ||
model.val_dataloader = None | ||
|
||
trainer = Trainer(max_epochs=1, weights_summary=None) | ||
trainer.fit(model) | ||
|
||
# make sure correct steps were called | ||
assert model.training_step_called | ||
assert not model.training_step_end_called | ||
assert model.training_epoch_end_called | ||
|
||
# assert epoch end metrics were added | ||
assert 'epoch' in trainer.callback_metrics and len(trainer.callback_metrics) == 1 | ||
assert len(trainer.progress_bar_metrics) == 0 | ||
|
||
# make sure training outputs what is expected | ||
for batch_idx, batch in enumerate(model.train_dataloader()): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why you do not set directly?
|
||
break | ||
|
||
out = trainer.run_training_batch(batch, batch_idx) | ||
assert out.signal == 0 | ||
assert len(out.batch_log_metrics) == 0 and isinstance(out.batch_log_metrics, dict) | ||
assert len(out.grad_norm_dic) == 0 and isinstance(out.grad_norm_dic, dict) | ||
|
||
train_step_out = out.training_step_output_for_epoch_end | ||
assert isinstance(train_step_out, torch.Tensor) | ||
assert train_step_out.item() == 171 | ||
|
||
# make sure the optimizer closure returns the correct things | ||
opt_closure_result = trainer.optimizer_closure(batch, batch_idx, 0, trainer.optimizers[0], trainer.hiddens) | ||
assert opt_closure_result['loss'].item() == 171 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this looks like a test, but why is it in
DeterministicModel
well maybe rather ask why these tests are not part of the template?