Source code for torchrecurrent.benchmarks.sequential_cifar10

import torch
from torch.utils.data import DataLoader, TensorDataset


[docs] def sequential_cifar10( images: torch.Tensor, targets: torch.Tensor, permutation: torch.Tensor = None, return_dataloader: bool = True, batch_size: int = 64, shuffle: bool = True, *, normalize: bool = True, dtype: torch.dtype = None, device: torch.device = None, generator: torch.Generator = None, **dataloader_kwargs, ): """Convert CIFAR-10 tensors into the sequential or permuted-CIFAR task. Every 32 by 32 RGB image becomes a sequence of 1024 three-channel pixel inputs in raster-scan order. With a permutation, the same fixed pixel ordering is applied to every image, mirroring the permuted-MNIST protocol of Arjovsky et al. (2016), Section 5.3 (https://proceedings.mlr.press/v48/arjovsky16.html). This function extends that pixel-by-pixel/permuted protocol to CIFAR-10; it is not itself drawn from a specific paper's CIFAR-10 experiment. The caller supplies the CIFAR-10 tensors so this package does not require a dataset-download dependency. Args: images: CIFAR-10 images with shape ``(N, 32, 32, 3)`` or ``(N, 3, 32, 32)``. targets: Class indices with shape ``(N,)``. permutation: Optional permutation of the integers from 0 through 1023. Reuse the same tensor for training and test data. return_dataloader: Return a data loader when true, otherwise tensors. batch_size: Batch size of the returned data loader. shuffle: Whether the returned data loader shuffles samples. normalize: Convert integer pixels from ``[0, 255]`` to ``[0, 1]``. Floating-point inputs are assumed to be normalized already. dtype: Floating-point dtype of the returned inputs. Defaults to the current PyTorch default dtype. device: Device on which to place inputs and targets. generator: Optional generator used by the data loader when shuffling. **dataloader_kwargs: Additional arguments passed to :class:`torch.utils.data.DataLoader`. Returns: A data loader, or ``(sequences, targets)`` when ``return_dataloader=False``. Sequences have shape ``(N, 1024, 3)`` and targets have shape ``(N,)`` with dtype :class:`torch.long`. """ if images.ndim == 4 and images.shape[1] == 3: images = images.permute(0, 2, 3, 1) if images.ndim != 4 or images.shape[1:] != (32, 32, 3): raise ValueError("images must have shape (N, 32, 32, 3) or (N, 3, 32, 32)") if targets.ndim != 1 or targets.shape[0] != images.shape[0]: raise ValueError("targets must have shape (N,) matching images") if dtype is None: dtype = torch.get_default_dtype() if not dtype.is_floating_point: raise TypeError("dtype must be a floating-point dtype") integer_pixels = not images.is_floating_point() sequences = images.reshape(images.shape[0], 1024, 3) sequences = sequences.to(device=device, dtype=dtype) if normalize and integer_pixels: sequences = sequences / 255 if permutation is not None: if permutation.ndim != 1 or permutation.numel() != 1024: raise ValueError("permutation must have shape (1024,)") permutation = permutation.to(device=sequences.device, dtype=torch.long) expected = torch.arange(1024, device=sequences.device) if not torch.equal(torch.sort(permutation).values, expected): raise ValueError("permutation must contain every index from 0 through 1023") sequences = sequences.index_select(1, permutation) targets = targets.to(device=device, dtype=torch.long) if not return_dataloader: return sequences, targets return DataLoader( TensorDataset(sequences, targets), batch_size=batch_size, shuffle=shuffle, generator=generator, **dataloader_kwargs, )