From 91f57726ae7b1119b00d1c2fd9f0207d78fbc7e7 Mon Sep 17 00:00:00 2001 From: Ethan Weber Date: Fri, 8 Apr 2022 17:01:47 +0000 Subject: [PATCH 1/9] some initial module structuring --- configs/modules.json | 34 +++++++++++++++++++ mattport/nerf/dataset/build.py | 2 +- mattport/nerf/dataset/{base.py => dataset.py} | 0 mattport/nerf/graph.py | 29 +++++++++++++--- .../{encodings.py => modules/encoding.py} | 4 +++ mattport/nerf/{models.py => modules/mlp.py} | 7 ---- mattport/nerf/trainer.py | 9 ++--- 7 files changed, 67 insertions(+), 18 deletions(-) create mode 100644 configs/modules.json rename mattport/nerf/dataset/{base.py => dataset.py} (100%) rename mattport/nerf/{encodings.py => modules/encoding.py} (92%) rename mattport/nerf/{models.py => modules/mlp.py} (94%) diff --git a/configs/modules.json b/configs/modules.json new file mode 100644 index 000000000..377de3a0d --- /dev/null +++ b/configs/modules.json @@ -0,0 +1,34 @@ +{ + "PositionalEncoder": { + "name": "encoder_0", + "inputs": [ + "x" + ], + "meta_data": { + "output_dim": 8 + } + }, + "MLP": { + "name": "mlp_0", + "inputs": [ + "encoder_0", "encoder_0" + ], + "meta_data": { + "num_layers": 8, + "num_skip_connections": [ + 3, + 7 + ], + "hidden_dim": 256, + "output_dim": 8 + } + }, + "RGB": { + "name": "rgb_0", + "inputs": ["mlp_0"] + }, + "Density": { + "name": "rgb_1", + "inputs": ["mlp_0"] + } +} \ No newline at end of file diff --git a/mattport/nerf/dataset/build.py b/mattport/nerf/dataset/build.py index 6966e87e6..6e0d9c4b3 100644 --- a/mattport/nerf/dataset/build.py +++ b/mattport/nerf/dataset/build.py @@ -4,7 +4,7 @@ Builds the dataset import importlib import logging -from mattport.nerf.dataset.base import Dataset +from mattport.nerf.dataset.dataset import Dataset def build_dataset(config: dict) -> Dataset: diff --git a/mattport/nerf/dataset/base.py b/mattport/nerf/dataset/dataset.py similarity index 100% rename from mattport/nerf/dataset/base.py rename to mattport/nerf/dataset/dataset.py diff --git a/mattport/nerf/graph.py b/mattport/nerf/graph.py index 01d1a6db1..ee0cf3efc 100644 --- a/mattport/nerf/graph.py +++ b/mattport/nerf/graph.py @@ -3,7 +3,7 @@ The Graph module contains all trainable parameters. """ from dataclasses import dataclass from torch import nn - +from mattport.nerf.modules.positional_encoder import PositionalEncoder @dataclass class GraphInputs: @@ -19,10 +19,31 @@ class Graph(nn.Module): nn (_type_): _description_ """ - def __init__(self) -> None: + def __init__(self, modules_config: dict) -> None: super().__init__() + + + # # for key in ... + # temp = graph_config.positional_encoder + # PositionalEncoder(name=temp.name, name=temp.inputs, ) + # self.modules = {} + # self.modules["name"] = MLP() + + + self.modules = {} + + + self.encoder_0 = Encoder() + self.mlp_0 = MLP() + + raise NotImplementedError - def forward(self): + def forward(self, x): """_summary_""" - raise NotImplementedError + # raise NotImplementedError + + for name in queue: # "encoder_0", + # assert name.output is not None + x = self.modules[name](x) + # self.mlp_0 \ No newline at end of file diff --git a/mattport/nerf/encodings.py b/mattport/nerf/modules/encoding.py similarity index 92% rename from mattport/nerf/encodings.py rename to mattport/nerf/modules/encoding.py index e25c3a50e..98daf6180 100644 --- a/mattport/nerf/encodings.py +++ b/mattport/nerf/modules/encoding.py @@ -8,6 +8,10 @@ from torchtyping import TensorType class Encoding(nn.Module): """Encode an input tensor. Intended to be subclassed""" + def __init__(self, name: str, inputs: list, meta_data: dict) -> None: + super().__init__() + raise NotImplementedError + def encode(self, in_tensor: TensorType[..., "input_dim"]) -> TensorType[..., "output_dim"]: """Encodes an input tensor. diff --git a/mattport/nerf/models.py b/mattport/nerf/modules/mlp.py similarity index 94% rename from mattport/nerf/models.py rename to mattport/nerf/modules/mlp.py index f58ecc717..94ac56e0e 100644 --- a/mattport/nerf/models.py +++ b/mattport/nerf/modules/mlp.py @@ -1,10 +1,4 @@ -""" -Collection of Models -""" -from typing import Optional - from torch import nn -from torchtyping import TensorType class MLP(nn.Module): @@ -30,7 +24,6 @@ class MLP(nn.Module): out_activation (Optional[nn.Module], optional): output activation function. Defaults to None. """ super().__init__() - layers = [] for i in range(num_layers): if i == 0: diff --git a/mattport/nerf/trainer.py b/mattport/nerf/trainer.py index 23c479f97..13e58d663 100644 --- a/mattport/nerf/trainer.py +++ b/mattport/nerf/trainer.py @@ -17,19 +17,16 @@ class Trainer(object): self.optimizer = None def setup_dataset(self): - """_summary_ - """ + """_summary_""" self.train_dataset = build_dataset(self.config.dataset) self.test_dataset = build_dataset(self.config.dataset) def setup_graph(self): - """_summary_ - """ + """_summary_""" self.graph = Graph() def setup_optimizer(self): - """_summary_ - """ + """_summary_""" self.optimizer = Optimizer(params=self.graph.parameters(), **self.config.optimizer) def load_checkpoint(self): From 62aee546118f71bb413003b21b36853bf5ee0c8b Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:12:14 +0000 Subject: [PATCH 2/9] done logic to instantiate graph, test to check instantiation --- configs/modules.json | 9 +++--- mattport/nerf/graph.py | 46 ++++++++++++++++++------------- mattport/nerf/modules/__init__.py | 2 ++ mattport/nerf/modules/encoding.py | 4 +-- mattport/nerf/modules/mlp.py | 6 +++- tests/nerf/test_graph.py | 43 +++++++++++++++++++++++++++++ 6 files changed, 84 insertions(+), 26 deletions(-) create mode 100644 mattport/nerf/modules/__init__.py create mode 100644 tests/nerf/test_graph.py diff --git a/configs/modules.json b/configs/modules.json index 377de3a0d..76c59f9d0 100644 --- a/configs/modules.json +++ b/configs/modules.json @@ -1,6 +1,6 @@ { - "PositionalEncoder": { - "name": "encoder_0", + "encoder_0": { + "class": "PositionalEncoder", "inputs": [ "x" ], @@ -8,8 +8,9 @@ "output_dim": 8 } }, - "MLP": { - "name": "mlp_0", + + "mlp_0": { + "class": "MLP", "inputs": [ "encoder_0", "encoder_0" ], diff --git a/mattport/nerf/graph.py b/mattport/nerf/graph.py index ee0cf3efc..843cde7c2 100644 --- a/mattport/nerf/graph.py +++ b/mattport/nerf/graph.py @@ -1,9 +1,11 @@ """ The Graph module contains all trainable parameters. """ +import importlib from dataclasses import dataclass + from torch import nn -from mattport.nerf.modules.positional_encoder import PositionalEncoder + @dataclass class GraphInputs: @@ -21,29 +23,35 @@ class Graph(nn.Module): def __init__(self, modules_config: dict) -> None: super().__init__() - - - # # for key in ... - # temp = graph_config.positional_encoder - # PositionalEncoder(name=temp.name, name=temp.inputs, ) - # self.modules = {} - # self.modules["name"] = MLP() - - self.modules = {} + self.module_order = self.get_module_order(modules_config) + for module_name, module_dict in modules_config.items(): + module = getattr(importlib.import_module("mattport.nerf.modules"), module_dict["class_name"]) + if module_dict["class_name"] != "Encoding": + in_dim = 0 + for inputs in module_dict["inputs"]: + in_dim += modules_config[inputs]["meta_data"]["out_dim"] + module_dict["meta_data"]["in_dim"] = in_dim + self.modules[module_name] = module(**module_dict["meta_data"]) + def get_module_order(self, modules_config: list): + """Generates a graph to determine the order in which the graph should execute - self.encoder_0 = Encoder() - self.mlp_0 = MLP() + Args: + modules_config (list): _description_ - - raise NotImplementedError + Returns: + _type_: _description_ + """ + # raise NotImplementedError + return modules_config def forward(self, x): - """_summary_""" + """_summary_ + + Args: + x (_type_): _description_ + """ # raise NotImplementedError - - for name in queue: # "encoder_0", - # assert name.output is not None + for name in self.module_order: x = self.modules[name](x) - # self.mlp_0 \ No newline at end of file diff --git a/mattport/nerf/modules/__init__.py b/mattport/nerf/modules/__init__.py new file mode 100644 index 000000000..d59de93cb --- /dev/null +++ b/mattport/nerf/modules/__init__.py @@ -0,0 +1,2 @@ +from .encoding import Encoding +from .mlp import MLP \ No newline at end of file diff --git a/mattport/nerf/modules/encoding.py b/mattport/nerf/modules/encoding.py index 98daf6180..821c663c5 100644 --- a/mattport/nerf/modules/encoding.py +++ b/mattport/nerf/modules/encoding.py @@ -8,9 +8,9 @@ from torchtyping import TensorType class Encoding(nn.Module): """Encode an input tensor. Intended to be subclassed""" - def __init__(self, name: str, inputs: list, meta_data: dict) -> None: + def __init__(self, out_dim: int) -> None: super().__init__() - raise NotImplementedError + # raise NotImplementedError def encode(self, in_tensor: TensorType[..., "input_dim"]) -> TensorType[..., "output_dim"]: """Encodes an input tensor. diff --git a/mattport/nerf/modules/mlp.py b/mattport/nerf/modules/mlp.py index 94ac56e0e..6c47264da 100644 --- a/mattport/nerf/modules/mlp.py +++ b/mattport/nerf/modules/mlp.py @@ -1,4 +1,7 @@ +from typing import Optional + from torch import nn +from torchtyping import TensorType class MLP(nn.Module): @@ -10,7 +13,7 @@ class MLP(nn.Module): out_dim: int, num_layers: int, layer_width: int, - activation: Optional[nn.Module] = nn.ReLU, + activation: Optional[nn.Module] = None, out_activation: Optional[nn.Module] = None, ) -> None: """Initialize mulilayer perceptron. @@ -24,6 +27,7 @@ class MLP(nn.Module): out_activation (Optional[nn.Module], optional): output activation function. Defaults to None. """ super().__init__() + self.in_dim = in_dim layers = [] for i in range(num_layers): if i == 0: diff --git a/tests/nerf/test_graph.py b/tests/nerf/test_graph.py new file mode 100644 index 000000000..5dbf9e468 --- /dev/null +++ b/tests/nerf/test_graph.py @@ -0,0 +1,43 @@ +import pytest + +from mattport.nerf.graph import Graph + + +def create_basic_graph(): + """Create basic test for creating a graph + + Returns: + dict: module definitions for constructing a graph + """ + basic_graph = { + "encoder_0": {"class_name": "Encoding", "inputs": ["x"], "meta_data": {"out_dim": 8}}, + "mlp_0": { + "class_name": "MLP", + "inputs": ["encoder_0", "encoder_0"], + "meta_data": {"in_dim": 0, "out_dim": 1, "num_layers": 2, "layer_width": 3}, + }, + "mlp_1": { + "class_name": "MLP", + "inputs": ["mlp_0"], + "meta_data": {"in_dim": 4, "out_dim": 5, "num_layers": 6, "layer_width": 7}, + }, + } + return basic_graph + + +def test_graph_init(): + """test modules dictionary is instantiated properly""" + test_graph = Graph(create_basic_graph()) + assert test_graph.modules is not None + assert type(test_graph.modules['encoder_0']).__name__ == 'Encoding' + assert type(test_graph.modules['mlp_0']).__name__ == 'MLP' + assert type(test_graph.modules['mlp_1']).__name__ == 'MLP' + + +def test_input_dimension(): + """test module input dimension calculation""" + test_graph = Graph(create_basic_graph()) + assert not hasattr(test_graph.modules['encoder_0'], 'in_dim') + assert test_graph.modules['mlp_0'].in_dim == 16 + assert test_graph.modules['mlp_1'].in_dim == 1 + \ No newline at end of file From f17192a93e27f64b53ef036e6f30a592293f186f Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:19:34 +0000 Subject: [PATCH 3/9] added test bench to github actions --- .github/workflows/pytest.yml | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 .github/workflows/pytest.yml diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml new file mode 100644 index 000000000..3dec171aa --- /dev/null +++ b/.github/workflows/pytest.yml @@ -0,0 +1,30 @@ +name: Python application + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +permissions: + contents: read + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v3 + - name: Set up Python 3.10 + uses: actions/setup-python@v3 + with: + python-version: "3.10" + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install flake8 pytest + if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + - name: Test with pytest + run: | + pytest tests/nerf/test_graph.py From c7911281c3a9f8bfae3c9c82744ddf7390fdc568 Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:26:22 +0000 Subject: [PATCH 4/9] fixing documentation for unfinished module ordering function --- mattport/nerf/graph.py | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/mattport/nerf/graph.py b/mattport/nerf/graph.py index 843cde7c2..84b8997ee 100644 --- a/mattport/nerf/graph.py +++ b/mattport/nerf/graph.py @@ -15,11 +15,7 @@ class GraphInputs: class Graph(nn.Module): - """_summary_ - - Args: - nn (_type_): _description_ - """ + """_summary_ """ def __init__(self, modules_config: dict) -> None: super().__init__() @@ -34,17 +30,16 @@ class Graph(nn.Module): module_dict["meta_data"]["in_dim"] = in_dim self.modules[module_name] = module(**module_dict["meta_data"]) - def get_module_order(self, modules_config: list): - """Generates a graph to determine the order in which the graph should execute + def get_module_order(self, modules_config: dict) -> list: + """Generates a graph to determine the order in which the modules should execute Args: - modules_config (list): _description_ + modules_config (dict): module definitions that make up the network Returns: - _type_: _description_ + list: ordering of the module names that should be executed """ - # raise NotImplementedError - return modules_config + raise NotImplementedError def forward(self, x): """_summary_ @@ -52,6 +47,6 @@ class Graph(nn.Module): Args: x (_type_): _description_ """ - # raise NotImplementedError - for name in self.module_order: - x = self.modules[name](x) + # for name in self.module_order: + # x = self.modules[name](x) + raise NotImplementedError From 05d26b5265143f4d90568a30f7985543bfca87b7 Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:31:52 +0000 Subject: [PATCH 5/9] fix lint errors --- mattport/nerf/modules/__init__.py | 2 +- mattport/nerf/modules/encoding.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mattport/nerf/modules/__init__.py b/mattport/nerf/modules/__init__.py index d59de93cb..39b25225c 100644 --- a/mattport/nerf/modules/__init__.py +++ b/mattport/nerf/modules/__init__.py @@ -1,2 +1,2 @@ from .encoding import Encoding -from .mlp import MLP \ No newline at end of file +from .mlp import MLP diff --git a/mattport/nerf/modules/encoding.py b/mattport/nerf/modules/encoding.py index 821c663c5..5abf0dbcf 100644 --- a/mattport/nerf/modules/encoding.py +++ b/mattport/nerf/modules/encoding.py @@ -10,7 +10,9 @@ class Encoding(nn.Module): def __init__(self, out_dim: int) -> None: super().__init__() - # raise NotImplementedError + self.out_dim = out_dim + + raise NotImplementedError def encode(self, in_tensor: TensorType[..., "input_dim"]) -> TensorType[..., "output_dim"]: """Encodes an input tensor. From 244f30b47db1ac288ef5831a838c1f2c62dd728f Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:46:52 +0000 Subject: [PATCH 6/9] experimenting test benching --- .github/workflows/pytest.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 3dec171aa..13730ce12 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -25,6 +25,10 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + cd external/goat + python setup.py develop + cd ../../ + python setup.py develop - name: Test with pytest run: | pytest tests/nerf/test_graph.py From 1544b3b4a2a19f6424836a9bede88f35dec4404c Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:51:59 +0000 Subject: [PATCH 7/9] removed external setups from github actions --- .github/workflows/pytest.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index 13730ce12..c7b2f642b 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -25,9 +25,6 @@ jobs: python -m pip install --upgrade pip pip install flake8 pytest if [ -f requirements.txt ]; then pip install -r requirements.txt; fi - cd external/goat - python setup.py develop - cd ../../ python setup.py develop - name: Test with pytest run: | From c8d84937e08e4e08ec109b310ef4fa5a99420f19 Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 05:54:38 +0000 Subject: [PATCH 8/9] fixing requirements path --- .github/workflows/pytest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pytest.yml b/.github/workflows/pytest.yml index c7b2f642b..320012ddc 100644 --- a/.github/workflows/pytest.yml +++ b/.github/workflows/pytest.yml @@ -24,7 +24,7 @@ jobs: run: | python -m pip install --upgrade pip pip install flake8 pytest - if [ -f requirements.txt ]; then pip install -r requirements.txt; fi + if [ -f environment/requirements.txt ]; then pip install -r environment/requirements.txt; fi python setup.py develop - name: Test with pytest run: | From cffb48e3e0e0e6f0719cabf385bc3d8ec68e7158 Mon Sep 17 00:00:00 2001 From: evonneng Date: Sat, 9 Apr 2022 06:00:33 +0000 Subject: [PATCH 9/9] passing tests locally, remove not implemented checks --- mattport/nerf/graph.py | 4 ++-- mattport/nerf/modules/encoding.py | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/mattport/nerf/graph.py b/mattport/nerf/graph.py index 84b8997ee..968522996 100644 --- a/mattport/nerf/graph.py +++ b/mattport/nerf/graph.py @@ -15,7 +15,7 @@ class GraphInputs: class Graph(nn.Module): - """_summary_ """ + """_summary_""" def __init__(self, modules_config: dict) -> None: super().__init__() @@ -39,7 +39,7 @@ class Graph(nn.Module): Returns: list: ordering of the module names that should be executed """ - raise NotImplementedError + return modules_config.keys() def forward(self, x): """_summary_ diff --git a/mattport/nerf/modules/encoding.py b/mattport/nerf/modules/encoding.py index 5abf0dbcf..b0985ecfc 100644 --- a/mattport/nerf/modules/encoding.py +++ b/mattport/nerf/modules/encoding.py @@ -12,8 +12,6 @@ class Encoding(nn.Module): super().__init__() self.out_dim = out_dim - raise NotImplementedError - def encode(self, in_tensor: TensorType[..., "input_dim"]) -> TensorType[..., "output_dim"]: """Encodes an input tensor.