4
0
mirror of https://github.com/nerfstudio-project/nerfstudio.git synced 2026-11-11 18:44:21 +08:00

GenericDataContainer and AbstractDataloaderV2

This commit is contained in:
Jake Austin 2022-07-17 18:29:25 -07:00
parent 971f503a9c
commit 1ef976d177
2 changed files with 114 additions and 1 deletions

View File

@ -16,6 +16,7 @@
Data loader.
"""
from abc import abstractmethod
import random
from typing import Dict, List, Tuple, Union
from omegaconf import ListConfig
@ -27,7 +28,7 @@ from pyrad.cameras.rays import RayBundle
from pyrad.data.image_dataset import ImageDataset
from pyrad.data.image_sampler import ImageSampler
from pyrad.data.pixel_sampler import PixelSampler
from pyrad.data.structs import DatasetInputs
from pyrad.data.structs import DatasetInputs, GenericDataContainer
from pyrad.data.utils import get_dataset_inputs_from_dataset_config
from pyrad.utils import profiler
from pyrad.utils.config import DataConfig
@ -81,6 +82,101 @@ def setup_dataset_eval(config: DataConfig, test_mode: bool, device: str) -> Tupl
return dataset_inputs_eval, dataloader_eval
class AbstractDataloaderV2(nn.Module):
"""Second version of the dataloader class
This version of the dataloader is designed to subsume both the train and eval dataloaders, especially since
this may contain learnable parameters which need to be shared across the train and test dataloaders. The idea
is that we have setup methods for train and eval separatley and this can be a combined train/eval if you want.
Train Methods:
setup_train: sets up for being used as train
iter_train: returns an iterator of the train dataloader
next_train: will be called on __next__() for the training iterator
Eval Methods:
setup_eval: sets up for being used as eval
iter_eval: returns an iterator of the eval dataloader
next_eval: will be called on __next__() for the eval iterator
Attributes:
image_sampler (ImageSampler): image sampler
pixel_sampler (PixelSampler): pixel sampler
intrinsics (TensorType): intrinsics
camera_to_world (TensorType): camera to world
ray_generator (RayBundle): ray generator
train_count (int): number of times train has been called
eval_count (int): number of times eval has been called
"""
def __init__(
self, image_sampler: ImageSampler, pixel_sampler: PixelSampler, intrinsics, camera_to_world, ray_generator
):
super().__init__()
self.image_sampler = image_sampler
self.pixel_sampler = pixel_sampler
self.iter_image_sampler = iter(self.image_sampler)
self.intrinsics = intrinsics
self.camera_to_world = camera_to_world
self.ray_generator = ray_generator
self.train_count = 0
self.eval_count = 0
def iter_train(self):
"""Returns an iterator that executes the self.next_train function"""
self.train_count = 0
class DataloaderIterable:
"""A helper class for dataloader iterables. This class's __next__ function is determined by
the next() function passed into the __init__ function. It will assume the dataloader passed into
the __init__ function is the dataloader object we want to"""
def __init__(self, dataloader: AbstractDataloaderV2, next: callable):
self.dataloader = dataloader
self.next = next
def __next__(self):
return self.next(self.dataloader)
return DataloaderIterable(self, self.next_train)
def iter_eval(self):
"""Returns an iterator that executes the self.next_eval function"""
self.train_count = 0
class DataloaderIterable:
"""A helper class for dataloader iterables. This class's __next__ function is determined by
the next() function passed into the __init__ function. It will assume the dataloader passed into
the __init__ function is the dataloader object we want to"""
def __init__(self, dataloader: AbstractDataloaderV2, next: callable):
self.dataloader = dataloader
self.next = next
def __next__(self):
return self.next(self.dataloader)
return DataloaderIterable(self, self.next_eval)
@abstractmethod
def setup_train(self):
"""Sets up the dataloader for training"""
@abstractmethod
def setup_eval(self):
"""Sets up the dataloader for evaluation"""
@abstractmethod
def next_train(self) -> GenericDataContainer:
"""Returns the next batch of data from the train dataloader"""
@abstractmethod
def next_eval(self) -> GenericDataContainer:
"""Returns the next batch of data from the eval dataloader"""
class TrainDataloader:
"""Training dataloader base class."""

View File

@ -20,6 +20,7 @@ from dataclasses import dataclass
from typing import List, Optional
import torch
from pyrad.cameras.rays import RayBundle
from torchtyping import TensorType
@ -106,3 +107,19 @@ class DatasetInputs:
def as_dict(self) -> dict:
"""Returns the dataclass as a dictionary."""
return vars(self)
@dataclass
class GenericDataContainer:
"""A container for data that is not specific to any dataset. It should be everything
needed by the renderer and loss calculation. Different datasets and models will probably
need to subclass from this differently, since different Field modules will require different
data.
Args:
rays: The rays for the image.
ground_truth_pixels: The ground truth pixels for the image.
"""
rays: RayBundle
ground_truth_pixels: TensorType["num_pixels", 3] = None