Error on zero length dataloaders (#1280)

* error_on_zero_length

* update CHANGELOG.md

* added test

* Update pytorch_lightning/trainer/data_loading.py

Co-authored-by: Nicki Skafte <nugginea@gmail.com>
Co-authored-by: Jirka Borovec <Borda@users.noreply.github.com>
This commit is contained in:
Nicki Skafte
2020-03-30 18:43:53 -04:00
committed by GitHub
co-authored by Nicki Skafte Jirka Borovec
parent 09167efdb5
commit 2ccc7456ca
5 changed files with 43 additions and 3 deletions
+1
View File
@@ -18,6 +18,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/).
- Added a check that stops the training when loss or weights contain `NaN` or `inf` values. ([#1097](https://github.com/PyTorchLightning/pytorch-lightning/pull/1097))
- Updated references to self.forward() to instead use the `__call__` interface. ([#1211](https://github.com/PyTorchLightning/pytorch-lightning/pull/1211))
- Added support for `IterableDataset` when `val_check_interval=1.0` (default), this will trigger validation at the end of each epoch. ([#1283](https://github.com/PyTorchLightning/pytorch-lightning/pull/1283))
- Added informative errors if user defined dataloader has zero length ([#1280](https://github.com/PyTorchLightning/pytorch-lightning/pull/1280))
### Changed
+5 -1
View File
@@ -26,9 +26,13 @@ else:
def _has_len(dataloader: DataLoader) -> bool:
""" Checks if a given Dataloader has __len__ method implemented i.e. if
it is a finite dataloader or infinite dataloader """
try:
# try getting the length
_ = len(dataloader)
if len(dataloader) == 0:
raise ValueError('Dataloader returned 0 length. Please make sure'
' that your Dataloader atleast returns 1 batch')
return True
except TypeError:
return False
+2 -1
View File
@@ -25,7 +25,8 @@ from tests.base.mixins import (
LightTestOptimizerWithSchedulingMixin,
LightTestMultipleOptimizersWithSchedulingMixin,
LightTestOptimizersWithMixedSchedulingMixin,
LightTestReduceLROnPlateauMixin
LightTestReduceLROnPlateauMixin,
LightZeroLenDataloader
)
+10
View File
@@ -252,6 +252,16 @@ class LightInfTestDataloader:
return CustomInfDataloader(self._dataloader(train=False))
class LightZeroLenDataloader:
""" Simple dataloader that has zero length. """
def train_dataloader(self):
dataloader = self._dataloader(train=True)
dataloader.dataset.data = dataloader.dataset.data[:0]
dataloader.dataset.targets = dataloader.dataset.targets[:0]
return dataloader
class LightEmptyTestStep:
"""Empty test step."""
+25 -1
View File
@@ -16,7 +16,8 @@ from tests.base import (
LightTrainDataloader,
LightInfTrainDataloader,
LightInfValDataloader,
LightInfTestDataloader
LightInfTestDataloader,
LightZeroLenDataloader
)
@@ -458,3 +459,26 @@ def test_inf_test_dataloader(tmpdir):
# verify training completed
assert result == 1
def test_error_on_zero_len_dataloader(tmpdir):
""" Test that error is raised if a zero-length dataloader is defined """
tutils.reset_seed()
class CurrentTestModel(
LightZeroLenDataloader,
LightningTestModel
):
pass
hparams = tutils.get_default_hparams()
model = CurrentTestModel(hparams)
# fit model
with pytest.raises(ValueError):
trainer = Trainer(
default_save_path=tmpdir,
max_epochs=1,
test_percent_check=0.5
)
trainer.fit(model)