def on_experiment_start(self, runner: "IRunner") -> None:
        """Collect information about loaders.

        Args:
            runner: current runner

        Raises:
            ValueError: if there are no loaders in epoch
        """
        # store pointers to data loader objects
        for name, loader in runner.loaders.items():
            self.loaders[name] = loader
        # experiment validation loader
        is_loaders_match = all(
            loader in runner.loaders for loader in self.loader_periods.keys()
        )
        is_same_loaders_number = len(self.loader_periods) == len(runner.loaders)
        if is_same_loaders_number and is_loaders_match:
            # find potential epoch with zero loaders
            zero_loaders_epochs = list(
                filter(
                    lambda n: all(
                        (p == 0 or n % p != 0) for p in self.loader_periods.values()
                    ),
                    range(1, runner.num_epochs + 1),
                )
            )
            if len(zero_loaders_epochs) > 0:
                epoch_with_err = zero_loaders_epochs[0]
                raise ValueError(f"There will be no loaders in epoch {epoch_with_err}!")

        if self.loader_periods.get(self.valid_loader_key, 1) < 1:
            raise ValueError(
                f"Period for a validation loader ('{self.valid_loader_key}') "
                "should be > 0!"
            )
Collect information about loaders.

        Args:
            runner: current runner

        Raises:
            ValueError: if there are no loaders in epoch
        
catalyst/callbacks/periodic_loader.py