Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- `ValidSplit` now raises a clear error when it receives an `IterableDataset`, instead of an opaque `TypeError` about a missing length (#594)

## [1.4.0]

### Added
Expand Down
7 changes: 7 additions & 0 deletions skorch/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -311,6 +311,13 @@ def __call__(self, dataset, y=None, groups=None):
if self.stratified and not self._is_stratified(cv):
raise bad_y_error

if isinstance(dataset, torch.utils.data.IterableDataset):
Comment thread
aiedwardyi marked this conversation as resolved.
Outdated
raise ValueError(
"Cannot perform a CV split on an IterableDataset because it has "
"no length. Set train_split=None to disable the internal "
"validation split, or pass a train_split that supports "
"IterableDataset.")

# pylint: disable=invalid-name
len_dataset = get_len(dataset)
if y is not None:
Expand Down
52 changes: 52 additions & 0 deletions skorch/tests/test_net.py
Original file line number Diff line number Diff line change
Expand Up @@ -2159,6 +2159,58 @@ def test_fit_with_dataset_stratified_without_explicit_y_raises(
msg = "Stratified CV requires explicitly passing a suitable y."
assert exc.value.args[0] == msg

@pytest.fixture
def iterable_dataset_cls(self):
class MyIterableDataset(torch.utils.data.IterableDataset):
def __init__(self, X, y):
super().__init__()
self.X = X
self.y = y

def __iter__(self):
return iter(zip(self.X, self.y))

return MyIterableDataset

def test_fit_with_iterable_dataset_and_train_split_raises(
self, net_cls, module_cls, iterable_dataset_cls, data):
from skorch.dataset import ValidSplit

net = net_cls(
module_cls,
max_epochs=1,
train_split=ValidSplit(stratified=False),
)
ds = iterable_dataset_cls(*data)
with pytest.raises(ValueError) as exc:
net.fit(ds, None)

msg = ("Cannot perform a CV split on an IterableDataset because it has "
"no length. Set train_split=None to disable the internal "
"validation split, or pass a train_split that supports "
"IterableDataset.")
assert exc.value.args[0] == msg

def test_fit_with_iterable_dataset_no_train_split(
self, net_cls, module_cls, iterable_dataset_cls, data):
net = net_cls(module_cls, max_epochs=1, train_split=None)
ds = iterable_dataset_cls(*data)
net.fit(ds, None) # does not raise

assert 'train_loss' in net.history[-1]

def test_fit_with_iterable_dataset_and_custom_train_split(
self, net_cls, module_cls, iterable_dataset_cls, data):
# a train_split that never indexes the dataset must keep working
def train_split(dataset, **kwargs):
return dataset, dataset

net = net_cls(module_cls, max_epochs=1, train_split=train_split)
ds = iterable_dataset_cls(*data)
net.fit(ds, None) # does not raise

assert 'valid_loss' in net.history[-1]

@pytest.fixture
def dataset_1_item(self):
class Dataset(torch.utils.data.Dataset):
Expand Down
Loading